对接企业微信
1、文章 - 一键推送至公众号
1、对接 公众号
2、定时获取公众号 token ( > 2 h )
IP 白名单
IP 白名单的配置了,你的服务器 IP 是一定要配置进去的,其余的 IP 酌情添加。
参考 :
微信公众号开发:服务器配置(Java)_weixin_30349597的博客-CSDN博客 ( √ )
对接微信-----微信服务器配置(java版)_往前的娘娘的博客-CSDN博客
1、服务器配置 需要进行校验,端口需要为 80
2、可自行写代码进行校验
3、校验通过,方可进行 启用 等后续流程
natapp 存在缺陷:无法自定义选择端口号( 故此处不选择、不推荐 )
unzip /path/to/ngrok.zip
ngrok config add-authtoken 2AYennnBRpRMLL3Ucl7kIpHevkB_2MvVwUqRhi1kYa4WMfZAi
ngrok http 80
https://a1f3-113-57-86-45.jp.ngrok.io/cms/weixin/event.do?grant_type=client_credential&appid=wxedxxxxxxx73e&secret=ad387ede22xxxxxxx1dce8c1c1e58
URL:https://a1f3-113-57-86-45.jp.ngrok.io/cms/weixin/event.do 对应代码
package net.mingsoft.cms.action.web;
import net.mingsoft.cms.action.BaseAction;
import net.mingsoft.cms.util.AesException;
import net.mingsoft.cms.util.SHA1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @Author: menghuan
* @Date: 2022/6/14 14:57
*/
// @Slf4j
@ApiIgnore
@Controller("cmsWeiXin")
@RequestMapping("/cms/weixin")
public class WeiXinAction extends BaseAction {
private static final String TOKEN = "ECMS_BOLIYUAN_QIYEMENHU";
@GetMapping("/event")
public void event(HttpServletRequest request, HttpServletResponse response) throws IOException {
//微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp,nonce参数
String signature = request.getParameter("signature");
//时间戳
String timestamp = request.getParameter("timestamp");
//随机数
String nonce = request.getParameter("nonce");
//随机字符串
String echostr = request.getParameter("echostr");
String token = TOKEN;
String jiami="";
try {
jiami = SHA1.getSHA1(token, timestamp, nonce,"");//这里是对三个参数进行加密
} catch (AesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("加密"+jiami);
System.out.println("本身"+signature);
PrintWriter out=response.getWriter();
if(jiami.equals(signature)){
out.print(echostr);
}
}
}
公众平台以 access_token 为接口调用凭据,来调用接口,
所有接口的调用需要先获取 access_token,access_token 在 2 小时内有效,过期需要重新获取,
但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。
获取令牌:
"access_token": "57_jnXVM7QzA8zGAGIsxil5accpU40IYI-kFC7rw5aPWV763Zjp0hqd9seepmIMweT9XUunCsa9aQEy7F0CRfr_K0lSoG086k6LWrHNlwpcgGhYlW2TiQFKJ3yMJSlDYQC2nY2Kqt0Pk6hNtqX_TXZgAIAWAC"
https://api.weixin.qq.com/cgi-bin/draft/add?access_token={{access_token}}
{
"articles": [
{
"title": "caca",
"author": "猫猫聚会",
"content": "cacacacacacacacaca",
"thumb_media_id": "EA69IHOkcmKWQxqpOrq8UeEaBovm_n3H_0kkGyiMi_ATihrP7KDku1zZDSozsNjQ",
"need_open_comment": 0,
"only_fans_can_comment": 0
}
]
}
详参:
微信开放文档
亲测,可用
package net.mingsoft.cms.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Map;
/**
* http请求工具
*/
@Slf4j
public class HttpUtil {
// private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
/**
* 发送post请求
* @param json 参数体
* @param URL 请求地址
* @return 返回结果
*/
public static String sendPost(JSONObject json, String URL) {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(URL);
post.setHeader("Content-Type", "application/json");
post.setHeader("User-Agent", "Apipost client Runtime/+https://www.apipost.cn/");
// post.addHeader("Authorization", "Basic YWRtaW46");
String result;
try {
StringEntity s = new StringEntity(json.toString(), "utf-8");
s.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(s);
// 发送请求
HttpResponse httpResponse = client.execute(post);
// 获取响应输入流
InputStream inStream = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader( inStream, "utf-8"));
StringBuilder strBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
strBuilder.append(line + "\n");
inStream.close();
result = strBuilder.toString();
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
log.info("请求服务器SUCCESS");
// System.out.println("请求服务器成功,做相应处理");
} else {
log.info("请求服务端FALSE");
// System.out.println("请求服务端失败");
}
} catch (Exception e) {
log.error("请求异常EXCEPTION:"+e.getMessage());
throw new RuntimeException(e);
}
return result;
}
/**
* 发送get请求
* @param url 请求URL
* @param param 请求参数 key:value url携带参数 或者无参可不填
* @return
*/
public static String sendGet(String url, Map param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static void main(String[] args) {
JSONObject EventTraceInput = new JSONObject();
String url="https://api.weixin.qq.com/cgi-bin/draft/add?access_token=57_espiUswWO3w-v7qQQavrnPVOcmpwZ6UDZ12k7iLBWGbzflCe01NvDAQUnEqzBzKxGHJpkmo6PfbcMjKmPz9-toqDnXpCJ0GDeDvIFxIyy3x3yaf7jUIpr8MoNhcE51VzdN3RLneP_g43MB1cBZKbADAKIT";
JSONArray EventArray = new JSONArray();
JSONObject jsonArray = new JSONObject();
jsonArray.put("title","caca");
jsonArray.put("author","猫猫聚会");
jsonArray.put("content","cacacacacacacacaca");
jsonArray.put("thumb_media_id","EA69IHOkcmKWQxqpOrq8UeEaBovm_n3H_0kkGyiMi_ATihrP7KDku1zZDSozsNjQ");
jsonArray.put("need_open_comment",0);
jsonArray.put("only_fans_can_comment",0);
EventArray.add(jsonArray);
EventTraceInput.put("articles",EventArray);
String strResult = sendPost(EventTraceInput, url);
System.out.println(
strResult
);
log.info("strResult:{}",strResult);
}
}
/**
* 新增文章草稿
* @return String 返回新增草稿 media_id,用于后续发布
*/
private String insertContentDraft(WxCore wxCore, ContentEntity contentEntity){
String accessToken = "access_token=" + wxCore.getWxAccessToken();
// 构造参数消息体
JSONObject eventTraceInput = new JSONObject();
String url="https://api.weixin.qq.com/cgi-bin/draft/add?" + accessToken;
JSONArray eventArray = new JSONArray();
JSONObject jsonArray = new JSONObject();
jsonArray.put("title",contentEntity.getContentTitle());
jsonArray.put("content",contentEntity.getContentDetails());
jsonArray.put("thumb_media_id","EA69IHOkcmKWQxqpOrq8UeEaBovm_n3H_0kkGyiMi_ATihrP7KDku1zZDSozsNjQ");
jsonArray.put("author",wxCore.getWxName());
jsonArray.put("need_open_comment",0);
jsonArray.put("only_fans_can_comment",0);
eventArray.add(jsonArray);
eventTraceInput.put("articles",eventArray);
// 发送请求
String strResult = HttpUtil.sendPost(eventTraceInput, url);
log.info("strResult:{}",strResult);
try{
Map mapResult = objectMapper.readValue(strResult, Map.class);
if (null != mapResult){
if (mapResult.containsKey("errcode") && StringUtils.isNotBlank(mapResult.get("errcode").toString()) && "42001".equals(mapResult.get("errcode").toString())){
throw new MCmsException("新增文章草稿异常:访问令牌过期,请核实后操作");
}
if(StringUtils.isNotBlank(mapResult.get("media_id").toString())){
log.info("同步新增文章草稿SUCCESS,草稿MEDIA_ID:{}",mapResult.get("media_id").toString());
return mapResult.get("media_id").toString();
}
}
throw new MCmsException("新增文章草稿异常,请核实后操作");
} catch (IOException e) {
log.error("解析失败...");
e.printStackTrace();
throw new MCmsException("文章草稿信息解析失败,请核实后操作");
}
}
/**
* 发布文章(草稿)
* @return String 返回新增草稿 media_id,用于后续发布
*/
private Boolean pushContentDraft(WxCore wxCore, String mediaId){
String accessToken = "access_token=" + wxCore.getWxAccessToken();
// 构造参数消息体
JSONObject eventTraceInput = new JSONObject();
String url = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?" + accessToken;
eventTraceInput.put("media_id",mediaId);
// 发送请求
String strResult = HttpUtil.sendPost(eventTraceInput, url);
try{
Map mapResult = objectMapper.readValue(strResult, Map.class);
if (null != mapResult && StringUtils.isNotBlank(mapResult.get("errcode").toString())){
if ("0".equals(mapResult.get("errcode").toString())){
log.info("发布文章(草稿)SUCCESS,ERRCODE状态码:{}",0);
return true;
}
if ("40001".equals(mapResult.get("errcode").toString())){
throw new MCmsException("AppSecret错误或失效,请开发者确认 AppSecret 的正确性");
}
}
} catch (IOException e) {
log.error("解析失败...");
e.printStackTrace();
}
return false;
}
/**
* 查询激活状态微信公众号的access_token
* @return Boolean.TRUE or Boolean.FALSE
*/
public String queryWXAccessToken(WxCore wxCore){
String accessToken = "access_token=" + wxCore.getWxAccessToken();
// 构造参数消息体
// JSONObject eventTraceInput = new JSONObject();
String url = "https://api.weixin.qq.com/cgi-bin/token?" + accessToken;
// eventTraceInput.put("media_id",mediaId);
Map param = new HashMap<>();
param.put("grant_type","client_credential");
param.put("appid",wxCore.getWxAppId());
param.put("secret",wxCore.getWxAppSecret());
// 发送请求
// String strResult = HttpUtil.sendPost(eventTraceInput, url);
String strResult = HttpUtil.sendGet(url, param);
try{
Map mapResult = objectMapper.readValue(strResult, Map.class);
if (null != mapResult){
if (StringUtils.isNotBlank(mapResult.get("access_token").toString())){
return mapResult.get("access_token").toString();
}
if ("40013".equals(mapResult.get("errcode").toString())){
throw new MCmsException("AppID错误或无效,请开发者确认 AppID 的正确性");
}
if ("0".equals(mapResult.get("errcode").toString())){
log.info("查询access_token请求发送成功SUCCESS");
}
}
} catch (IOException e) {
log.error("解析失败...");
e.printStackTrace();
}
return "FALSE";
}
至此,微信公众号其他操作,按需对接、按需操作,哇咔咔......