前言
在工作中遇到一个需求,需要向微信公众号发布文章,通过查询资料以及查阅微信的开发文档,最终实现.
微信开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
一.准备工作
通过前期的准备工作我们发现,想要实现微信公众号发布文章的功能,主要分为三步.1.上传图片素材2.发布草稿箱3.将草稿箱内容发布出去.当然,还有一个功能贯彻这三部,就是获取token.
1.获取token
首先定义实体
package com.sinosoft.springbootplus.znts.domain.entity;
/**
* json格式化accessToken
* @author mc
* @version 1.0
* @创建时间 2023年3月07日
* @修改时间 2023年3月07日
*/
public class Token {
// 接口访问凭证
private String accessToken;
// 凭证有效期,单位:秒
private int expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
调用获取token的地址,和所需的appid(凭证)以及appsecret(密钥).
package com.sinosoft.springbootplus.znts.utils;
/**
* 微信常量定义
* 版权:(C) 版权所有 2015-2018 中科软科技股份有限公司
* <功能名称>
* <详细描述>
* @author mc
* @version 1.0
* @创建时间 2021年12月30日
* @修改时间 2021年12月30日
*/
public class ConstantUtil {
// 公众号开发者APPID
public final static String app_id = "";
// 公众号开发者密码
public final static String app_secret = "";
// 凭证获取(GET)
public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// 获取用户openid集合
//发布
public final static String sendSucaiUrl = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN";
//上传素材
public final static String uploadUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN";
//发布
public final static String ufabuUrl = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token=ACCESS_TOKEN";
//新增草稿
public final static String sendtemplateUrl = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token=ACCESS_TOKEN";
}
然后获取token
/**
* 获取接口访问凭证
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static Token getToken(String appid, String appsecret) {
Token token = null;
String requestUrl = ConstantUtil.token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
// 发起GET请求获取凭证
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
if (null != jsonObject) {
try {
token = new Token();
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
token = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return token;
}
2.上传图片素材
上传图片主要是因为在新增草稿箱时需要图片来做封面,还必须是永久的,所以在调用时需注意不要选错接口
public String uploadimg() throws IOException {
final File file = new File("D:\\software\\3.jpg");
RequestBody fileBody = RequestBody.create(file,okhttp3.MediaType.parse(MediaType.APPLICATION_OCTET_STREAM_VALUE));
MultipartBody body = new MultipartBody.Builder()
.setType(Objects.requireNonNull(okhttp3.MediaType.parse("multipart/form-data")))
.addFormDataPart("media",file.getName(),fileBody)
.build();
Request request = new Request.Builder()
.post(body)
.url("https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=" + CommonUtil.getToken(ConstantUtil.app_id, ConstantUtil.app_secret).getAccessToken() + "&type=image").build();
final String string = Objects.requireNonNull(client.newCall(request).execute().body()).string();
log.info(string);
return string;
}
上传成功后拿到media_id即可,这里需要注意如果上传失败,有可能是图片涉及敏感字,可以先换一张照片试一下.
3.新增草稿
/**
* 新增草稿想
* @return
*/
public static String addDraft(String title,String author,String content){
Object mediaId;
String access_token = "";
String strResult = "";
try {
JSONObject EventTraceInput = new JSONObject();
access_token = CommonUtil.getToken(ConstantUtil.app_id, ConstantUtil.app_secret).getAccessToken();
String url = ConstantUtil.sendtemplateUrl.replace("ACCESS_TOKEN", access_token);
JSONArray EventArray = new JSONArray();
JSONObject jsonArray = new JSONObject();
jsonArray.put("title", title);
jsonArray.put("author", author);
jsonArray.put("content", content);
jsonArray.put("thumb_media_id", "");
jsonArray.put("need_open_comment", 0);
jsonArray.put("only_fans_can_comment", 0);
EventArray.add(jsonArray);
EventTraceInput.put("articles", EventArray);
strResult = WX_TemplateMsgUtil.sendPost(EventTraceInput, url);
JSONObject jsonObject = JSONObject.parseObject(strResult);
mediaId = jsonObject.get("media_id");
}catch (Exception e){
log.error("调用微信公众号接口出错,access_token为:【{}】,调用草稿箱接口返回值为:【{}】", access_token,strResult);
throw new BusinessException(e.getMessage());
}
return mediaId.toString();
}
在这里我们只需要根据接口文档的信息传入想对应的值即可,thumb_media_id是上一步上传永久素材返回的media_id
4.发布文章
发布文章就比较简单了,只需要上传上一步上传草稿返回的media_id即可,具体代码如下:
/**
* 发布
* @return
*/
public static String publishWx(String mediaId){
String info="";
String access_token="";
try{
access_token = CommonUtil.getToken(ConstantUtil.app_id, ConstantUtil.app_secret).getAccessToken();
String url = ConstantUtil.sendSucaiUrl.replace("ACCESS_TOKEN",access_token);
JSONObject jsonObject = new JSONObject();
//素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
jsonObject.put("media_id", mediaId);
//发起POST请求
info = WX_TemplateMsgUtil.sendPost(jsonObject, url);
}catch (Exception e){
log.error("调用微信公众号接口出错,access_token为:【{}】,调用发布文章接口返回值为:【{}】", access_token,info);
throw new BusinessException(e.getMessage());
}
return info;
}