SpringBoot 开发之集成微信公众号之发送模板消息

微信公众平台: https://mp.weixin.qq.com

准备参数:

每个公众号都有自己的 开发者ID(AppID) 和 开发者密码(AppSecret) 。可以前往微信公众平台,在开发基本配置中查看。
SpringBoot 开发之集成微信公众号之发送模板消息_第1张图片

Maven 导入
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

一.直接在微信公众平台创建消息模板

1.登录微信公众平台,找到模板消息,从模板库中找到自己想要的消息模板,进入详情添加即可。
SpringBoot 开发之集成微信公众号之发送模板消息_第2张图片
SpringBoot 开发之集成微信公众号之发送模板消息_第3张图片

SpringBoot 开发之集成微信公众号之发送模板消息_第4张图片

  1. 保存后在我的模板中就会创建一个消息模板,保存好消息模板的ID,后面发送消息时需要使用。
    SpringBoot 开发之集成微信公众号之发送模板消息_第5张图片

二、获取 AccessToken

access_token 是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。
access_token 的存储至少要保留512个字符空间。
access_token 的有效期目前为2个小时,重复获取将导致上次获取的access_token失效。
access_token 每日获取上限 100000 次。

建议公众号开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务

https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明
参数 是否必须 是否必须
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret
正常情况下,微信会返回下述JSON数据包给公众号:

{“access_token”:“ACCESS_TOKEN”,“expires_in”:7200}

参数说明
参数 说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{“errcode”:40013,“errmsg”:“invalid appid”}
错误时错误码等信息详情可查看官方文档

三、发送模板消息

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

POST数据示例如下:

   {
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepath":"index?foo=bar"
           },          
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }
参数 是否必填 说明
touser 接收者openid
template_id 模板ID
url 模板跳转链接(海外帐号没有跳转能力)
miniprogram 跳小程序所需数据,不需跳小程序可不用传该数据
appid 所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
pagepath 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
data 模板数据
color 模板内容字体颜色,不填默认为黑色

其他详细内容可查看官方文档

四、效果图

SpringBoot 开发之集成微信公众号之发送模板消息_第6张图片

五、附:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yo.project.module.common.utils.character.StringUtils;
import com.yo.project.web.controller.parking.TemplateData;
import com.yo.project.web.controller.parking.WxTemplate;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: yoult
 * @Description: TODO
 * @LoginName: ZDGG
 * @Date: 2020-12-02 14:27 星期三
 */
public class WxTemplateMessageServlet {

    // 开发者密码(AppSecret)
    private static String AppSecret;
    // 开发者ID(AppID)
    private static String AppId;
    // 消息模板ID
    private static String TemplateId;

    // 网页授权接口
    private final static String GetAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
    // 发送模板消息接口
    private final static String SendTempMessage = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";

    /**
     * 推送模板消息
     * @param parkingName 停车场名称
     * @param plateNumber 车牌号
     * @param enterTime 入场时间
     * @param openId    推送用户OpenId (注意,是OpenId)
     * @param templateUrl 跳转Url
     */
    public void sendEnterTemplateMessage(String parkingName, String plateNumber, String enterTime, String openId, String templateUrl) {
        Map<String, Object> result = null;
        try {
            Map<String, TemplateData> data = new HashMap<>();
            TemplateData first = new TemplateData();
            TemplateData keyword1 = new TemplateData();
            TemplateData keyword2 = new TemplateData();
            TemplateData keyword3 = new TemplateData();
            TemplateData remark = new TemplateData();
            first.setColor("#328392");
            first.setValue("欢迎进入" + parkingName);
            keyword1.setColor("#328392");
            keyword1.setValue(plateNumber);
            keyword2.setColor("#328392");
            keyword2.setValue(parkingName);
            keyword3.setColor("#328392");
            keyword3.setValue(enterTime);
            remark.setColor("#328392");
            // 有模板模板跳转链接,则推送消息可点击
            remark.setValue("本车场开通车牌识别,临停车辆请在临出场之前进行缴费,方便您的出行。" + (StringUtils.isBlank(templateUrl) ? "" : "点击可预支付缴费出场。"));
            data.put("first", first);
            data.put("keyword1", keyword1);
            data.put("keyword2", keyword2);
            data.put("keyword3", keyword3);
            data.put("remark", remark);
            WxTemplate template = new WxTemplate();
            // 推送用户OpenId
            template.setTouser(openId);
            // 消息模板ID
            template.setTemplate_id(TemplateId);
            // 有模板模板跳转链接,则推送消息可点击
            if (!StringUtils.isBlank(templateUrl)) template.setUrl(templateUrl);
            template.setData(data);
            System.out.println("模板消息推送:" + template.toString());
            // 获取 AccessToken
            String accessToken = null;
            try {
                accessToken = getAccessToken();
            } catch (Exception e) {
                e.printStackTrace();
            }
            template.setAppid(AppId);
            String message = sendPostMessage(SendTempMessage.replace("ACCESS_TOKEN", accessToken), template);
            result.put("code", 1);
            result.put("message", message);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println((String.valueOf(result)));
    }
    /**
     * Post 请求发送数据
     * @param url
     * @param dataMap
     * @return
     */
    private static String sendPostMessage(String url, Object dataMap) {
        String data = new String();
        // 创建HttpClient实例
        HttpClient client = HttpClientBuilder.create().build();
        // 根据URL创建HttpPost实例
        HttpPost post = new HttpPost(url);
        try {
            // 构造post参数
            StringEntity s = new StringEntity(JSON.toJSONString(dataMap), "UTF-8");
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");//发送json数据需要设置contentType
            post.setEntity(s);
            // 发送请求,得到响应体
            HttpResponse response = client.execute(post);
            // 判断是否正常返回
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 解析数据
                HttpEntity resEntity = response.getEntity();
                data = EntityUtils.toString(resEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return data;
    }
    /**
     * 获取AccessToken
     * @return
     * @throws Exception
     */
    private static String getAccessToken() throws Exception {
        String requestUrl = GetAccessTokenUrl.replace("APPID", AppId).replace("SECRET", AppSecret);
        HttpClient client = HttpClientBuilder.create().build();
        String accessToken = null;
        String errcode = null;
        String errmsg = null;
        try {
            HttpGet httpget = new HttpGet(requestUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject OpenidJSONO = JSONObject.parseObject(response);
            errcode = String.valueOf(OpenidJSONO.get("errcode"));
            errmsg = String.valueOf(OpenidJSONO.get("errmsg"));
            accessToken = String.valueOf(OpenidJSONO.get("access_token"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        if (!StringUtils.isBlank(errcode) && !errcode.equals("null"))
            throw new Exception(errmsg);
        return accessToken;
    }
}
import lombok.Data;
/**
 * 模板消息
 */
@Data
public class TemplateData {

    private String value;//模板显示值
    private String color;//模板显示颜色

    @Override
    public String toString() {
        return "TemplateData{" + "value='" + value + '\'' + ", color='" + color + '\'' + '}';
    }
}


import lombok.Data;
import java.util.Map;

/**
 * 模板基类
 *
 * @author CLiang
 */
@Data
public class WxTemplate {
    private String touser;//目标openId
    private String template_id;//模板ID
    private String url;//用户点击模板信息的跳转页面
    private Map<String, Object> miniprogram;//跳小程序所需数据,不需跳小程序可不用传该数据
    private String appid;//所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
    private String pagepath;//所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
    private String color;//模板内容字体颜色,不填默认为黑色
    private Map<String, TemplateData> data;//模板里的数据

    @Override
    public String toString() {
        return "WxTemplate{" + "touser='" + touser + '\'' + ", template_id='" + template_id + '\'' + ", url='" + url + '\'' + ", miniprogram=" + miniprogram + ", appid='" + appid + '\'' + ", pagepath='" + pagepath + '\'' + ", color='" + color + '\'' + ", data=" + data + '}';
    }
}

你可能感兴趣的:(笔记,java)