Springboot实现微信公众号模板消息发送

简介: 最近看了一个地推的公众号,每天都会给你推送好几条地推需要的模板消息,好一段时间没有做公众号开发了,最近刚申请了个服务号,刚好可以拿来开发。模板消息需要服务号才可以,申请服务号的话需要企业营业执照,个人的话是没有办法申请的。下面来分享一下我的开发过程。

最近看了一个地推的公众号,每天都会给你推送好几条地推需要的模板消息,好一段时间没有做公众号开发了,最近刚申请了个服务号,刚好可以拿来开发。模板消息需要服务号才可以,申请服务号的话需要企业营业执照,个人的话是没有办法申请的。下面来分享一下我的开发过程。

dc57269f849048d52afc76c8d2f3a03f_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQOeMquWkp-iCoA==,size_20,color_FFFFFF,t_70,g_se,x_16.png

开发步骤

1.微信公众号服务号
2.准备好 APPID 跟AppSecret
3.开通模板消息,申请一个模板,获取模板ID
4.获取ACCESS_TOKEN
5.获取关注公众号的用户列表
6.选择需要发送的用户,并推送消息

一、资料申请

1.1、获取 APPID 跟AppSecret

1.2、获取 模板消息ID

找不到的话,就在新功能上面去添加;

二、开发

2.1、编写yml配置文件

#公众号配置
wechat:
    appid:  APPID
    appkey: APP密钥
    messageId: 模板ID

2.2、编写配置类

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
public class WechatConfig {
    @Value("${wechat.appid}")
    private String appid;
    @Value("${wechat.appkey}")
    private String appkey;
}

2.3、获取ACCESS_TOKEN

这里有点类似登录吧,就是用咱们的APPID跟APP密钥送到官方接口那边去验证身份,如果没问题人家就给你返回一个token,方便后面调用接口可以传,让官方接口知道是谁发过来的。token是临时的,有效期是2个小时.

2.3.1、导入工具类 (hutool)maven依赖

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>${hutool.version}</version>
    </dependency>

2.3.2、导入工具类 (hutool)maven依赖

@Component
public class ConfigurationService {
    private String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";
    @Autowired
    private WechatConfig wechatConfig;
    public JSONObject getAccessToken() {
        String requestUrl = accessTokenUrl + "appid=" + wechatConfig.getAppid() + "&secret=" + wechatConfig.getAppkey();
        String resp = HttpUtil.get(requestUrl);
        JSONObject result = JSONUtil.parseObj(resp);
        System.out.println("获取access_token:" + resp);
        return result;
    }
}

2.4、获取关注你公众号的用户列表

因为我们在发送模板消息的时候,需要填推送的对象(openid),

所以我们需要先查询出用户,再一个个推送。

    /**
     * 获取用户列表
     * @param accessToken
     * @return
     */
    public JSONObject getUserList(String accessToken) {
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken + "&next_openid=";
        String resp = HttpUtil.get(requestUrl);
        JSONObject result = JSONUtil.parseObj(resp);
        System.out.println("用户列表:" + resp);
        return result;
    }

next_openid=这个可以为空,代表从头查起。也可以放上某个用户的openid,发送请求的到时候,用来告诉官方接口从哪个用户开始查起。因为查询一次,最多只能查一万条数据,假设你有几万个用户,那么你就需要查询好几次了,就需要用到这个参数。

2.5、发送模板消息

2.5.1、新建消息配置类

因为我是将把配置写到数据库里面了,方便后面添加发送任务。大家不一定要做这部操作哈。!

@Data
@TableName("template_msg")
public class TemplateMsgEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId
    private Integer id;
    /**
     * 标题
     */
    private String tTitle;
    /**
     * 第一行
     */
    private String tKeyword1;
    /**
     * 第二行
     */
    private String tKeyword2;
    /**
     * 第三行
     */
    private String tKeyword3;
    /**
     * 第四行
     */
    private String tKeyword4;
    /**
     * 备注
     */
    private String tRemark;
    /**
     * 跳转连接
     */
    private String tUrl;
    /**
     * 模板编码
     */
    private String tCode;
    /**
     * 状态
     */
    private int tStatus;
}

模板发送

  public JSONObject sendMsg(TemplateMsgEntity messageVo, String token, String openId) {
        String requestUrl = " https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="  + token;
        Map<String,Object> content=new HashMap<>();
        JSONObject data = JSONUtil.createObj();
        data.put("first",new JSONObject().put("value",messageVo.getTTitle()));
        data.put("keyword1",new JSONObject().put("value",messageVo.getTKeyword1()));
        data.put("keyword2",new JSONObject().put("value",messageVo.getTKeyword2()));
        data.put("keyword3",new JSONObject().put("value",messageVo.getTKeyword3()));
        data.put("keyword4",new JSONObject().put("value",messageVo.getTKeyword4()));
        data.put("remark",new JSONObject().put("value",messageVo.getTRemark()));
        content.put("touser",openId);
        content.put("url",messageVo.getTUrl());
        content.put("template_id","jbgHt8W8RNpRN2KZwvAMty40iiZU2sa9dqnFXOsCvqw");
        content.put("data",data);
        String resp = HttpUtil.post(requestUrl,JSONUtil.parseFromMap(content).toString());
        System.out.println(content.toString());
        System.out.println(JSONUtil.parseFromMap(content));
        JSONObject result = JSONUtil.parseObj(resp);
        System.out.println("发送消息:" + resp);
        return result;
    }

接口字段要对应着来。

官方文档:https://mp.weixin.qq.com/advanced/tmplmsg?action=faq&token=1066457355&lang=zh_CN

fb98eb988b46e0e4c8889bb043565740_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQOeMquWkp-iCoA==,size_20,color_FFFFFF,t_70,g_se,x_16.png

有个需要注意的地方就是,模板封装好之后,推送到官方提供的接口时,数据类型是String类型哦,别整个对象就过来,那样解析不了的。

三、测试

  /**
     * 发送模板消息
     * @return
     */
    @GetMapping( "/sedMsg")
    public JSONObject sedMsg(){
      JSONObject accessToken = configurationService.getAccessToken();
      String token=accessToken.getStr("access_token");
       //获取用户列表
        JSONObject userList = configurationService.getUserList(token);
        JSONArray openids = userList.getJSONObject("data").getJSONArray("openid");
        System.out.println(openids.toArray());
        TemplateMsgEntity messageVo=new TemplateMsgEntity();
        messageVo.setTTitle("标题");
        messageVo.setTKeyword1("测试1");
        messageVo.setTKeyword2("测试2");
        messageVo.setTKeyword3("测试3");
        messageVo.setTKeyword4("测试4");
        messageVo.setTRemark("remark");
        for (Object openid:openids) {
            JSONObject resp = configurationService.sendMsg(messageVo,token,openid.toString());
        }
        return null;
    }

612a03ebb068bdc4738d529586711658_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQOeMquWkp-iCoA==,size_20,color_FFFFFF,t_70,g_se,x_16.png

四、优化

由于ACCESS_TOKEN只有两个小时就过期,所以我们应该专门写一个服务,或者一个定时间任务,隔一段时间就去读取数据库中记录的access_token,并且将写入access_token的时间跟现在的时间进行比较,大概超过117分钟时,就重新刷新写到数据中去。思路是这样的,大家可以自己写哈,方式很多。

@Configuration
@EnableScheduling
public class MessageTask {
    @Autowired
    SysConfigService sysConfigService;
    @Autowired
    ConfigurationService configurationService;
    @Autowired
    TemplateMsgService templateMsgService;
    /**
     * 维护Token
     */
    @Scheduled(fixedRate = 120000)
    public void tokenTask(){
        System.out.println("定时任务开启:");
        //获取token
        String token = sysConfigService.getValue("ACCESS_TOKEN");
        JSONObject json = JSONUtil.parseObj(token);
        String expires_date = json.getStr("expires_date");
        //token创建的时间
        DateTime parse = DateUtil.parse(expires_date);
        //跟现在的时间对比是否大于7000s 
        long between = DateUtil.between(parse, new DateTime(), DateUnit.MINUTE);
        System.out.println("时间比较:"+between);
        //快过期了,重新刷新token
        if (between>115){ 
            JSONObject accessToken = configurationService.getAccessToken();
            if (accessToken.getStr("expires_in")!=null&&accessToken.getStr("expires_in").equals("7200")){
                accessToken.put("expires_date",DateUtil.now().toString());
                sysConfigService.updateValueByKey("ACCESS_TOKEN",accessToken.toString());
                System.out.println("token更新了:"+accessToken.toString());
            }
        }
    }
}

希望能帮助到大家



目录
相关文章
|
2月前
|
移动开发 安全 JavaScript
SpringBoot接入微信JSSDK,看这篇妥妥的
这篇教程详细介绍了如何在Spring Boot项目中接入微信JSSDK,实现H5页面的自定义分享和调用相册选取图片等功能。文章首先通过对比理想与现实的分享效果,引出了接入微信JSSDK的必要性。接着,作者提供了GitHub和Gitee上的项目源码链接,并逐步讲解了整个接入过程的关键步骤,包括配置文件、主要类和方法的实现细节,以及必要的微信公众号设置。此外,还特别强调了几个常见问题及其解决方案,如域名绑定、IP白名单设置和签名验证等。最后,通过实际测试验证了功能的正确性。适合初学者快速上手微信JSSDK接入。
46 8
SpringBoot接入微信JSSDK,看这篇妥妥的
|
15天前
|
小程序
java--微信小程序发送模板消息
java--微信小程序发送模板消息
62 0
|
2月前
|
小程序 JavaScript Java
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
|
2月前
|
小程序 安全 Java
|
2月前
|
小程序 Java API
springboot 微信小程序整合websocket,实现发送提醒消息
springboot 微信小程序整合websocket,实现发送提醒消息
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
72 7
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
81 7
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的“鼻护灵”微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的“鼻护灵”微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的“财来财往”微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的“财来财往”微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的传统戏曲推广微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的传统戏曲推广微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)