1、什么是模板消息?
微信为防止服务号对用户进行恶意骚扰和营销,而服务号在某些场景又必须给用户发送消息时(如购物成功、支付成功),这时候就可以应用微信提供的模板消息来给用户进行提醒。
比如:
2、怎么添加模板消息?
在微信公众号后台菜单里面有模板消息一栏,点击进去后可以看到模板库,可以根据自己的实际需要添加自己需要的模板消息,模板涵盖各行各业,暂不可自己编辑模板。
微信限制最多只能选择8个模板,应该也够用了。选中模板后就可以看到模板ID、标题等,这里已购买成功为列,查看详情时:
可以看到该模板需要提供的相关参数,这样就可以拼装请求的参数了。
这一步主要是要拿到模板的ID和该模板需要的参数名。
3、怎么请求发送模板?
通过在模板消息功能的模板库中使用需要的模板,可以获得模板ID。
第二步:请求接口
请注意,URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
POST请求
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
其中的POST请求中需要两个基本的技术要点:
1、获取ACCESS_TOKEN。
2、如何提交POST请求。
具体请参考开发教程系列获取ACCESS_TOKEN篇,http://kangliang.iteye.com/admin/blogs/21617
然后组装需要的JSON信息:
如:
- {
- "touser": "OPENID",
- "template_id": "ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
- "url": "http://weixin.qq.com/download",
- "topcolor": "#FF0000",
- "data": {
- "firstData": {
- "value": "恭喜您购物成功!",
- "color": "#173177"
- },
- "product": {
- "value": "韩版西服",
- "color": "#173177"
- },
- "price": {
- "value": "149元",
- "color": "#173177"
- },
- "time": {
- "value": "2014-12-04 13:09:17",
- "color": "#173177"
- },
- "remark": {
- "value": "感谢您的光临,我们将尽快发货!",
- "color": "#173177"
- }
- }
- }
因模板消息属于固定格式,可在代码中写死拼装方式:
组装json信息:
- /** 商品购买成功
- * templateId 模板ID
- * orderId 订单id
- *
- */
- String toTemplateMsgText(String orderId,String templateId){
- OrderResponse response=getOrderByOrderId(orderId);
- //查询订单信息
- Order order=response.getOrder();
- String first="您好,欢迎在新礼特购物!";
- String remark="您的收货信息:"+order.getReceiver_name()+" 电话:" +order.getReceiver_mobile()+" 地址:"+order.getReceiver_city()+order.getReceiver_zone()+order.getReceiver_address()+" 我们将尽快发货,祝您购物愉快!";
- String jsonText="{\"touser\":\"OPENID\",\"template_id\":\"templateId\",\"url\":\"\",\"topcolor\":\"#FF0000\",\"data\":{\"first\": {\"value\":\"firstData\",\"color\":\"#173177\"},\"product\": {\"value\":\"productData\",\"color\":\"#173177\"},\"price\": {\"value\":\"priceData\",\"color\":\"#173177\"},\"time\": {\"value\":\"timeData\",\"color\":\"#173177\"},\"remark\": {\"value\":\"remarkData\",\"color\":\"#173177\"}}}";
- jsonText= jsonText.replace("firstData", first).replace("templateId", templateId).replace("OPENID", order.getBuyer_openid()).replace("productData", order.getProduct_name()).replace("priceData",order.getOrder_total_price()/100f+"元").replace("timeData", order.getOrder_create_time()).replace("remarkData", remark);
- return jsonText;
- }
发送消息:
- /**
- * 发送模板消息
- * @param accessToken
- * @param jsonData
- */
- public static void sendTemplateMsg(String accessToken,String jsonData){
- String requestUrl=send_templatemsg_url.replace("ACCESS_TOKEN", accessToken);
- JSONObject jsonObject = httpRequest(requestUrl, "GET", jsonData);
- if(jsonObject!=null){
- if("0".equals(jsonObject.getString("errcode"))){
- System.out.println("发送模板消息成功!");
- }else{
- System.out.println(jsonObject.getString("errcode"));
- }
- }
- }
另附上httpRequest请求方法:
- /**
- * 发起https请求并获取结果
- *
- * @param requestUrl 请求地址
- * @param requestMethod 请求方式(GET、POST)
- * @param outputStr 提交的数据
- * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
- */
- public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
- JSONObject jsonObject = null;
- StringBuffer buffer = new StringBuffer();
- try {
- // 创建SSLContext对象,并使用我们指定的信任管理器初始化
- TrustManager[] tm = { new MyX509TrustManager() };
- SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
- sslContext.init(null, tm, new java.security.SecureRandom());
- // 从上述SSLContext对象中得到SSLSocketFactory对象
- SSLSocketFactory ssf = sslContext.getSocketFactory();
- URL url = new URL(requestUrl);
- HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
- httpUrlConn.setSSLSocketFactory(ssf);
- httpUrlConn.setDoOutput(true);
- httpUrlConn.setDoInput(true);
- httpUrlConn.setUseCaches(false);
- // 设置请求方式(GET/POST)
- httpUrlConn.setRequestMethod(requestMethod);
- if ("GET".equalsIgnoreCase(requestMethod))
- httpUrlConn.connect();
- // 当有数据需要提交时
- if (null != outputStr) {
- OutputStream outputStream = httpUrlConn.getOutputStream();
- // 注意编码格式,防止中文乱码
- outputStream.write(outputStr.getBytes("UTF-8"));
- outputStream.close();
- }
- // 将返回的输入流转换成字符串
- InputStream inputStream = httpUrlConn.getInputStream();
- InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
- String str = null;
- while ((str = bufferedReader.readLine()) != null) {
- buffer.append(str);
- }
- bufferedReader.close();
- inputStreamReader.close();
- // 释放资源
- inputStream.close();
- inputStream = null;
- httpUrlConn.disconnect();
- jsonObject = JSONObject.fromObject(buffer.toString());
- } catch (ConnectException ce) {
- } catch (Exception e) {
- }
- return jsonObject;
- }
事件推送
在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中。
1、送达成功时,推送的XML如下:
- <xml>
- <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
- <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]&g;</FromUserName>
- <CreateTime>1395658920</CreateTime>
- <MsgType><![CDATA[event]]></MsgType>
- <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
- <MsgID>200163836</MsgID>
- <Status><![CDATA[success]]></Status>
- </xml>
2、送达由于用户拒收(用户设置拒绝接收公众号消息)而失败时,推送的XML如下:
- <xml>
- <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
- <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
- <CreateTime>1395658984</CreateTime>
- <MsgType><![CDATA[event]]></MsgType>
- <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
- <MsgID>200163840</MsgID>
- <Status><![CDATA[failed:user block]]></Status>
- </xml>
在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
{ "errcode":0, "errmsg":"ok", "msgid":200228332 }
在根据相应的事件监听,就可以获取发送的状态,而及时对消息进行重复或其他的操作。