這兩天接到了一個新任務,通過后臺管理編寫文章,發送到官網的同時,推送一份到公眾號,研究了一下微信的文檔,發現不難,只需要有幾個注意點就可以了。
注意:
- 微信公眾號只能訪問微信自己上傳的圖片鏈接,外網鏈接會自動屏蔽。
- 微信公眾號自己上傳的圖片返回的鏈接,只能用于騰訊域內訪問,外網是訪問不了的。
- 微信公眾號分為服務號和訂閱號,服務號每個月只能群發4次文章,訂閱號是每天可以發1次,但是服務號和訂閱號是可以1次發1~8篇文章的哦,這對于咱們測試來說就很麻煩,所以我們可以申請一個測試賬號,用于測試開發,測試賬號的權限也是最大的,很多API都可以調用,我把申請的流程放到下面。
注意這幾點就可以了,好了接下來我們進入到正文!
這是微信公眾號開發文檔鏈接:微信公眾號開發文檔鏈接 ,可以結合文檔看,畢竟他老是在更新。
一、申請微信公眾號測試賬號
登錄公眾號以后,按照這個步驟就可以申請測試公眾號了,沒有公眾號的先去自己申請一個,這里就不多贅述了(建議個人開發的話用訂閱號哈,服務號申請比較麻煩)。
二、開發準備工作
一、項目所需要的依賴
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.43</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
因為我是用redis做了微信access_token的緩存,所以用到了redis,看各位自己的需求,直接存靜態對象里也行。
二、涉及到的微信接口
public class WeChatConstant {public static final String APP_ID = "";public static final String SECRET = "";public static final String ACCESS_TOKEN = "access-_token";//獲取tokenpublic static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";//上傳圖文圖片永久素材public static final String UPLOAD_FILE_IMAGE_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s";public static final String UPLOAD_FILE_OTHER_TYPE_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=%s";//建立草稿箱public static final String CREATE_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token=%s";//發布草稿箱public static final String PUSH_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token=%s";//群發草稿箱消息public static final String SEND_ALL_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=%s";
}
三、實現代碼
上傳公眾號,分為幾個步驟,上圖片。
根據圖片可以看到,所有的接口都是需要accessToken的,所以我們先獲取accessToken。
一、 獲取AccessToken
@Resourceprivate RedisCache redisCache;public String getAccessToken() {String url = String.format(WeChatConstant.ACCESS_TOKEN_URL, WeChatConstant.APP_ID, WeChatConstant.SECRET);String result = HttpUtil.get(url);log.info("獲取AccessToken,返回結果:{}",result);JSONObject jsonObject = JSON.parseObject(result);if (!jsonObject.containsKey("access_token")) {throw new RuntimeException(result);}String access_token = jsonObject.getString("access_token");String expires_in = jsonObject.getString("expires_in");redisCache.setCacheObject(WeChatConstant.ACCESS_TOKEN,access_token,Integer.parseInt(expires_in), TimeUnit.SECONDS);return access_token;}
二、上傳文本內的圖片素材
這個是用來上傳富文本內圖片到微信的接口,是不占用微信公眾號素材庫的,但是圖片需要小于1M,詳細介紹可以看官網文檔。
@Overridepublic String uploadImageTextWeChatImage(String path) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.UPLOAD_FILE_IMAGE_URL, accessToken);Map<String, Object> map = new HashMap<>(1);File file = new File(path);map.put("media",file);String result = HttpUtil.post(upload, map);log.info("上傳微信圖文內永久素材,返回結果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String url = jsonObject.getString("url");if(StrUtil.isBlank(url)) {throw new ServiceException("上傳富文本內圖片到微信錯誤,錯誤原因:" + jsonObject.toString());}return url;}
三、上傳其他類型文件
這個是用來上傳文章標題圖片的,也可以上傳其他類型的文件,比如視頻等,需要按照官方文檔類型上傳。
@Overridepublic String uploadOtherTypeWeChat(String path, String type) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.UPLOAD_FILE_OTHER_TYPE_URL, accessToken,type);Map<String, Object> map = new HashMap<>(1);File file = new File(path);map.put("media",file);String result = HttpUtil.post(upload, map);log.info("上傳其他類型永久素材,返回結果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String mediaId = jsonObject.getString("media_id");if(StrUtil.isBlank(mediaId)) {throw new ServiceException("上傳標題圖片到微信錯誤,錯誤原因:" + jsonObject.toString());}return mediaId;}
四、上傳文章到草稿箱
草稿箱實體類
@Data@Accessors(chain = true)public class DraftVo implements Serializable {private String title;private String author;private String digest;private String content;private String content_source_url;private String thumb_media_id;}
@Overridepublic String uploadDraftWeChat(DraftVo vo) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.CREATE_DRAFT_URL, accessToken);Map<String, Object> map = new HashMap<>(1);map.put("articles", Arrays.asList(vo));String json = JSON.toJSONString(map);String result = HttpUtil.post(upload, json);log.info("上傳文章到草稿箱,返回結果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String mediaId = jsonObject.getString("media_id");if(StrUtil.isBlank(mediaId)) {throw new ServiceException("上傳文章到微信草稿箱錯誤,錯誤原因:" + jsonObject.toString());}return mediaId;}
五、群發草稿箱的內容到公眾號
@Overridepublic String sendAllDraftWeChat(String mediaId) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.SEND_ALL_DRAFT_URL, accessToken);Map<String, Object> map = new HashMap<>(4);Map<String, Object> filterMap = new HashMap<>(2);filterMap.put("is_to_all",true);filterMap.put("tag_id","");map.put("filter",filterMap);Map<String, Object> mpnews = new HashMap<>(1);mpnews.put("media_id",mediaId);map.put("mpnews",mpnews);map.put("msgtype","mpnews");map.put("send_ignore_reprint","1");String json = JSON.toJSONString(map);String result = HttpUtil.post(upload, json);log.info("群發草稿箱的文章到公眾號,返回結果:{}",result);JSONObject jsonObject = JSON.parseObject(result);Integer errcode = Integer.parseInt(jsonObject.getString("errcode"));if (errcode != 0) {throw new ServiceException("群發文章錯誤,錯誤原因:" + jsonObject.getString("errmsg"));}return jsonObject.getString("msg_id");}
六、Service層接口
public interface WeChatService {/*** 獲取token*/public String getAccessToken();/*** 上傳文本內的圖片素材* @param path * @return*/public String uploadImageTextWeChatImage(String path);/*** 上傳其他類型文件* @return */public String uploadOtherTypeWeChat(String path,String type);/*** 上傳文章到草稿箱* @param vo* @return */public String uploadDraftWeChat(DraftVo vo);/*** 群發草稿箱的內容到公眾號* @param mediaId* @return*/public String sendAllDraftWeChat(String mediaId);
}
好了到這里就已經可以發送文章到公眾號了,有什么問題可以在下面給我留言,我看到了會一一回復的哦~,如果對你有用的話請大家動一下發財的小手,收藏、關注、點贊一下哈。