这两天接到了一个新任务,通过后台管理编写文章,发送到官网的同时,推送一份到公众号,研究了一下微信的文档,发现不难,只需要有几个注意点就可以了。
注意:
- 微信公众号只能访问微信自己上传的图片链接,外网链接会自动屏蔽。
- 微信公众号自己上传的图片返回的链接,只能用于腾讯域内访问,外网是访问不了的。
- 微信公众号分为服务号和订阅号,服务号每个月只能群发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);
}
好了到这里就已经可以发送文章到公众号了,有什么问题可以在下面给我留言,我看到了会一一回复的哦~,如果对你有用的话请大家动一下发财的小手,收藏、关注、点赞一下哈。