微信素材管理和群發這塊文檔對Java很不友好。本文只對新增臨時素材,新增永久素材做介紹,其余獲取、刪除、修改自行補充
公眾號經常有需要用到一些臨時性的多媒體素材的場景,例如在使用接口特別是發送消息時,對多媒體文件、多媒體消息的獲取和調用等操作,是通過media_id來進行的。素材管理接口對所有認證的訂閱號和服務號開放。
素材的限制
圖片(image): 2M,支持PNG\JPEG\JPG\GIF格式
語音(voice):2M,播放長度不超過60s,支持AMR\MP3格式
視頻(video):10MB,支持MP4格式
縮略圖(thumb):64KB,支持JPG格式
一、新增臨時素材
接口:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE,再傳一個媒體文件類型,可以是圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)。
1、訂閱號和服務號要通過認證
2、臨時素材media_id是可復用的
3、媒體文件在微信后台保存時間為3天,即3天后media_id失效。
/** * 新增臨時素材(本地) * * @param accessToken * @param type 媒體文件類型,分別有圖片(image)、語音(voice)、(video)和縮略圖(thumb) * @param filePath 本地路徑 * @return */ @Override public MaterialResult uploadTempMediaFile(String accessToken, String type, String filePath) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", type); try { String result = MaterialUtil.uploadMediaFile(wechatMaterialConfig.getUploadTempMediaUrl(), params, filePath); return JsonUtil.fromJson(result, MaterialResult.class); } catch (Exception e) { log.error(e.getMessage()); } return null; } /** * 新增臨時素材(網絡) * * @param accessToken * @param type 媒體文件類型,分別有圖片(image)、語音(voice)、(video)和縮略圖(thumb) * @param url 網絡路徑 * @return */ @Override public MaterialResult uploadTempMediaUrl(String accessToken, String type, String url) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", type); try { String result = MaterialUtil.uploadMediaUrl(wechatMaterialConfig.getUploadTempMediaUrl(), params, url); return JsonUtil.fromJson(result, MaterialResult.class); } catch (Exception e) { log.error(e.getMessage()); } return null; }
二、新增永久素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE,媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video,例外)和縮略圖(thumb)
/** * 新增永久素材(本地) * * @param accessToken * @param type 媒體文件類型,分別有圖片(image)、語音(voice)和縮略圖(thumb) * @param filePath 本地路徑 * @return */ @Override public MaterialResult uploadForeverMediaFile(String accessToken, String type, String filePath) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", type); try { String result = MaterialUtil.uploadMediaFile(wechatMaterialConfig.getUploadForeverMediaUrl(), params, filePath); return JsonUtil.fromJson(result, MaterialResult.class); } catch (Exception e) { log.error(e.getMessage()); } return null; } /** * 新增永久素材(網絡) * * @param accessToken * @param type 媒體文件類型,分別有圖片(image)、語音(voice)和縮略圖(thumb) * @param url 網絡路徑 * @return */ @Override public MaterialResult uploadForeverMediaUrl(String accessToken, String type, String url) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", type); try { String result = MaterialUtil.uploadMediaUrl(wechatMaterialConfig.getUploadForeverMediaUrl(), params, url); return JsonUtil.fromJson(result, MaterialResult.class); } catch (Exception e) { log.error(e.getMessage()); } return null; }
新增永久視頻素材需特別注意,在上傳視頻素材時需要POST另一個表單,id為description,包含素材的描述信息title和introduction,內容格式為JSON
/** * 上傳本地video永久素材 * 返回格式 * { * "media_id":MEDIA_ID * } * * @param accessToken * @param title 視頻素材的標題 * @param introduction 視頻素材的描述 * @param filePath 本地路徑 * @return */ @Override public String uploadForeverMediaFile(String accessToken, String title, String introduction, String filePath) { //只能是mp4的 Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_VIDEO); try { String result = MaterialUtil.uploadVideoMediaFile(wechatMaterialConfig.getUploadForeverMediaUrl(), params, filePath, title, introduction); return JsonUtil.fromJson(result, MaterialResult.class).getMediaId(); } catch (Exception e) { log.error(e.getMessage()); } return null; } /** * 上傳網絡video永久素材 * 返回格式 * { * "media_id":MEDIA_ID * } * * @param accessToken * @param title 視頻素材的標題 * @param introduction 視頻素材的描述 * @param url 網絡路徑 * @return */ @Override public String uploadForeverMediaUrl(String accessToken, String title, String introduction, String url) { //只能是mp4的 Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); params.put("type", WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_VIDEO); try { String result = MaterialUtil.uploadVideoMediaUrl(wechatMaterialConfig.getUploadForeverMediaUrl(), params, url, title, introduction); // log.error(result); return JsonUtil.fromJson(result, MaterialResult.class).getMediaId(); } catch (Exception e) { log.error(e.getMessage()); } return null; }
三、新增永久圖文素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN
對於常用的素材,開發者可通過本接口上傳到微信服務器,永久使用.
1、永久圖片素材新增后,將帶有URL返回給開發者,開發者可以在騰訊系域名內使用(騰訊系域名外使用,圖片將被屏蔽)。
2、公眾號的素材庫保存總數量有上限:圖文消息素材、圖片素材上限為5000,其他類型為1000。
3、圖文消息的具體內容中,微信后台將過濾外部的圖片鏈接,圖片url需通過"上傳圖文消息內的圖片獲取URL"接口上傳圖片獲取。
4、"上傳圖文消息內的圖片獲取URL"接口所上傳的圖片,不占用公眾號的素材庫中圖片數量的5000個的限制,圖片僅支持jpg/png格式,大小必須在1MB以下。
5、圖文消息支持正文中插入自己帳號和其他公眾號已群發文章鏈接的能力。
/** * 新增永久圖文素材 * 返回示例 * { * "media_id":MEDIA_ID * } * 活得新增的圖文消息素材的media_id * * @param accessToken * @param entity 圖文消息article組合的data * @return * @see WechatMassService#uploadForMassNewsFile */ @Override public String uploadNewsMedia(String accessToken, UploadNewsEntity entity) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); String data = JsonUtil.toJson(entity); String result = HttpUtil.doPost(wechatMaterialConfig.getAddNewsUrl(), params, data); return JsonUtil.fromJson(result, MassNewsResult.class).getMediaId(); }
四、上傳圖文消息內的圖片獲取URL
接口:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
本接口所上傳的圖片不占用公眾號的素材庫中圖片數量的5000個的限制。圖片僅支持jpg/png格式,大小必須在1MB以下,此接口返回的url就是上傳圖片的URL,可放置圖文消息中使用。
/** * { * "url": "http://mmbiz.qpic.cn/mmbiz/gLO17UPS6FS2xsypf378iaNhWacZ1G1UplZYWEYfwvuU6Ont96b1roYs CNFwaRrSaKTPCUdBK9DgEHicsKwWCBRQ/0" * } * 圖文消息的具體內容中,微信后台將過濾外部的圖片鏈接,圖片url需通過"上傳圖文消息內的圖片獲取URL"接口上傳圖片獲取 * 獲取 * * @param accessToken * @param filePath 本地路徑 * @return */ @Override public String uploadFileForNewsMedia(String accessToken, String filePath) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); try { String result = MaterialUtil.uploadMediaFile(wechatMaterialConfig.getUploadimgMediaUrl(), params, filePath); return JsonUtil.fromJson(result, MaterialResult.class).getUrl(); } catch (Exception e) { log.error(e.getMessage()); } return null; } /** * { * "url": "http://mmbiz.qpic.cn/mmbiz/gLO17UPS6FS2xsypf378iaNhWacZ1G1UplZYWEYfwvuU6Ont96b1roYs CNFwaRrSaKTPCUdBK9DgEHicsKwWCBRQ/0" * } * 圖文消息的具體內容中,微信后台將過濾外部的圖片鏈接,圖片url需通過"上傳圖文消息內的圖片獲取URL"接口上傳圖片獲取 * 獲取 * * @param accessToken * @param url 網絡路徑 * @return */ @Override public String uploadUrlForNewsMedia(String accessToken, String url) { Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); try { String result = MaterialUtil.uploadMediaUrl(wechatMaterialConfig.getUploadimgMediaUrl(), params, url); return JsonUtil.fromJson(result, MaterialResult.class).getUrl(); } catch (Exception e) { log.error(e.getMessage()); } return null; }
五、Junit測試
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = WechatMainApplication.class) @ActiveProfiles("dev") public class WechatMaterialServiceImplTest { @Autowired private WechatAuthService wechatAuthService; @Autowired private WechatMaterialService wechatMaterialService; @Test public void uploadTempMediaFile() { String filePath = "C:/Users/Phil/Pictures/cc0a42661f668d17e18d0a0f3a699909.jpeg"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增臨時本地圖片素材,返回" + wechatMaterialService.uploadTempMediaFile(accessToken, WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_IMAGE, filePath)); //新增臨時本地圖片素材,返回MassNewsResult(type=image, mediaId=rh0D9L_B5Ty_-EcwIFULGjb57eCGAbQZRz8bNrWnfcLMiMz2Pm7vIQCdUKzC8C_8, createdAt=1543648966, url=null) } @Test public void uploadTempMediaUrl() { String url = "http://b-ssl.duitang.com/uploads/item/201503/14/20150314212812_kCLmy.jpeg"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增臨時網絡圖片素材,返回 " + wechatMaterialService.uploadTempMediaUrl(accessToken, WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_IMAGE, url)); //新增臨時網絡圖片素材,返回 MassNewsResult(type=image, mediaId=lgbD-K0ltDTmsW2dSxus6sFxqqFc3mU_NiIAOev_U_mU2Yqa6iSv8KPF5e5WE7yC, createdAt=1543648973, url=null) } @Test public void uploadForeverMediaFile() { String filePath = "C:/Users/Phil/Pictures/cc0a42661f668d17e18d0a0f3a699909.jpeg"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增永久本地圖片素材,返回" + wechatMaterialService.uploadForeverMediaFile(accessToken, WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_IMAGE, filePath)); //新增永久本地圖片素材,返回MassNewsResult(type=null, mediaId=tbP52CbH1vuCLlyUAt2rlUEZKK230SjWIaB9xablAPw, createdAt=0, url=http://mmbiz.qpic.cn/mmbiz_jpg/L8zibbZGicwDyd6CV9JpbEe6T7rjqK2fBibCrZAxEvwDCJKHAgtfUialcnNlcjxTsAmycHSKjrO6KzdDUMeDwhYsIA/0?wx_fmt=jpeg) } @Test public void uploadForeverMediaUrl() { String url = "http://www.59xihuan.cn/uploads/allimg/201309/9181378183464-lp.jpg"; // String url = "http://b-ssl.duitang.com/uploads/item/201503/14/20150314212812_kCLmy.jpeg"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增永久網絡圖片素材, 返回" + wechatMaterialService.uploadForeverMediaUrl(accessToken, WechatMaterialConstant.MATERIAL_UPLOAD_TYPE_IMAGE, url)); //新增永久網絡圖片素材, 返回MassNewsResult(type=null, mediaId=GG16CzQSj3di2OTScAcNAzmoxg_5_KTyxsJ6uEEBpiM, createdAt=0, url=http://mmbiz.qpic.cn/mmbiz_jpg/3WjFdhSpzNwwEwTpWMU4j8UVddOSDGR2zRuJsQZXaRYnsIB3g4yESBqjxkf1e7ruIWYfUO5FtRWIibaVwt6icOHw/0?wx_fmt=jpeg) } @Test public void uploadNewsMedia() { String accessToken = wechatAuthService.getAccessToken(); UploadNewsEntity entity = new UploadNewsEntity(); UploadNewsEntity.UploadNewsArticle article1 = new UploadNewsEntity.UploadNewsArticle(); article1.setThumbMediaId("tbP52CbH1vuCLlyUAt2rlWEIB6qGsfypnI01Jwwonjg"); article1.setAuthor("article1"); article1.setTitle("article1"); article1.setContentSourceUrl(""); article1.setContent("article1"); article1.setDigest("article1"); article1.setShowConverPic(1); entity.addArticle(article1); UploadNewsEntity.UploadNewsArticle article2 = new UploadNewsEntity.UploadNewsArticle(); article2.setThumbMediaId("tbP52CbH1vuCLlyUAt2rlRjbl4sO2dPYqvCLZNwIorg"); article2.setAuthor("article2"); article2.setTitle("article2"); article2.setContentSourceUrl(""); article2.setContent("article2"); article2.setDigest("article2"); article2.setShowConverPic(0); entity.addArticle(article2); System.out.println("新增永久圖文素材, 返回" + wechatMaterialService.uploadNewsMedia(accessToken, entity)); //新增永久圖文素材, 返回tbP52CbH1vuCLlyUAt2rlVvIMceFKJmY663R_urJAYc } @Test public void uploadFileForNewsMedia() { String accessToken = wechatAuthService.getAccessToken(); String filePath = "D:\\Project\\Phil\\Wechat\\phil_new_wechat\\src\\main\\webapp\\image\\00_01.jpeg"; System.out.println(wechatMaterialService.uploadFileForNewsMedia(accessToken, filePath)); //http://mmbiz.qpic.cn/mmbiz_jpg/L8zibbZGicwDw6sv1WWkFK1nCUDY9bJrHiaEbJuTS37XbJR3hEiblAkibzjdTHdHKqXb6Ij53CDfNwztRsOwljibEp8A/0 } @Test public void uploadUrlForNewsMedia() { String accessToken = wechatAuthService.getAccessToken(); String url = "http://www.59xihuan.cn//uploads/allimg/20130728/64511374987081-lp.jpg"; System.out.println(wechatMaterialService.uploadUrlForNewsMedia(accessToken, url)); //http://mmbiz.qpic.cn/mmbiz_jpg/L8zibbZGicwDw6sv1WWkFK1nCUDY9bJrHiaQXwtf52SyM4ftxVeuickvh1rDLPMaeE1jDxgpWice9TgJOzYPIRAy8uA/0 } @Test public void uploadForeverVideoMediaFile() { String filePath = "D:/Project/Phil/Wechat/phil_new_wechat/src/main/webapp/video/1539717180390.mp4"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增永久本地視頻素材, 返回" + wechatMaterialService.uploadForeverMediaFile(accessToken, "title", "test", filePath)); //新增永久本地視頻素材, 返回GG16CzQSj3di2OTScAcNA-LTwMdsrKszM7M677NJyic } @Test public void uploadForeverVideoMediaUrl() { //String url = "http://vs6.bdstatic.com/browse_static/v3/common/widget/global/player/newPlayer_e2332cd1.swf"; //轉換 String url = "http://xiaozhaozhao.nat300.top/video/1539717180390.mp4"; String accessToken = wechatAuthService.getAccessToken(); System.out.println("新增永久網絡視頻素材, 返回" + wechatMaterialService.uploadForeverMediaUrl(accessToken, "title", "test", url)); // 新增永久網絡視頻素材, 返回GG16CzQSj3di2OTScAcNA6OWJlBHKk8sXSmbgPzxEQo } @Test public void getTempMaterial() { String accessToken = wechatAuthService.getAccessToken(); String mediaId = "c985PlW3avLd3w9gUclA75geC9PFFozfX6-Jn6s9kRWwV2gu0KHSaBEDJu0Eugno"; System.out.println(wechatMaterialService.getTempMaterial(accessToken, mediaId)); } @Test public void getMaterial() { String accessToken = wechatAuthService.getAccessToken(); // String mediaId = "tbP52CbH1vuCLlyUAt2rlUEZKK230SjWIaB9xablAPw"; //圖片 String mediaId = "tbP52CbH1vuCLlyUAt2rlVvIMceFKJmY663R_urJAYc"; //圖文 System.out.println(wechatMaterialService.getMaterial(accessToken, mediaId)); } @Test public void deleteMaterial() { String mediaId = "tbP52CbH1vuCLlyUAt2rlYaBvU3BHrs8g0-XxdnNILY"; //tbP52CbH1vuCLlyUAt2rlfnoE7EJNJvPvEv0nFkezsw //tbP52CbH1vuCLlyUAt2rlYUYsAvjhY7UmdgQ_8qnip4 String accessToken = wechatAuthService.getAccessToken(); System.out.println(wechatMaterialService.deleteMaterial(accessToken, mediaId)); //ResultState(errcode=0, errmsg=ok) } @Test public void geMaterialCount() { String accessToken = wechatAuthService.getAccessToken(); System.out.println(wechatMaterialService.geMaterialCount(accessToken)); //MaterialCountResult(voiceCount=0, videoCount=5, imageCount=15, newsCount=2) } }