1、什么是模板消息?
微信为防止服务号对用户进行恶意骚扰和营销,而服务号在某些场景又必须给用户发送消息时(如购物成功、支付成功),这时候就可以应用微信提供的模板消息来给用户进行提醒。
比如:
2、怎么添加模板消息?
在微信公众号后台菜单里面有模板消息一栏,点击进去后可以看到模板库,可以根据自己的实际需要添加自己需要的模板消息,模板涵盖各行各业,暂不可自己编辑模板。
?
微信限制最多只能选择8个模板,应该也够用了。选中模板后就可以看到模板ID、标题等,这里已购买成功为列,查看详情时:
?可以看到该模板需要提供的相关参数,这样就可以拼装请求的参数了。
这一步主要是要拿到模板的ID和该模板需要的参数名。
3、怎么请求发送模板?
? 第一步:获取模板ID?其中的POST请求中需要两个基本的技术要点:
? ? 1、获取ACCESS_TOKEN。
? ? 2、如何提交POST请求。
具体请参考开发教程系列获取ACCESS_TOKEN篇,http://kangliang.iteye.com/admin/blogs/21617
然后组装需要的JSON信息:
如:
?
class="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 }
?
在根据相应的事件监听,就可以获取发送的状态,而及时对消息进行重复或其他的操作。
?
?
?