赞
踩
如果是未开通能力的账户, 在未开通里面寻找,根据提示填入相关信息即可
进入模板库,添加符合自己需求的模板消息, 在我的模板中查看模板id,如图:
查看模板消息的内容,以第四个为例
至此模板消息的功能开通完成!
消息内容
表结构(根据功能需求设计, 不必完全一样)
package net.huashitong.ssydt.wechat.entity; import io.swagger.annotations.ApiModelProperty; import net.huashitong.ssydt.base.entity.BaseEntity; import net.huashitong.ssydt.base.entity.LongEntity; /** * @author xiazz * @Date 2022/11/3 * @Description: t_template_message 公众号模板消息 */ public class TemplateMessage extends BaseEntity { @ApiModelProperty("id") private String id; @ApiModelProperty("模板id") private String templateId; @ApiModelProperty("推送时间") private String pushTime; @ApiModelProperty("副标题") private String firstData; @ApiModelProperty("关键词1") private String keyword1; @ApiModelProperty("关键词2") private String keyword2; @ApiModelProperty("关键词3") private String keyword3; @ApiModelProperty("消息跳转的url") private String referUrl; @ApiModelProperty("关联的appid") private String relateAppid; @ApiModelProperty("备注") private String remark; @ApiModelProperty("用户的openid") private String openid; @ApiModelProperty("推送类型: 1所有用户 2单个指定用户") private Integer pushType; @ApiModelProperty("推送状态: 0未推送 1已推送") private Integer pushStatus; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTemplateId() { return templateId; } public void setTemplateId(String templateId) { this.templateId = templateId; } public String getPushTime() { return pushTime; } public void setPushTime(String pushTime) { this.pushTime = pushTime; } public String getFirstData() { return firstData; } public void setFirstData(String firstData) { this.firstData = firstData; } public String getKeyword1() { return keyword1; } public void setKeyword1(String keyword1) { this.keyword1 = keyword1; } public String getKeyword2() { return keyword2; } public void setKeyword2(String keyword2) { this.keyword2 = keyword2; } public String getKeyword3() { return keyword3; } public void setKeyword3(String keyword3) { this.keyword3 = keyword3; } public String getReferUrl() { return referUrl; } public void setReferUrl(String referUrl) { this.referUrl = referUrl; } public String getRelateAppid() { return relateAppid; } public void setRelateAppid(String relateAppid) { this.relateAppid = relateAppid; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String getOpenid() { return openid; } public void setOpenid(String openid) { this.openid = openid; } public Integer getPushType() { return pushType; } public void setPushType(Integer pushType) { this.pushType = pushType; } public Integer getPushStatus() { return pushStatus; } public void setPushStatus(Integer pushStatus) { this.pushStatus = pushStatus; } }
@ApiOperation("发送模板消息") @GetMapping("/send/{id}") public Result<String> sendMsg(@PathVariable("id") String id) { String colorBlue = "#173177"; String colorRed = "#DC143C"; // 根据id获取详细的模板消息参数 TemplateMessage templateMessage = templateMessageService.info(id); if (Objects.isNull(templateMessage) || Objects.equals(1,templateMessage.getPushStatus())) { throw new ServiceException("消息不存在或者已推送"); } // 模板参数 Map<String, WeChatTemplateMsg> sendMsg = new HashMap<String, WeChatTemplateMsg>(); sendMsg.put("first",new WeChatTemplateMsg(templateMessage.getFirstData())); sendMsg.put("keyword1",new WeChatTemplateMsg(templateMessage.getKeyword1(),colorRed)); // 考试名称 sendMsg.put("keyword2",new WeChatTemplateMsg(templateMessage.getKeyword2())); // 考试单位 sendMsg.put("keyword3",new WeChatTemplateMsg(templateMessage.getKeyword3(),colorRed)); // 考试时间 sendMsg.put("remark",new WeChatTemplateMsg(templateMessage.getRemark(),colorBlue)); String accessToken = getAccessToken().getAccess_token(); // 测试: 向单个用户发送 String send = send(accessToken,"oJcdptwBGx3bSa8-FbepyxB-2Okc", templateMessage.getTemplateId(), templateMessage.getReferUrl(),templateMessage.getRelateAppid(), sendMsg); JSONObject jsonObject = JSONObject.parseObject(send); Integer errcode = (Integer) jsonObject.get("errcode"); if (Objects.equals(0,errcode)) { try { templateMessage.setPushStatus(1); // 设置为已推送 templateMessageService.update(templateMessage); } catch (Exception e) { throw new ServiceException("消息状态更新失败,原因: " + e.getMessage()); } } return ResultUtils.getSuccessResults("发送完成"); // 线上:向所有已关注公众号的用户发送模板消息 logger.info("模板消息开始发送......"); long start = System.currentTimeMillis(); List<String> openidList = new ArrayList<>(); Integer total = getOpenIdList(openidList, accessToken, ""); logger.info("关注该公众账号的总用户数:" + total); logger.info("获取到的公众号的总用户数:" + openidList.size()); // 用户数量较多, 使用多线程发送 if (total == openidList.size()) { ExecutorService executor = Executors.newFixedThreadPool(35); for (String openid : openidList) { executor.execute(new SendTask(accessToken, openid, templateMessage, sendMsg)); } } long end = System.currentTimeMillis(); // 更新消息状态 try { templateMessage.setPushStatus(1); // 设置为已推送 templateMessageService.update(templateMessage); } catch (Exception e) { throw new ServiceException("消息状态更新失败,原因: " + e.getMessage()); } logger.info("模板消息发送完成,共耗时:" + (end - start) + "ms"); return ResultUtils.getSuccessResults("发送完成"); }
public static AccessToken getAccessToken() {
String sb = "https://api.weixin.qq.com/cgi-bin/token?" +
"grant_type=client_credential" +
"&appid=" + "公众号appId" +
"&secret=" + "公众号AppSecret";
HttpRequest request = HttpRequest.get(sb);
HttpResponse response = request.send();
return JSON.parseObject(response.bodyText(),AccessToken.class);
}
/** * @date: 2022/11/2 * @description: 获取关注者的(openid列表) */ public static Integer getOpenIdList(List<String> openidList,String accessToken,String nextOpenid) { RestTemplate restTemplate = getInstance("UTF-8"); Map<String, String> params = new HashMap<>(); params.put("access_token", accessToken); // params.put("next_openid", nextOpenid); // ResponseEntity<String> responseEntity = restTemplate.getForEntity( "https://api.weixin.qq.com/cgi-bin/user/get?access_token={access_token}&next_openid={next_openid}", String.class, params ); String body = responseEntity.getBody(); JSONObject jsonObject = JSON.parseObject(body); // 解析成JSONObject 并获取(叫data的JSON对象)JSONObject // 获取 JSONObject 中的 JSONArray JSONArray array = jsonObject.getJSONObject("data").getJSONArray("openid"); List<String> currentOpenidList = array.toJavaList(String.class); openidList.addAll(currentOpenidList); Integer total = (Integer) jsonObject.get("total"); if (openidList.size() < total) { nextOpenid = (String) jsonObject.get("next_openid"); getOpenIdList(openidList,accessToken,nextOpenid); } return total; }
public class SendTask implements Runnable { private String accessToken; private String openid; private TemplateMessage templateMessage; private Map<String,WeChatTemplateMsg> dataMap; public SendTask(String accessToken,String openid,TemplateMessage templateMessage,Map<String,WeChatTemplateMsg> dataMap){ this.accessToken = accessToken; this.openid = openid; this.templateMessage = templateMessage; this.dataMap = dataMap; } public SendTask() {} public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getOpenid() { return openid; } public void setOpenids(String openid) { this.openid = openid; } public TemplateMessage getTemplateMessage() { return templateMessage; } public void setTemplateMessage(TemplateMessage templateMessage) { this.templateMessage = templateMessage; } public Map<String,WeChatTemplateMsg> getDataMap() { return dataMap; } public void setDataMap(Map<String,WeChatTemplateMsg> dataMap) { this.dataMap = dataMap; } //多线程入口 @Override public void run() { TemplateMessage templateMessage1 = this.templateMessage; String send = send(this.accessToken, openid, templateMessage1.getTemplateId(), templateMessage1.getReferUrl(), templateMessage1.getRelateAppid(), this.dataMap); JSONObject jsonObject = JSONObject.parseObject(send); Integer errcode = (Integer) jsonObject.get("errcode"); if (Objects.equals(0,errcode)) { logger.info("已向openid为" + openid + "发送通知"); } } }
/** * 2、发送模版消息 * openId 用户Id * templateId 模板Id * data 模板参数 * @param data */ public static String send(String accessToken,String openId, String templateId, String referUrl,String relateAppid, Map<String, WeChatTemplateMsg> data) { RestTemplate restTemplate = getInstance("UTF-8"); String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN"; String url = sendUrl.replace("ACCESS_TOKEN", accessToken); //拼接base参数 Map<String, Object> sendBody = new HashMap<>(); if (StringUtils.isNotBlank(relateAppid)) { Map<String, String> miniprogramMap = new HashMap<>(); miniprogramMap.put("appid", relateAppid); miniprogramMap.put("pagepath", "/pages/index/index?foo=bar"); sendBody.put("miniprogram",miniprogramMap);// 关联的小程序 } if (StringUtils.isNotBlank(referUrl)) { sendBody.put("url", referUrl);// 点击模板信息跳转地址 } sendBody.put("touser", openId); // openId sendBody.put("data", data); // 模板参数 sendBody.put("template_id", templateId); // 模板Id ResponseEntity<String> forEntity = restTemplate.postForEntity(url, sendBody, String.class); return forEntity.getBody(); }
过程中遇到了一些问题, 比如微信一次只给一万条的限制(使用递归获取前每发完一万条要重启一次服务), 使用单线程发送过慢的问题(亲测一万条数据花费1个半小时), 好在后面都解决了, 特此记录! 如果有什么不明白或者觉得说得不对的地方, 欢迎在评论区指正, 互相学习
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。