原创声明:本文来源于本人另一博客【发送模板消息实现消息业务实时通知 】原创作品,绝非他处摘取,转载请联系博主
前篇文章讲解了如何获取用户微信基本详情,实现微信绑定后自动登录,回看请点击这里:http://banshanxianren.iteye.com/blog/2369250
本篇文章主要介绍利用上篇文章获取到的微信ID,向已绑定用户发送模板消息,如我们常见的消费通知、订单通知等业务都可以用该功能实现。理论知识就不反复强调了,实践是检验真理的唯一标准,直接看例子,相信大家就能一目了然了。下面我们来看下要准备哪里步骤:
1.配置模板
登录测试公众号/正式公众号(认证后的服务号),测试公众号:模板消息接口->新增测试模板中添加模板,正式公众号:在功能->模板消息中添加模板,模板可以在模板库中选择,如果没有你需要的模板,可以申请添加,一个月可以申请三条。模板添加成功后,有个模板ID(用于接口调用)。
具体如何配置可以参看官方文档:https://mp.weixin.qq.com/wiki 中消息管理->发送消息-模板消息接口
2.代码应用展示
封装发送模板接口
import java.util.Map; /** * 模板基类 * @author lh * */ public class WxTemplate { private String template_id;//模板ID private String touser;//目标客户 private String url;//用户点击模板信息的跳转页面 private String topcolor;//字体颜色 private Map<String,TemplateData> 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<String,TemplateData> getData() { return data; } public void setData(Map<String,TemplateData> data) { this.data = data; } }
一条模板包含多条数据,模板数据类封装
/** * 模板数据 * @author lh * */ 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; } }
看文档,发送模板信息接口为:https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN,前期模板数据都准备好了,现在缺少ACCESS_TOKEN,缺什么就去获取什么,查看文档可知获取ACCESS_TOKEN接口为:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,现在就封装个获取ACCESS_TOKEN的请求接口:
public class WeixinUtil { private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); // 获取access_token的接口地址(GET) 限200(次/天) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * 获取access_token * @param appid 凭证 * @param appsecret 密钥 * @return */ public static AccessToken getAccessToken(String appid, String appsecret) { AccessToken accessToken = null; String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); // 如果请求成功 if (null != jsonObject) { try { accessToken = new AccessToken(); accessToken.setToken(jsonObject.getString("access_token")); accessToken.setExpiresIn(jsonObject.getInt("expires_in")); } catch (JSONException e) { accessToken = null; // 获取token失败 log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } return accessToken; } }
注意:ACCESS_TOKEN有请求次数限制,而且会在获取后7200秒后自动失效,所以要妥善保存好ACCESS_TOKEN,本实例是放在内存里面,每次获取时,判断是否已经存在,不存在才去请求,而如何保证保存的ACCESS_TOKEN为有效的呢?一般解决方法是定时请求获取最新ACCESS_TOKEN,更新内存里的数据,可使用线程定时请求、quartz,或者Spring的任务调度功能,下面展示比较通用的线程方法:
/** * 定时获取微信access_token的线程 */ public class TokenThread implements Runnable { private static Logger log = LoggerFactory.getLogger(TokenThread.class); // 第三方用户唯一凭证 public static String appid = "xxx"; // 第三方用户唯一凭证密钥 public static String appsecret = "xxxx"; public static AccessToken accessToken = null;//保存ACCESS_TOKEN到内存 public void run() { while (true) { try { accessToken = WeixinUtil.getAccessToken(appid, appsecret); if(null != accessToken) { log.info("获取access_token成功,有效时长{}秒 token:{}", accessToken.getExpiresIn(), accessToken.getToken()); // 休眠7000秒 Thread.sleep((accessToken.getExpiresIn() - 200) * 1000); }else{ // 如果access_token为null,60秒后再获取 Thread.sleep(60 * 1000); } } catch (InterruptedException e) { try{ Thread.sleep(60 * 1000); } catch (InterruptedException e1) { log.error("{}", e1); } log.error("{}", e); } } } }
现在ACCESS_TOKEN已经获取,万事俱备,只欠调用了,下面给出发送模板
/**订单模板,模板ID:ai3WcdUjq-x4v0Reir442UCIzl3AsyCgpAy0e5q2mkY(公众号后台添加模板后自动生成)**/ {{first.DATA}} 订单编号:{{keyword1.DATA}} 订单类型:{{keyword2.DATA}} 商品名称:{{keyword3.DATA}} {{remark.DATA}}
的具体调用实例:
/** * 发送模板消息调用实例 * @param websiteAndProject 请求地址与工程名:http://192.168.2.113/seafood * @param receiverWeixinId 接受者的微信ID,如何获取,可看前一篇文章 * @return */ WxTemplate template = new WxTemplate(); template.setUrl(""+TimedTask.websiteAndProject+"/weixinTwo/gotoOrderConfirm?orderId="+map.get("orderId")); template.setTouser("receiverWeixinId")); template.setTopcolor("#000000"); template.setTemplate_id("ai3WcdUjq-x4v0Reir442UCIzl3AsyCgpAy0e5q2mkY"); Map<String,TemplateData> m = new HashMap<String,TemplateData>(); TemplateData first = new TemplateData(); first.setColor("#000000"); first.setValue("您好,您有一条待确认订单。"); m.put("first", first); TemplateData keyword1 = new TemplateData(); keyword1.setColor("#328392"); keyword1.setValue("OD0001"); m.put("keyword1", keyword1); TemplateData keyword2 = new TemplateData(); keyword2.setColor("#328392"); keyword2.setValue("预定订单"); m.put("keyword2", keyword2); TemplateData keyword3 = new TemplateData(); keyword3.setColor("#328392"); keyword3.setValue("大龙虾"); m.put("keyword3", keyword3); TemplateData remark = new TemplateData(); remark.setColor("#929232"); remark.setValue("请及时确认订单!"); m.put("remark", remark); WeixinUtil.sendMessageBefore("",template, m);
public class WeixinUtil { private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); // 获取access_token的接口地址(GET) 限200(次/天) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * 获取access_token * @param appid 凭证 * @param appsecret 密钥 * @return */ public static AccessToken getAccessToken(String appid, String appsecret) { AccessToken accessToken = null; String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); // 如果请求成功 if (null != jsonObject) { try { accessToken = new AccessToken(); accessToken.setToken(jsonObject.getString("access_token")); accessToken.setExpiresIn(jsonObject.getInt("expires_in")); } catch (JSONException e) { accessToken = null; // 获取token失败 log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } return accessToken; } /** * 发送模板消息前获取token * @param template_id_short 模板库中模板的编号 * @param t * @param m */ public static void sendMessageBefore(String template_id_short,WxTemplate t,Map<String,TemplateData> m){ AccessToken token = null; if(TokenThread.accessToken==null || TokenThread.accessToken.getToken()==""){ token = WeixinUtil.getAccessToken(TokenThread.appid, TokenThread.appsecret); }else{ token = TokenThread.accessToken; } if(template_id_short!=null&&!"".equals(template_id_short)){ Template template = WeixinUtil.getTemplate(template_id_short,token.getToken()); t.setTemplate_id(template.getTemplate_id()); } t.setData(m); int result = WeixinUtil.sendMessage(t,token.getToken()); } /** * 发送模板消息 * @param t * @param accessToken * @return */ public static int sendMessage(WxTemplate t,String accessToken) { int result = 0; // 拼装创建菜单的url String url = sendTemplateMessage_url.replace("ACCESS_TOKEN", accessToken); // 将菜单对象转换成json字符串 String jsonMenu = JSONObject.fromObject(t).toString(); // 调用接口创建菜单 JSONObject jsonObject = httpRequest(url, "POST", jsonMenu); if (null != jsonObject) { if (0 != jsonObject.getInt("errcode")) { result = jsonObject.getInt("errcode"); log.error("发送模板消息失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } return result; } }
至此,发送消息流程已全部完成,如有不足,不解或者改进之处,欢迎大家在评论区指出。
相关推荐
以订单推送为例,主要为大家详细介绍了java实现微信公众号发送模版消息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-...
3、WechatAuth.class.php 封装了 微信消息及二维码类 可指定openid 发送消息 消息类型包括(text、image、voice、video、music、news、location、'link、event) 几行代码实现微信公众号中你想要的功能,详细内容请...
微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法微信公众号开发相关方法...
微信公众号运营计划方案(最新范文模板) .pdf微信公众号运营计划方案(最新范文模板) .pdf微信公众号运营计划方案(最新范文模板) .pdf微信公众号运营计划方案(最新范文模板) .pdf微信公众号运营计划方案(最新范文模板)...
PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号管理系统 PHP微信公众号...
是一款由吾爱破解论坛用户开发的微信公众号文章批量下载工具, 软件为绿色版,无需安装,解压后双击即可使用。支持下载微信公众号的历史消息,可以保存文章为html/md/pdf/docx文件。软件支持单篇下载和批量下载,...
主要介绍了C#微信公众号开发之接收事件推送与消息排重的方法,详细分析了事件推送与消息排重的使用技巧,对微信开发有一定参考借鉴价值,需要的朋友可以参考下
java二次开发接微信公众号接口,实现根据用户授权,获取用户code,再获取openid,然后向其推送模版消息
thinkphp 5.0 对接微信公众号,向指定用户发送模板消息
微信公众号认证申请公函模板.docx
文档通过已认证的微信服务号介绍了微信公众号消息模板的PHP编程对接方法,具有较好的学习和参考价值
1000套微信图文设计模板微信公众号文章模板html格式,下载打开可以直接编辑使用。涵盖各个主要节日,行业。学校教育,旅游居家生活,电商微商。新媒体文章模板。
Java 实现微信公众号模板消息推送,demo
微信消息通知,给微信公众号用户发送消息通知 本程序用laravel框架,使用的时候请根据自己的目录结构自行修改命名空间和类名继承等信息
这是一款基于ThinkPHP6.0开发的微信公众号多域名回调系统。本系统有如下功能: 微信公众号多域名回调功能:微信公众号后台默认只能授权2个网页域名,用本系统突破这个限制,用同一个公众号对接无限多个网站。网站...
微信公众号开发的必须jar包,很完整
springboot实现微信公众号模版消息推送,用的是构架:springboot+redis,详细教程:https://blog.csdn.net/chenhongming888/article/details/95173079
asp.net 微信公众号开发源码
微信公众号h5页面制作,微信公众号H5吸粉模板源码 。源码参考链接:www.pikao.cn