微信公众号发送模版消息

背景:

当用户发布任务的时候,公众号会自动推送消息通知。例如我们都熟悉的场景:微信支付的时候,公众号会推送支付成功消息。

申请模版:

模版消息,顾名思义,就是有模版的消息,那么要模版干嘛呢?模版是从哪来呢?
发送消息需要有固定的格式,我们可以在微信公众号平台上配置模版。

微信公众号平台–>广告与服务–>模版消息–>我的模版
「我的模版」列表里的是已经申请的模版,如果里面的模版格式都不符合自己业务,可以到模版库里找,然后添加到「我的模版」。也可以按照自己的需求申请新的模版,一般第二个工作日会审核通过。

https://mp.weixin.qq.com/

打开模版详情,查看模版的格式,下图左边红框是消息最终展示的效果,
右边红框是需要传的参数。

有了模版之后,模版ID就是我们要放进代码里的,把模版ID复制出来。

发送模版消息接口文档:

消息模版准备好之后,暂时不要写代码奥,查看微信开发文档,看看发送模版都需要哪些参数。

微信开发文档–>基础消息能力–>模版消息接口–「发送模版消息」
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html

微信开发文档参数介绍

发送模版消息

http请求方式: POST 请求地址: https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN


注:
url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。

返回码说明:
在调用模板消息接口后,会返回JSON数据包。
返回JSON数据包示例如下
{
“errcode”:0,
“errmsg”:“ok”,
“msgid”:200228332
}

发送模版所需参数:
模版ID和openId是必须有的,剩下的就是和自己业务有关了。

上面的内容都搞定之后,就可以开始撸代码了

发送模版微信返回Dto

@Data
public class TemplateMsgResultDto extends ResultState {/*** 消息id(发送模板消息)*/private String msgid;}

发送模版微信返回状态

@Data
public class ResultState implements Serializable {/*** 状态码*/private int errcode;/*** 信息*/private String errmsg;}

微信模版消息请求参数实体类

@Data
public class WxTemplateMsg {/*** 接收者openId*/private String touser;/*** 模板ID*/private String template_id;/*** 模板跳转链接*/private String url;/*** 消息data*/private TreeMap<String, TreeMap<String, String>> data;/*** 参数** @param value 值* @param color 颜色* @return params*/public static TreeMap<String, String> item(String value, String color) {TreeMap<String, String> params = new TreeMap<String, String>();params.put("value", value);params.put("color", color);return params;}
}

Java封装模版信息代码

 public TemplateMsgResultDto noticeTemplate(TemplateMsgVo templateMsgVo) {// 模版IDString templateId="XXX";TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();//根据具体模板参数组装params.put("first", WxTemplateMsg.item("恭喜!您的需求已发布成功", "#000000"));params.put("keyword1", WxTemplateMsg.item(templateMsgVo.getTaskName(), "#000000"));params.put("keyword2", WxTemplateMsg.item("需求已发布", "#000000"));params.put("remark", WxTemplateMsg.item("请耐心等待审核", "#000000"));WxTemplateMsg wxTemplateMsg = new WxTemplateMsg();// 模版IDwxTemplateMsg.setTemplate_id(templateId);// openIdwxTemplateMsg.setTouser(templateMsgVo.getOpenId());// 关键字赋值wxTemplateMsg.setData(params);String data = JsonUtils.ObjectToString(wxTemplateMsg);return handleSendMsgLog(data);}

发送模版代码

    private TemplateMsgResultDto handleSendMsgLog(String data) {TemplateMsgResultDto resultDto = new TemplateMsgResultDto();try {resultDto = sendTemplateMsg(data);} catch (Exception exception) {log.error("发送模版失败",  exception);}// TODO 可以记录一下发送记录的日志return resultDto;}public TemplateMsgResultDto sendTemplateMsg(String data) throws Exception {// 获取tokenString accessToken = getAccessToken();// 发送消息HttpResult httpResult = HttpUtils.stringPostJson(ConstantsPath.SEND_MESSAGE_TEMPLATE_URL + accessToken, data);return IMJsonUtils.getObject(httpResult.getBody(), TemplateMsgResultDto.class);}/*** 获取全局token*/public String getAccessToken() {String key = ConstantsRedisKey.ADV_WX_ACCESS_TOKEN;// 从redis缓存中获取tokenif (redisCacheManager.get(key) != null) {return (String) redisCacheManager.get(key);}// 获取access_tokenString url = String.format(ConstantsPath.WX_ACCESS_TOKEN_URL, appid, secret);ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);if (result.getStatusCode() == HttpStatus.OK) {JSONObject jsonObject = JSON.parseObject(result.getBody());String accessToken = jsonObject.getString("access_token");// Long expires_in = jsonObject.getLong("expires_in");redisCacheManager.set(key, accessToken, 1800);return accessToken;}return null;}

微信地址常量类

public class ConstantsPath {/*** 微信公众号获取全局token*/public static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";/*** 微信发送模版消息*/public static final String SEND_MESSAGE_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";}

Json工具类

package com.demo.advertiser.common.utils;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cglib.beans.BeanMap;import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Slf4j
public class JsonUtils {private static ObjectMapper json;static {json = new ObjectMapper();json.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));json.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);}/*** 序列化为JSON字符串*/public static String ObjectToString(Object object) {try {return (json.writeValueAsString(object));} catch (Exception e) {log.error("序列化为JSON字符串出错",e);}return null;}public static <T> T getObject(String jsonString, Class<T> clazz) {if (StringUtils.isEmpty(jsonString))return null;try {return json.readValue(jsonString, clazz);} catch (Exception e) {log.error("将JSON字符串转化为Map出错",e);return null;}}}

Http工具类

package com.demo.advertiser.common.utils;import com.google.common.base.Splitter;
import com.demo.advertiser.common.utils.component.HttpResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Component
@Slf4j
public class HttpUtils {private static String sourcePath;public static HttpResult stringPostJson(String path, String content) throws Exception{return stringPost(path, null, content, "utf-8", "utf-8", "application/json");}public static HttpResult stringPost(String path, Map<String,String> headerMap, String content, String contentencode, String encode, String contentType) throws Exception{StringEntity entity = new StringEntity(content, contentencode);entity.setContentType(contentType);return post(path, headerMap, entity, encode);}private static HttpResult post(String path, Map<String,String> headerMap, HttpEntity entity, String encode){HttpResult httpResult = new HttpResult();CloseableHttpClient httpClient = null;CloseableHttpResponse response = null;try{HttpPost httpPost = new HttpPost(getURI(path));LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();httpClient = HttpClientBuilder.create().setRedirectStrategy(redirectStrategy).build();RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).setConnectionRequestTimeout(120000).setCircularRedirectsAllowed(true).setRedirectsEnabled(true).setMaxRedirects(5).build();httpPost.setConfig(requestConfig);httpPost.setHeader("User-Agent", header);if(headerMap != null && headerMap.size() > 0){for(String name:headerMap.keySet()) {httpPost.addHeader(name, headerMap.get(name));}}httpPost.setEntity(entity);response = httpClient.execute(httpPost);httpResult.setStatus(response.getStatusLine().getStatusCode());if(httpResult.getStatus() == 200){HttpEntity resEntity = response.getEntity();httpResult.setBody(EntityUtils.toString(resEntity, encode));}}catch(Exception ex){log.error("post请求出错", ex);}finally{try{if(response != null){response.close();}if(httpClient != null){httpClient.close();}}catch(Exception ex) {log.error("post请求关闭资源出错", ex);}}return httpResult;}
}
package com.demo.advertiser.common.utils.component;public class HttpResult {private Integer status = 601;private String body = "";public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}
}

微信公众号发送模版消息 Java实现相关推荐

  1. 微信公众号发送模版消息详细过程

    前置条件,具有模版消息权限的公众号(可以直接用测试号),rest测试工具(windows推荐使用火狐浏览器插件RestClient,会翻墙的话可以用谷歌的插件Postman好像) 如下 1.配置配置模 ...

  2. 微信公众号发送模版消息

    在我们购买商品或其他操作的时候,这时候微信公众号会推送相关模版消息.接下来简单介绍开发流程:(本文以订单推送为例) 测试号新建模版消息 格式如下: {{first.DATA}} 用户名:{{keywo ...

  3. 微信公众号 java发送消息_微信公众号发送模板消息 Java实现。

    本博文是测试公众号调用模板接口测试.请不要完全复制我的代码.里面的测试代码中有本人测试号的微信模板id.麻烦替换成自己的可以吗? 第一步:创建模板信息 第二步:准备模板代码实体类用到的属性自行加入就行 ...

  4. java 模板接口开发_微信公众平台 发送模板消息(Java接口开发)

    前言:最近一直再弄微信扫码推送图文消息和模板消息发送,感觉学习到了不少东西.今天先总结一下微信公众平台模板消息的发送.因为这个自己弄了很久,开始很多地方不明白,所以今天好好总结一下. 微信公众平台技术 ...

  5. springboot微信公众号发送模板消息

    springboot微信公众号发送模板消息 1.准备工作 申请你所需要模板 配置ip白名单(你所需要部署的服务器ip) 2.编写模板消息的请求参数封装类 import java.util.HashMa ...

  6. 微信公众号 发送模板消息和获取关注公众号人数

    微信公众号发送模板消息 1.创建模板,拿到模板ID 2.创建发送消息工具类 import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JS ...

  7. php 微信模板消息url,【求助】php 微信公众号 发送模板消息改变不了颜色

    php 微信公众号 发送模板消息改变不了颜色 不知道为什么 1.模板消息内容: 2.发送的模板消息效果: 序列化的模板消息内容如下: 大家可以测试下,touser需要另外添加下 a:4:{s:11:& ...

  8. php之微信公众号发送模板消息

    讲一下开发项目中微信公众号发送模板消息的实现过程(我用的还是Thinkphp5.0).先看一下效果,如图: 就是类似于这样的,下面讲一下实现过程: 第一步:微信公众号申请模板消息权限: 立即申请: 申 ...

  9. 公众号 接收规则 消息_微信公众平台 发送模板消息(Java接口开发)

    前言:最近一直再弄微信扫码推送图文消息和模板消息发送,感觉学习到了不少东西.今天先总结一下微信公众平台模板消息的发送.因为这个自己弄了很久,开始很多地方不明白,所以今天好好总结一下. 微信公众平台技术 ...

  10. (Java)微信公众号发送模板消息

    模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等.不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息. 1.模板消息调用时主要 ...

最新文章

  1. Retinaface c++
  2. 请大家访问另一个我的博客!
  3. RawCode-本身就是实验性的8位类型
  4. 在 Centos7 用Jexus服务器 运行.Net Core 只需几步
  5. [剑指offer]面试题第[6]题[JAVA][旋转数组的最小数字][二分法]
  6. POJ1077 Eight —— 反向BFS
  7. 计蒜客挑战难题:元素移除
  8. 第5章 广义与一般线性模型
  9. 如何检查Django版本
  10. spring5.0学习笔记2
  11. 每周收获(11-13)
  12. 垂直跑马灯水平跑马灯
  13. linux系统富士通打印机驱动,PRIMERGY:驱动下载 - 富士通中国
  14. opencv小案例 --- 证件照背景替换
  15. 【Docker】03 Docker的常用命令
  16. 【uniapp】实现H5微信分享
  17. git 提交代码防止尾行序列LF转为CRLF
  18. 系统分析师---论软件的系统测试及应用
  19. 微软打补丁出现“此更新不适用于您的计算机”
  20. 安卓手机小说阅读器_书城小说阅读器app下载_书城小说阅读器手机版下载

热门文章

  1. 小甲鱼老师目前所有视频教程下载地址(mark下来慢慢看系列)
  2. 揭密如何写ASP木马后门
  3. 《C专家编程》之 内存泄漏
  4. 线性规划专题——Lingo的使用
  5. vc2008中如何调试dll
  6. html 图片的缩略图,纯CSS制作缩略图片
  7. 活动 | 腾讯×Nature Research:42问AI与机器人的未来
  8. 计算机知识脑筋急转弯,10道智力题图片及答案大全|2018年朋友圈最烧脑的10道智力题 附答案_最火软件站...
  9. 知名国产论坛,凉了!!!!
  10. 【阿里云】SCDN介绍及配置