微信公众号推送模板消息(四):Java调用实现模板消息推送

简单介绍模板消息

什么是模板消息?模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如涉及金钱交易-刷卡支付,商品购买等,不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。模版消息可以不通过用户主动交互向用户推送消息,但尽量少推送消息,避免被举报,以下微信模板消息的使用规则:
微信模板消息使用规则
微信官方文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html



第一步:有一个公众号或申请一个公众号测试号 然后 添加一个消息模板

申请一个公众号测试号,详情请看我在前面写的博客:微信公众号推送模板消息(一):申请微信公众帐号测试号


第二步:通过公众号或测试号的 appid 和 secret ,获取 access_token 信息

获取 access_token 信息,详细请看我在前面写的博客:微信公众号推送模板消息(二):Access_token的获取


第三步:通过获取到的 access_token 获取关注者 openid (以便于给多用户推送消息)

获取 openid 关注者列表,详细请看我在前面写的博客:微信公众号推送模板消息(三):获取关注者列表 openid


第四步:配置模板类 及 定义相关参数 来准备消息推送

微信模板消息推送采用的是 JSON 格式,我们可以用两种方式对他进行配置:
第一种就是下面的这个配置模板类,然后一步一步的来搞定 微信消息参数,模版消息内容,模版消息(公用的类,注意一下模版名称规范)。
第二种就是手动拼接成 JSON 串,进行推送。


配置模板类

微信消息参数模板 WxTemplate

import java.util.Map;

/**
 * 微信消息参数
 */
public class WxTemplate {
	
	//进行推送所需参数
    private String touser;//用户openid(接收人)
    private String template_id;//消息模版id
    private String url = "https://baidu.com";//跳转到某链接或某页面
    private Map<String, TemplateData> data;//要推送的模板内容

    public String getTouser() {
        return touser;
    }

    public void setTouser(String touser) {
        this.touser = touser;
    }

    public String getTemplate_id() {
        return template_id;
    }

    public void setTemplate_id(String template_id) {
        this.template_id = template_id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Map<String, TemplateData> getData() {
        return data;
    }

    public void setData(Map<String, TemplateData> data) {
        this.data = data;
    }

}

微信模版消息内容 TemplateData

/**
 * 微信模版消息内容
 */
public class TemplateData {

    private String value;//消息内容
    private String color;//消息颜色

    //构造方法(空参)
    public TemplateData() {
    }

    //构造方法(有参)
    public TemplateData(String value,String color) {
        this.value = value;
        this.color = 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;
    }

}

微信消息模版 MeTemplate (根据消息模版的字段来定义此类)

/**
 * 微信消息模板
 */
public class MeTemplate {

    // 根据 新增的消息测试模板来定义
    private String title;// 标题
    private String content;// 内容
    private String time;// 时间
    private String remark;// 备注

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

}


第五步: 配置好所需要的参数后们就可以进行 配置推送模板消息

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 发送模板消息
 */
@RestController
public class PushWxMessage {

    /*
     * 微信测试账号 批量 循环推送 模板消息
     */
    @PostMapping("/weChatPush")
    public String weChatPush() {
        try {
            List<String> ls = getOpenId(getAccessToken());
            for (int i=0;i<ls.size();i++){
                System.out.println(ls.get(i));
                push(ls.get(i),"","");
            }
            return ("推送成功");
        }catch (Exception e){
            e.printStackTrace();
            return ("推送失败");
        }
    }

    /*
     * 微信测试账号 发送模板消息
     */
    @PostMapping("/push")
    public Object push(String openid, String template_id, String jumpurl) {

        RestTemplate restTemplate = new RestTemplate();
        //为了简单测试 这里每次都获取最新的access_token(在实际开发中,应该在 access_token 快过期时再重新获取)
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken();
        //推送的模版 (目前为了简单测试 很多参数都写死,固定了,但也可以根据需要动态传入参数)
        WxTemplate wxTe = new WxTemplate();
        wxTe.setTouser(openid);//用户的openid(接收人,这里应该传进来的)
        wxTe.setTemplate_id("你拿到的 模板id");//订阅消息模板id
        wxTe.setUrl("www.baidu.com");//跳转链接

        //日期格式定义 转换
        DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String dateString = dateformat.format(new Date());

        Map<String, TemplateData> m = new HashMap<>();
        m.put("title", new TemplateData("测试推送:收费通知!","#F7A36F"));
        m.put("content", new TemplateData("即将要欠费,你要交钱了!","#79CCE9"));
        m.put("time", new TemplateData(dateString,"#79CCE9"));
        m.put("remark", new TemplateData("多交点!少费事!","#FF0000"));
        wxTe.setData(m);

        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxTe, String.class);
        return JSON.parseObject(responseEntity.getBody());
    }
	
	/*
	 * 获取 access_token(接口调用凭据)
	 */
    @GetMapping("/getAccessToken")
    public String getAccessToken() {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> params = new HashMap<>();
        params.put("APPID", "你拿到的 appid");  //
        params.put("APPSECRET", "你拿到的 appsecret");  //
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}", String.class, params);
        String body = responseEntity.getBody();
        JSONObject object = JSON.parseObject(body);
        String Access_Token = object.getString("access_token");
        String expires_in = object.getString("expires_in");// 过期时长(两小时)
        //System.out.println("有效时长expires_in:" + expires_in);
        return Access_Token;
    }

	 /*
	  * 获取 openid(关注者列表)
	  */
    @GetMapping("/getOpenId")
    public List<String> getOpenId(String access_token) {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> params = new HashMap<>();
        params.put("access_token", access_token);  //
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(
                "https://api.weixin.qq.com/cgi-bin/user/get?access_token={access_token}", String.class, params
        );

        String body = responseEntity.getBody();
        // 解析成JSONObject 并获取(叫data的JSON对象)JSONObject
        JSONObject object = JSON.parseObject(body).getJSONObject("data");
        // 获取 JSONObject 中的 JSONArray
        JSONArray array = object.getJSONArray("openid");

        System.out.println("array"+array);
        // JSONArray 转成 List<Strig> 集合(注意 alibaba 的fastjson 1.2.23以下的版本 和 1.2.3 的版本不包含 toJavaList()方法 )
        List<String> lists = array.toJavaList(String.class);
        System.out.println(lists.get(0));

        return lists;
    }

}


了解一下,拼接JSON串

像以下的格式,简单理解一下,其实就是 一个大的对象里 套了一个叫 data 的对象,然后又套了(title,content,time,remark)几个同级的对象 ; 一共三个层级 组成json串。

{
	"touser":"接收人 OPENID",
	"template_id":"模板ID",
	"url":"www.baidu.com",
	"data":{
		"title":{
			"value":"标题",
			"color":"#282A36"
		},
		"content":{
			"value":"内容",
			"color":"#02ABE4"
		},
		"time":{
			"value":"时间",
			"color":"#02ABE4"
		},
		"remark":{
			"value":"备注",
			"color":"#02ABE4"
		}
	}
}

在这里就不用代码进行拼接了,直接用 postman 传json格式(其实和下面注释掉的 一片代码差不多,三层 逐层追加)

/*
     * 发送模板消息
     */
    @PostMapping("/jsonpush")
    public Object jsonpush(@RequestBody Map<String, Object> map) {

        System.out.println(map);
        RestTemplate restTemplate = new RestTemplate();
        //为了简单测试 这里每次都获取最新的access_token(在实际开发中,应该在 access_token 快过期时再重新获取)
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken();

//        //日期格式定义 转换
//        DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//        String dateString = dateformat.format(new Date());//当前时间
//
//        //也可以定义为 JSONObject 类型来进行追加
//        Map<String, Object> data = (Map<String, Object>) map.get("data");// 获取data对象 转为Map集合
//        Map<String, String> time = new HashMap<String, String>();// 定义一个叫time的Map集合
//        //逐层追加
//        time.put("value",dateString);
//        time.put("color","#02ABE4");
//        data.put("time",time);
//        map.put("data",data);

        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, map, String.class);
        return JSON.parseObject(responseEntity.getBody());
    }

总结:

 这一套流程走下来,比较简单的模板消息推送就能完成了。

 在上面为了简单 我们把推送的相关方法和接口都写在一块了,这样不能说是有错但有点不够规范 严谨。我们其实可以把相关方法拿出来进行封装一下,接口再调用封装的方法;面向对象的三大原则相信就不用多说了。

 在上面有一个微信消息模版 MeTemplate 类 暂时没用到,在传参赋值或获取参数值时 可以调用其中相关get set 方法。

 还有一个问题 在上面获取 access_token 会有一个 expires_in (过期时间)在这里我们可以用 Redis 来进行定期获取。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值