参考的链接:
微信公众平台测试号——模板消息发送Demo_a816120的博客-CSDN博客
开放接口 | 微信开放文档
微信公众平台
功能一:代码实现发送微信公众平台配置的模板消息
1、事先获取好appID和appsecret
2、书写发送的工具类
package com.talk915.common.templateMsg;import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.talk915.common.redis.RedisUtil;
import com.talk915.model.pojo.WxAccessToken;
import com.talk915.model.pojo.WxOpenIdInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @ClassName : WxTemplateMsgUtil* @Author : cong* @Date : 2021/11/16 17:33* @Description : 微信模板消息工具类*/@Slf4j
public class WxTemplateMsgUtil {/*** @param* @return* @Author LK* @Description 获取accessToken* @Date 2021/7/26 17:36*/public static WxAccessToken getAccessToken() {WxAccessToken cacheInfo = RedisUtil.getWxAccessToken();if(cacheInfo != null){Long expiresIn = cacheInfo.getExpiresIn();if (expiresIn > 150){return cacheInfo;}}//重新请求String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + WxTemplateMsgConstant.WX_TEMPLATE_MSG_APP_ID + "&secret=" + WxTemplateMsgConstant.WX_TEMPLATE_MSG_APP_SECRET;String ret = HttpUtil.get(url);if (StringUtils.isBlank(ret)) {return null;}Map<String, Object> map = JSONObject.parseObject(ret, Map.class);String errCode = String.valueOf(map.get("errcode"));if (StringUtils.isNotBlank(errCode) && !"null".equals(errCode)) {String errMsg = String.valueOf(map.get("errmsg"));log.error("微信获取AssessToken失败,错误码:" + errCode + ";错误消息:" + errMsg);return null;}String accessToken = String.valueOf(map.get("access_token"));String expiresIn = String.valueOf(map.get("expires_in"));WxAccessToken wxAccessToken = new WxAccessToken();wxAccessToken.setAccessToken(accessToken);wxAccessToken.setExpiresIn(Long.parseLong(expiresIn));//设置缓存RedisUtil.setWxAccessToken(wxAccessToken);return wxAccessToken;}/*** @param* @return* @Author LK* @Description 模板消息* @Date 2021/7/26 18:37*/public static String sendMsg(TemplateMessage templateMessage) {WxAccessToken accessTokenInfo = getAccessToken();String accessToken = accessTokenInfo.getAccessToken();String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;String paramStr = JSON.toJSONString(templateMessage);String ret = HttpUtil.post(url, paramStr);if (StringUtils.isBlank(ret)) {log.error("微信模板消息推送失败!");return "";}Map<String, Object> retMap = JSONObject.parseObject(ret, Map.class);Integer errCode = (Integer) retMap.get("errcode");if (errCode != 0) {String errMsg = String.valueOf(retMap.get("errmsg"));log.error("微信模板消息推送失败!,错误信息:" + errMsg);return "";}return String.valueOf(retMap.get("msgid"));}}
3、书写模板类
package com.talk915.common.templateMsg;import org.springframework.beans.factory.annotation.Value;/*** @ClassName : TemplateMsgContent* @Author : cong* @Date : 2021/11/16 16:54* @Description :*/public class TemplateMsgContent {private static boolean allowSiteEnvironment;//补偿课时通知(测试)public static String CLASS_COMPENSATE_MSG = "ygJSffhiKZOp5BjreTk3GSurJ8vqWticSbzaTEW5Nwc";//课程取消通知(测试)private static String CLASS_CANCEL_MSG = "7L3Zel6GFltH0xrf4-qNxC_wE22f_9t-Yi_-O8hT0xw";/*** @param* @return* @Author cong* @Description 课时补偿通知* @Date 2021/11/11 16:43*/public static TemplateMessage getCompensateClassTime(String compensationNum, String userName, String openId) {First first = new First("亲,您有" + compensationNum + "个课时返还信息!");Keyword[] keywords = new Keyword[2];Keyword keyword1 = new Keyword(compensationNum, "#173177");Keyword keyword2 = new Keyword(userName, "#173177");keywords[0] = keyword1;keywords[1] = keyword2;Remark remark = new Remark("感谢您的支持!");Data data = new Data(first, remark, keywords);return new TemplateMessage(openId, CLASS_COMPENSATE_MSG, data);}/*** @param* @return* @Author cong* @Description 取消课程通知* @Date 2021/11/11 16:43*/public static TemplateMessage getCancelClass(String className, String userName, String reason, String classTime, String openId) {First first = new First("你好,你的课程已被取消!");Keyword[] keywords = new Keyword[4];Keyword keyword1 = new Keyword(className, "#173177");Keyword keyword2 = new Keyword(userName, "#173177");Keyword keyword3 = new Keyword(reason, "#173177");Keyword keyword4 = new Keyword(classTime, "#173177");keywords[0] = keyword1;keywords[1] = keyword2;keywords[2] = keyword3;keywords[3] = keyword4;Remark remark = new Remark("敬请谅解,有疑问请联系管理员!");Data data = new Data(first, remark, keywords);return new TemplateMessage(openId, CLASS_CANCEL_MSG, data);}/*** @param* @return* @Author cong* @Description 正式服的相关配置* @Date 2021/3/20 10:21*/@Value("${allow.site.environment}")private void setAllowSend(boolean allowSiteEnvironment) {TemplateMsgContent.allowSiteEnvironment = allowSiteEnvironment;if (allowSiteEnvironment) {CLASS_COMPENSATE_MSG = "***";CLASS_CANCEL_MSG = "***";}}}
public class First {private String value;private String color;public First (String value){this.value = value;}
}public class Remark {private String value;private String color;public Remark (String value){this.value = value;}
}public class Data {private First first;private Keyword keyword1;private Keyword keyword2;private Keyword keyword3;private Keyword keyword4;private Remark remark;public Data(First first, Remark remark, Keyword... keyword) {this.first = first;int count = 1;for (Keyword keyword1 : keyword) {if (count == 1) {this.keyword1 = keyword1;} else if (count == 2) {this.keyword2 = keyword1;} else if (count == 3) {this.keyword3 = keyword1;} else if (count == 4) {this.keyword4 = keyword1;}count++;}this.remark = remark;}
功能二:代码实现输入关键字推送对应的内容
1、首先在微信公众平台配置回调地址 url/weChat/check
2、编写接收的接口逻辑
package com.talk915.async.controller.wx;import cn.hutool.crypto.SecureUtil;
import com.talk915.async.service.UserBindService;
import com.talk915.common.templateMsg.AesException;
import com.talk915.common.templateMsg.SHA1;
import com.talk915.common.templateMsg.WxMsgInfo;
import com.talk915.common.templateMsg.WxTemplateMsgConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;/*** @ClassName : WeChatController* @Author : cong* @Date : 2021/11/12 14:41* @Description : 微信服务号使用*/
@RestController
@RequestMapping(value = "/weChat")
public class WeChatController {@Autowiredprivate UserBindService userBindService;/*** 微信加密字符串*/private static final String token = "talk915";/*** @param* @return* @Author LK* @Description 接收微信发送数据* @Date 2021/8/12 14:44*/@PostMapping(value = "/check",produces = MediaType.APPLICATION_XML_VALUE)public String wxPostConnect(HttpServletRequest request) {try {Marshaller marshaller;Unmarshaller unmarshal;//解析对象JAXBContext jaxbContext = JAXBContext.newInstance(WxMsgInfo.class);unmarshal = jaxbContext.createUnmarshaller();//xml解码成bean对象WxMsgInfo wxMsgInfo = (WxMsgInfo) unmarshal.unmarshal(request.getInputStream());String event = wxMsgInfo.getEvent();String msgType = wxMsgInfo.getMsgType();//关注用户openIdString fromUserName = wxMsgInfo.getFromUserName();//接收的内容String msg = wxMsgInfo.getContent();//判断 1.关注/取关 2.发送消息 3.找不到相应的就推送客服链接// 判断是否为关注,subscribe(订阅)、unsubscribe(取消订阅)String content = "";if (StringUtils.isNotBlank(event)){//关注boolean isSubscribe = "subscribe".equals(event);//关注或取关boolean subscribe = "subscribe".equals(event) || "unsubscribe".equals(event);//推送默认消息if (isSubscribe) {content = WxTemplateMsgConstant.createTextMsg(1,"");}//添加/编辑 关注/取关记录if (subscribe){userBindService.addOrEditSubscribeStatus(fromUserName,isSubscribe);}} else if (StringUtils.isNotBlank(msgType) && "text".equals(msgType) && WxTemplateMsgConstant.BIND_TEXT.contains(msg)) {content = WxTemplateMsgConstant.createTextMsg(2, SecureUtil.md5(fromUserName + "TaLk#915"));} else if (StringUtils.isNotBlank(msgType) && "text".equals(msgType) && WxTemplateMsgConstant.UN_BIND_TEXT.contains(msg)){content = WxTemplateMsgConstant.createTextMsg(3,"");} else if (StringUtils.isNotBlank(msgType) && "text".equals(msgType) && StringUtils.isNotBlank(WxTemplateMsgConstant.checkUnBindText(msg))){//解除绑定content = userBindService.unBindAccount(WxTemplateMsgConstant.checkUnBindText(msg),fromUserName);} else {content = WxTemplateMsgConstant.createTextMsg(4,"");}WxMsgInfo msgInfo = new WxMsgInfo();msgInfo.setFromUserName(wxMsgInfo.getToUserName());msgInfo.setToUserName(wxMsgInfo.getFromUserName());msgInfo.setCreateTime(new Date().getTime());msgInfo.setMsgType("text");msgInfo.setContent(content);marshaller = jaxbContext.createMarshaller();StringWriter writer = new StringWriter();marshaller.marshal(msgInfo, writer);return writer.toString();} catch (Exception e) {e.printStackTrace();}return "";}
}
package com.talk915.common.templateMsg;import com.talk915.common.pattern.PatternCheckUtil;
import com.talk915.common.util.FileUrlConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;import java.util.Arrays;
import java.util.List;/*** @ClassName : WxTemplateMsgConstant* @Author : cong* @Date : 2021/11/10 18:14* @Description : 微信模板信息*/public class WxTemplateMsgConstant {private static boolean allowSiteEnvironment;/*** 测试服appId*/public static String WX_TEMPLATE_MSG_APP_ID = "wx11d4e0f54f0cbbbb";/*** 测试服appSecret*/public static String WX_TEMPLATE_MSG_APP_SECRET = "774b8b69b473fd2b03930f6bfe80010b";/*** 客服地址*/public static final String DEFAULT_CS_LINK = "服务号暂时不支持其他功能,正在完善中!若您有其他问题,您可以咨询 <a href=\"https://platform.usongshu.com/im/index.html#/robot?platformType=0&platformUserId=&platformUserType=7&platformPhone=&platformNickName=&platformTerminalType=1\">在线客服</a>";/*** 账号绑定基础链接*/private static final String BIND_BASE_URL = FileUrlConstant.getPrefixUrl() + "h5/wxBind?code=";//前缀private static final String BIND_URL_PREFIX = "<a href=\"";//后缀private static final String BIND_URL_SUFFIX = "\">点击完成账号绑定</a>";/*** 账号绑定关键词*/public static final List<String> BIND_TEXT = Arrays.asList("账号绑定","绑定账号","账号关联","关联","上课提醒","绑定","通知");/*** 账号解绑*/public static final List<String> UN_BIND_TEXT = Arrays.asList("账号解绑","解绑账号","解绑");/*** @Author LK* @Description 创建文本消息* @Date 2021/8/16 10:18* @param* @return*/public static String createTextMsg(int type,String baseContent) {String content = "";switch (type) {//1.关注默认消息case 1://content = "感谢您关注说客英语服务号!目前服务号提供上课提醒功能,回复 绑定账号,根据提示完成账号绑定即可!";content = "感谢您关注说客英语服务号!" +"目前服务号提供课前提醒和上课迟到提醒,回复:绑定,根据提示完成帐号绑定即可接收推送信息." +"如需解绑,回复:解绑_帐号,例如:解绑_12345678901";break;//2.账号绑定case 2:content = BIND_URL_PREFIX + BIND_BASE_URL + baseContent + BIND_URL_SUFFIX;break;//账号解绑case 3:content = "按照如下格式输入您需要解绑的账号即可:解绑_13700000001";break;//其他内容暂时推送客服链接default:content = DEFAULT_CS_LINK;}return content;}/*** @Author LK* @Description 检测解绑格式* @Date 2021/8/24 18:06* @param* @return*/public static String checkUnBindText(String text){if (StringUtils.isBlank(text)){return "";}boolean contains = text.contains("_");if(!contains){return "";}String[] arr = StringUtils.split(text, "_");if (!arr[0].equals("解绑")){return "";}String account = arr[1];if (StringUtils.isBlank(account)){return "";}boolean checked = PatternCheckUtil.isPhone(account);if (!checked){return "";}return account;}/*** @param* @return* @Author cong* @Description 正式服的相关配置* @Date 2021/3/20 10:21*/@Value("${allow.site.environment}")private void setAllowSend(boolean allowSiteEnvironment) {WxTemplateMsgConstant.allowSiteEnvironment = allowSiteEnvironment;if (allowSiteEnvironment) {WX_TEMPLATE_MSG_APP_ID = "***";WX_TEMPLATE_MSG_APP_SECRET = "***";}}
}