微信小程序订阅功能实现(不使用微信云开发,Java版)

前言:

昨天要实现一个微信小程序发送订阅消息的功能,但是网上找了下,似乎没有写的很简单明了的,然后就自己稍微研究了一下,然后给各位兄弟们分享一下,希望能对各位有所帮助。

话不多说,先看效果图。

效果图:

准备:

首先你需要一个微信公众平台账号,然后在里面注册一个小程序。

因为需要用到

然后去基础功能下面的订阅消息下面去申请模版。

都准备好后,就可以开始了,直接上代码。

前端代码

         //需要绑定到一个按钮上面,这个必须通过点击按钮触发
            wx.requestSubscribeMessage({
              tmplIds: [
                '输入你的模版ID', '模版ID'
              ]
            }).then((data) => {
              // 用户同意订阅
              console.log('用户同意订阅', data);

            }).catch((err) => {
              // 用户拒绝订阅
              console.error('用户拒绝订阅', err);
            });

后端代码

我这里使用的是Maven,导入的就不写了。

        <!-- 这里我用的是这个okhttp -->       
         <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.8.1</version>
          </dependency>
//调用接口首先要获取的就是调用接口凭证

 /**
     * 获取接口调用凭证
     * @param client okHttp客户端
     * @return 接口调用凭证
     */
    public String getAccessToken(OkHttpClient client){
        // 执行 HTTP 请求 其中appId 和secret就是上面准备阶段获取到的小程序ID和密钥
        String url = "https://api.weixin.qq.com/cgi-bin/token?    
        grant_type=client_credential&appid="+ appId +"&secret="+ secret;
        Request request = new Request.Builder()
                .url(url)
                .build();
        try {
            Response response = client.newCall(request).execute();
            String string = response.body().string();
            JSONObject jsonObject = JSON.parseObject(string);
            String access_token = jsonObject.get("access_token").toString();
            //然后将其存放入redis,可以方便下次调用
           redisTemplate.opsForValue().set("access_token",access_token,jsonObject.getLong("expires_in"), TimeUnit.SECONDS);
            return access_token;
        } catch (IOException e) {
            log.error("获取微信接口调用凭证的时候出现错误:{}",e);
//            throw new RuntimeException(e);
        }
        return null;
    }
    //然后就可以封装推送方法了
 /**
     * 订阅消息推送
     * @param touser 接收者(用户)的 openid
     * @param templateId 所需下发的订阅模板id
     * @param page 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
     * @param miniprogramState 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
     * @param lang 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
     * @param data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object
     */
    @Override
    public void send(String touser, String templateId, String page, String miniprogramState, String lang, Map<String,Object> data){
        //判断接口凭证是否存在
        Object o = redisTemplate.opsForValue().get("access_token");
        OkHttpClient client = new OkHttpClient();
        String accessToken;
        if(o == null){
            //获取接口调用凭证
            accessToken = getAccessToken(client);
            if(accessToken == null){
                //接口出错
                log.error("获取微信接口调用凭证的时候出现错误");
                return;
            }

        }else{
            //存在
            accessToken = o.toString();
        }
        //发送消息
        Map<String,Object> body = new HashMap<>();
        body.put("template_id",templateId);
        body.put("touser",touser);
        body.put("page",page);
        body.put("miniprogram_state",miniprogramState);
        body.put("lang",lang);
        body.put("data",data);
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+accessToken;
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MediaType.parse("application/json;charset=utf-8"),JSON.toJSONString(body))).build();
        try {
            Response response = client.newCall(request).execute();
            String string = response.body().string();
            JSONObject jsonObject = JSON.parseObject(string);
            Integer code = jsonObject.getInteger("errcode");
            String result = jsonObject.getString("errmsg");
            switch (code){
                case 0:
                    log.info("订阅消息推送成功");
                    break;
                default:
                    log.error("订阅消息推送时出现错误:{},推送给的用户是{},推送的模版ID是:{}",result,touser,templateId);
                    break;
            }
        } catch (IOException e) {
            log.error("订阅消息推送时出现错误:",e);
        }
    }
    //消息模版
    public HashMap<String,Object> formatParam(String value){
        HashMap<String, Object> map = new HashMap<>();
        map.put("value",value);
        return map;
    }

将其封装完成后,调用的时候,只需要构建模版的消息内容即可,比如

        HashMap<String, Object> finisherData = new HashMap<>();
        finisherData.put("character_string1",formatParam(orderId));
        finisherData.put("time14",formatParam(LocalTime.getNowTimeToString(orders.getStartTime())));
        finisherData.put("amount2",formatParam(orders.getCommission().toString()));
        finisherData.put("thing15",formatParam("接单成功"));
        send("推送的用户appid","模版ID","点击后跳转的路径","跳转的版本,默认是正式版","点进去后的语言",finisherData);

消息类型:

报错说明

至于怎么看key,就去公众平台模版那里,点击详情后,就可以查看。

最后,这个请求里面的body,格式应该是这样的
 

{
    "template_id":"模版ID",
    "page":"点击后跳转路径",
    "touser":"需要推送用户的id",
   "data": {
    "phrase1": {
      "value": "审核通过"
    },
    "time2": {
      "value": "2024-09-18 08:45:07"
    },
    "thing3": {
      "value": "提现审核通知"
    }
  }
}

稍微需要注意一点的就是,类型要仔细一点,大部分都是以内,别写超了。

最后说一下,我这个用的是一次性订阅,简单来说就是用户授权一次,然后就可以推送一条消息,还有一种是长期订阅,就是用户授权后,小程序可以随时推送消息(这种好像有点资质要求),一般来说这个一次性就够用了。

最后祝各位,早上好,中午好,晚上好,早点休息,在熬夜头发要掉光了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值