博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微信模板消息
阅读量:5813 次
发布时间:2019-06-18

本文共 17459 字,大约阅读时间需要 58 分钟。

hot3.png

任务描述

原本的消息推送分为两个类型,文本消息和图文消息。现在要将其中一部分修改为图文消息。参考:

准备工作

首先应该去微信的官方客服购买消息模板,购买以后会获得template_id_short,即模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式。并且会有对应的模板样式,如下:

{
{first.DATA}}订单号:{
{keyword1.DATA}}商品名称:{
{keyword2.DATA}}收件人姓名:{
{keyword3.DATA}}收件人电话:{
{keyword4.DATA}}收件人地址:{
{keyword5.DATA}}{
{remark.DATA}}您提交的发货订单已发货订单号:5244030005646商品名称:某商品收件人姓名:陈璐收件人电话:13522211111收件人地址:广东省 广州市 天河区 科韵北路112号如有疑问,请尽快联系我们。

注意事项

  1. 模板中的关键字,必须与模板保持一致,否则模板并不会识别。如:{
    {first.DATA}},最后保存JSON 的时候,名字应为{"first",first}. 2.申请模板之后,模板的存储数量有限,所以需要写方法,将已经获取的模板id(template_id)存放在缓存或者数据库中,下一次以同样的appid和template_id_short去获取template_id时,先判断是否已经在缓存或数据库中存在,若不存在,再去获取。 3.微信中可以存放的模板id数量有限,所以需要方法去判断之前是否申请过模板id,保证模板id不会重复被申请。 4.如果模板出现错误,应该删除更新。 5.如果出现错误,去官方文档中可以查询到错误原因。 /暂时想到的就这么多,如果还有其他,欢迎补充/

###1. 获取access_token的方法

@Componentpublic class WxCacheManager extends CacheManager
{ @Autowired private JedisManager manager; @Override public int getDbIndex() { return IConstants.DB_INDEX_VARIABLE; } @Override public JedisManager getJedisManager() { return manager; } /** * 获取指定公众号的access_token * @param appid 公众号的appid * @return */ public String getTokenFromCache(String appid){ String access_token = (String)this.getByKey("access_token_" + appid); if(Commons.isNull(access_token)){ String appsecret = WeixinUtil.getAppsecret(appid); AccessToken accessToken = WeixinUtil.getAccessToken(appid, appsecret); access_token = accessToken.getToken(); if(!Commons.isNull(access_token)){ this.setKeyValue("access_token_" + appid,access_token,7000); } } return access_token; } /** * 获得指定公众号的jsApiTicket * @param appid 公众号的appid * @return */ public String getJsApiTicketFromCache(String appid){ String jsApiTicket = (String)this.getByKey("jsApiTicket_" + appid); if(Commons.isNull(jsApiTicket)){ JsApiTicket jsTicket = WeixinUtil.getJsTicket(getTokenFromCache(appid)); jsApiTicket = jsTicket.getTicket(); if(!Commons.isNull(jsApiTicket)){ this.setKeyValue("jsApiTicket_" + appid,jsApiTicket,7000); } } return jsApiTicket; } /** * 从缓存中查询微信用户信息 * @param appid * @param openid * @return */ public UserInfo getUserInfoFromCache(String appid, String openid){ UserInfo userinfo = (UserInfo)super.getByKey("userinfo_" + appid + "_" + openid); if(Commons.isNull(userinfo)){ userinfo = WeixinUtil.getUserInfoByOpenid(this.getTokenFromCache(appid),openid); if(userinfo!=null){ super.setKeyValue("userinfo_" + appid + "_" + openid,userinfo,3600); } } return userinfo; } /** * 将微信用户信息添加到缓存 * @param userinfo * @param appid */ public void setUserInfoCache(UserInfo userinfo, String appid){ if(!Commons.isNull(userinfo) && !Commons.isNull(userinfo.getOpenid()) && !Commons.isNull(appid)){ this.setKeyValue("userinfo_" + appid + "_" + userinfo.getOpenid(),userinfo,3600); } } /** * 从缓存中获取指定公众号信息 * @param appid * @return */ public Wbapp getWbappFromCache(String appid){ return null; /*return (Wbapp)this.getByKey("wbapp_" + appid);*/ } /** * 将公众号信息添加到缓存 * @param wbapp */ public void setWbappCache(Wbapp wbapp){ if(!Commons.isNull(wbapp)){ this.setKeyValue("wbapp_" + wbapp.getAppid(),wbapp,7000); } } /** * 从缓存中查询用户基本信息 * @param id * @return */ public WbUser getWbUserFromCache(Long id){ return null; //return (WbUser)super.getByKey(WbUser.class.getCanonicalName() + id); } /** * 将用户基本信息添加到缓存 * @param wbuser */ public void setWbUserCache(WbUser wbuser){ if(!Commons.isNull(wbuser)){ this.setKeyValue(WbUser.class.getCanonicalName() + wbuser.getId(),wbuser,7000); } } public Long getSyncTimesFromCache(String appid){ return (Long)this.getByKey("wzc_synctimes_" + appid); } public void setSyncTimesCache(String appid,Long time){ if(!Commons.isNull(appid) && !Commons.isNull(time)){ this.setKeyValue("wzc_synctimes_" + appid,time,24*60*60); } }}

2. 模板消息类

public class WxTemplate {	private String template_id;	private String touser;	private String url;	private String topcolor;	private Map
data; public String getTemplate_id() { return template_id; } public void setTemplate_id(String template_id) { this.template_id = template_id; } public String getTouser() { return touser; } public void setTouser(String touser) { this.touser = touser; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getTopcolor() { return topcolor; } public void setTopcolor(String topcolor) { this.topcolor = topcolor; } public Map
getData() { return data; } public void setData(Map
data) { this.data = data; }}

3.设置每条模板消息信息的类

public class TemplateData {	private String value;	private String color;	public String getValue() {		return value;	}	public void setValue(String value) {		this.value = value;	}	public String getColor() {		return color;	}	public void setColor(String color) {		this.color = color;	}	}

4.模板消息使用方法部分

//消息类型@Servicepublic class MessageUtil {	/**	 * 发送模板消息	 * @param appid	 * @param openid	 * @param template_id  模板id	 * @param data 模板消息内容	 * @param url  URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击	 */	public static void sendTemplateMessage(String appid, String openid, String template_id, Map
data, String url, String template_id_short){ WxCacheManager wxCacheManager = SpringContextHolder.getBean(WxCacheManager.class); WxTemplate wxTemplate = new WxTemplate(); wxTemplate.setTouser(openid); wxTemplate.setTemplate_id(template_id); //微信端页面是否有跳转,通过判断跳转链接是否为空来决定,所以当url为空时,将链接设置为"" if (url==null){ wxTemplate.setUrl(""); }else { wxTemplate.setUrl(url); } wxTemplate.setData(data); String access_token = wxCacheManager.getTokenFromCache(appid); String request_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token; JSONObject returnObj = com.xiangshi.wzc.wx.util.MessageUtil.httpRequest(request_url, "POST", JSONObject.fromObject(wxTemplate).toString()); if(returnObj.containsKey("errcode") && "40037".equals(returnObj.getString("errcode"))) { ActiveMQQueue dest = new ActiveMQQueue("Wzc_template_List"); long delayTime = TimingConstants.DELAY_TIME_TWO_SECOND; Map
map = new HashMap
(); map.put("appid", appid); map.put("openid", openid); map.put("template_id", template_id); map.put("data", data); map.put("url", url); map.put("template_id_short", template_id_short); JSONObject jsonObject = JSONObject.fromObject(map); SendMessage sendMessage = SpringContextHolder.getBean(SendMessage.class); sendMessage.sendSingle(jsonObject.toString(), dest, delayTime); } } /** * 获取模板id * @param appid * @param template_id_short 模板库中模板的编号 * @return */ public static String applyTemplateID(String appid,String template_id_short){ WxCacheManager wxCacheManager = SpringContextHolder.getBean(WxCacheManager.class); String access_token = wxCacheManager.getTokenFromCache(appid); String request_url = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=" + access_token; Map
map = new HashMap
(); map.put("template_id_short",template_id_short); JSONObject resultObj = com.xiangshi.wzc.wx.util.MessageUtil.httpRequest(request_url, "POST", JSONObject.fromObject(map).toString()); if (resultObj.containsValue("ok")){ return String.valueOf(resultObj.get("template_id")); }else { return null; } } /** * 获取模板列表 * @param appid * @return */ public static JSONArray getTemplateList(String appid) { WxCacheManager wxCacheManager = SpringContextHolder.getBean(WxCacheManager.class); String access_token = wxCacheManager.getTokenFromCache(appid); String request_url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=" + access_token; JSONObject resultObj = com.xiangshi.wzc.wx.util.MessageUtil.httpRequest(request_url, "GET", null); if(resultObj.containsKey("template_list")) { return resultObj.getJSONArray("template_list"); } else { return null; } } /** * 根据模板id删除模板 * @param appid * @param template_id */ public static void deleteTemplateById(String appid, String template_id) { WxCacheManager wxCacheManager = SpringContextHolder.getBean(WxCacheManager.class); String access_token = wxCacheManager.getTokenFromCache(appid); String request_url = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token=" + access_token; Map
map = new HashMap
(); map.put("template_id", template_id); com.xiangshi.wzc.wx.util.MessageUtil.httpRequest(request_url, "POST", JSONObject.fromObject(map).toString()); } public static void main(String[] args){ }}

5.获取模板id的时候,判断模板是否已经存在,更新模板id

@Servicepublic class MessageWxTemplateServiceImpl extends BaseServiceImpl
implements MessageWxTemplateService { @Autowired private MessageWxTemplateDao messageWxTemplateDao; @Autowired private WxCacheManager cacheManager; private static final String CACHE_PREFIX = "WXTemplateID_"; private static final Integer TIME_ONE_DAY_SECOND = 24 * 60 * 60; @Override protected BaseDao
getBaseDao() { return messageWxTemplateDao; } @Override public String getApplyTemplateID(String appid, String template_id_short){ String templateid = (String) cacheManager.getByKey(CACHE_PREFIX+appid+"_"+template_id_short); if(templateid==null){ MessageWxTemplate messageWxTemplate = new MessageWxTemplate(); messageWxTemplate.setTemplate_id_short(template_id_short); messageWxTemplate.setAppid(appid); messageWxTemplate = messageWxTemplateDao.selectOne(messageWxTemplate); if(messageWxTemplate==null){ templateid = MessageUtil.applyTemplateID(appid,template_id_short); messageWxTemplate = new MessageWxTemplate(); messageWxTemplate.setTemplate_id_short(template_id_short); messageWxTemplate.setAppid(appid); messageWxTemplate.setTemplate_id(templateid); this.insert(messageWxTemplate); return templateid; } else { setTemplateCache(messageWxTemplate); return messageWxTemplate.getTemplate_id(); } } else { return templateid; } } @Override public String updateTemplateID(String appid, String template_id, String template_id_short) { //1-1.获取模板编号在数据库中对应的信息 MessageWxTemplate query = new MessageWxTemplate(); query = new MessageWxTemplate(); query.setAppid(appid); query.setTemplate_id_short(template_id_short); MessageWxTemplate template = messageWxTemplateDao.selectOne(query); if (!Commons.isNull(template)) { //1-2.清除缓存中数据 delTemplateCache(appid, template_id_short); //1-3.将此错误模板信息从数据库删除 messageWxTemplateDao.deleteById(template.getId()); } //1-4.获取数据库中平台所有的模板信息 query = new MessageWxTemplate(); query.setAppid(appid); List
templates = messageWxTemplateDao.selectList(query); //2.获取微信中平台所有的模板信息 JSONArray templatesWX = MessageUtil.getTemplateList(appid); //3.比对,将错误的模板删掉(删掉的是所有的错误模板) boolean next = true; if (!Commons.isNull(templates) && templates.size() > 0 && !Commons.isNull(templatesWX) && templatesWX.size() > 0 ) { for (int i = 0; i < templatesWX.size(); i++) { JSONObject templateInfo = templatesWX.getJSONObject(i); //表示此模板是否需要删除,默认需要删除 boolean b = true; if (templateInfo.containsKey("template_id")) { //3-1.循环比较微信中的模板是否也在数据库中 for (MessageWxTemplate mwt : templates) { //3-1-1.此模板存在,不需要删除 if (templateInfo.getString("template_id").equals(mwt.getTemplate_id())) { b = true; break; } } if (!b) { //3-1-2.此模板存在,需要删除 MessageUtil.deleteTemplateById(appid, templateInfo.getString("template_id")); } } } } else if ((Commons.isNull(templates) || templates.size() == 0) && !Commons.isNull(templatesWX) && templatesWX.size() > 0 ) { for (int i = 0; i < templatesWX.size(); i++) { JSONObject templateInfo = templatesWX.getJSONObject(i); if (templateInfo.containsKey("template_id")) { MessageUtil.deleteTemplateById(appid, templateInfo.getString("template_id")); } } } //5.根据template_id_short获取新的template_id String new_template_id = MessageUtil.applyTemplateID(appid, template_id_short); if (Commons.isNull(new_template_id)) { return null; } return new_template_id; } @Override public void insert(MessageWxTemplate entity) { if(entity==null||entity.getTemplate_id_short()==null||entity.getAppid()==null||entity.getTemplate_id()==null){ return; } super.insert(entity); setTemplateCache(entity); } private void setTemplateCache(MessageWxTemplate entity){ cacheManager.setKeyValue(CACHE_PREFIX+entity.getAppid()+"_"+entity.getTemplate_id_short(), entity.getTemplate_id(), TIME_ONE_DAY_SECOND); } private void delTemplateCache(String appid, String template_id_short){ cacheManager.deleteByKey(CACHE_PREFIX+appid+"_"+template_id_short); }}

6.发送模板消息

//获取模板id                        String template_id = messageWxTemplateService.getApplyTemplateID(appid,"OPENTM*********");                        if (template_id!=null||template_id!="") {                            messages.setMsgtype("模板通知");                            //修改为模板消息                            //{
{first.DATA}} TemplateData first = new TemplateData(); first.setValue("您提交的发货订单已发货"); first.setColor("#173177 "); //订单内容:{
{keyword1.DATA}} TemplateData keyword1 = new TemplateData(); keyword1.setValue(order.getProname()); keyword1.setColor("#173177 "); //物流服务:{
{keyword2.DATA}} TemplateData keyword2 = new TemplateData(); keyword2.setValue(deliverOrder.getExpress()); keyword2.setColor("#173177 "); //快递单号:{
{keyword3.DATA}} TemplateData keyword3 = new TemplateData(); keyword3.setValue(deliverOrder.getExpressno()); keyword3.setColor("#173177 "); //收货信息:{
{keyword4.DATA}} TemplateData keyword4 = new TemplateData(); StringBuffer receiveMessage = new StringBuffer(); receiveMessage.append(deliverOrder1.getConsignee()); receiveMessage.append(" "); receiveMessage.append(deliverOrder1.getConsigneemobile()); receiveMessage.append(" "); receiveMessage.append(deliverOrder1.getP_c_d()); receiveMessage.append(" "); receiveMessage.append(deliverOrder1.getAddress()); keyword4.setValue(receiveMessage.toString()); keyword4.setColor("#173177 "); //{
{remark.DATA}} TemplateData remark = new TemplateData(); remark.setValue("\n如有疑问,请尽快联系我们。"); remark.setColor("#173177 "); Map
data = new HashMap<>(); data.put("first", first); data.put("keyword1", keyword1); data.put("keyword2", keyword2); data.put("keyword3", keyword3); data.put("keyword4", keyword4); data.put("remark", remark); MessageUtil.sendTemplateMessage(appid, wbUser1.getOpenid(), template_id, data, Commons.getClientServer() + "/wzc/order/" + order.getId() + "?state=" + appid, "OPENTM************");

最后的话

本来写工作日志是不打算公开的,毕竟觉得自己看看就好了,但是之前有人跟我说,公开之后,让别人看到,有人指出不足,会更好,所以还是公开好了~"OPENTM************"然后这一部分是被我手动注释掉了。写东西完全按照自己的思维来,比较乱。就是这样。

转载于:https://my.oschina.net/LYQ19941105/blog/846881

你可能感兴趣的文章
删除设备和驱动器中软件图标
查看>>
第四章 TCP粘包/拆包问题的解决之道---4.1---
查看>>
html语言
查看>>
从源码看集合ArrayList
查看>>
spring-boot支持websocket
查看>>
菜鸟笔记(一) - Java常见的乱码问题
查看>>
我理想中的前端工作流
查看>>
记一次Git异常操作:将多个repository合并到同一repository的同一分支
查看>>
CodeIgniter 3.0 新手捣鼓源码(一) base_url()
查看>>
Chrome 广告屏蔽功能不影响浏览器性能
查看>>
vSphere 6将于2月2日全球同步发表
查看>>
Android状态栏实现沉浸式模式
查看>>
让你的APP实现即时聊天功能
查看>>
iOS 绝对路径和相对路径
查看>>
使用Openfiler搭建ISCSI网络存储
查看>>
应用新安全组 - 每天5分钟玩转 OpenStack(116)
查看>>
iOS - UIViewController
查看>>
IntPtr 转 string
查看>>
学生名单
查看>>
(转) 多模态机器翻译
查看>>