likes
comments
collection
share

eggjs实现微信发送订阅功能

作者站长头像
站长
· 阅读数 11

需求

有这么一个需求,一群小伙伴要去一个地方集合,但是人数很多,无法统计;那么我们就需要做一个签到功能(小程序);当散会以后,我们又可以发送通知给签到者你签到成功啦!现在可以离开了。

要实现这种功能就需要用到小程序的订阅功能!

订阅功能又分为一次订阅和长期订阅功能,如果是一次订阅的话需要每次都授权,否则通知不到用户;但是大部分功能都只能一次订阅;大家可以详情看看文档 微信订阅相关文档

设置订阅

在微信公众平台上开通订阅功能

根据自己的需求进行配置即可!

如下图:

eggjs实现微信发送订阅功能

订阅授权

在tmplIds中填写你配置的订阅模板id;需要订阅的消息模板的id的集合,一次调用最多可订阅3条消息;这样授权以后就可以发送订阅消息了

wx.requestSubscribeMessage({
      tmplIds: ['*********************'],
       success (res) {
         console.log(res);
       },
       fail(err){
        console.log(err);
       }
     })

小程序获取code

前台获取code;主要用于获取openid时使用;有效时间只能60秒左右(我记得好像是)

wx.login({
      success: res => {
        console.log(res);
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
})

获取openid

这儿需要传递过来的code(前台获取的code)然后通过小程序的开放接口以及appid和appSecret获得openid;小程序登录技术文档

const Controller = require('egg').Controller;

const wxConfig = {
  appid: '****************',
  appSecret: '******************'
}

class WxMinniController extends Controller {
  // 通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程
  async openid() {
    const { ctx } = this;
    const { code } = ctx.request.body;
    const urlStr = 'https://api.weixin.qq.com/sns/jscode2session'
    const data = {
      appid: wxConfig.appid,           // 小程序 appId
      secret: wxConfig.appSecret,      // 小程序 appSecret
      js_code: code,         // 登录时获取的 code
      grant_type: 'authorization_code' // 授权类型,此处只需填写
    }
    const result = await ctx.curl(urlStr, {
      data: data,
      dataType: 'json',
    });
    if(result.data.errmsg){
      ctx.body = {
        code: 201,
        msg: '操作失败',
        errcode: result.data.errcode,
        errmsg: result.data.errmsg
      };
    }else{
      ctx.body = {
        code: 200,
        msg: '操作成功',
        openid: result.data.openid,
        session_key: result.data.session_key
      };
    }
  }
}
module.exports = WxMinniController;

成功返回:

{
    "code": 200,
    "msg": "操作成功",
    "openid": "***********",
    "session_key": "****=="
}

获取access_token

获取access_token的目的主要是为了发送订阅消息的时候需要携带这个值才能成功发送订阅消息通知用户;token有效期为7200s

获取接口调用凭据文档

async accessToken () {
    const { ctx } = this;
    const urlStr = 'https://api.weixin.qq.com/cgi-bin/token'
    const data = {
      appid: wxConfig.appid,           // 小程序 appId
      secret: wxConfig.appSecret,      // 小程序 appSecret
      grant_type: 'client_credential',         // 登录时获取的 code
    }
    const { data:result } = await ctx.curl(urlStr, {
        method:"GET",
        data,
        dataType: 'json',
    });
    ctx.body = {
        code: 200,
        msg: '操作成功',
        data:result,
      };
  }

发送订阅消息

  • touser 用户openid
  • template_id 订阅模板
  • miniprogram_state 跳转小程序类型 developer为开发版;trial为体验版;formal为正式版;默认为正式版
  • lang 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
  • data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object
  • page 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转

更多的信息可以根据文档配置相关的信息 发送订阅消息文档

参数说明: row格式,data中的time24需要和微信公众号里面配置的订阅消息字段保持一致

{
  "touser": "*************************",
  "template_id": "*********************************",
  "miniprogram_state":"developer",
  "lang":"zh_CN",
  "data": {
      "time24": {
          "value": "2019年11月11日 20:20"
      },
      "time27": {
          "value": "2019年11月11日 20:20"
      },
      "thing21": {
          "value": "小程序由公众号:广东专插本最前线开发"
      },
      "thing23": {
          "value": "小程序由公众号:广东专插本最前线开发"
      }
  }
}

发送订阅消息相关代码:

  async subscription () {
    const { ctx } = this;
    const { access_token, touser, template_id } = ctx.request.body;
    const urlStr = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' + access_token;
    const data = {
        "touser": touser, // 接收者(用户)的 openid
        "template_id": template_id, // 所需下发的订阅模板id
        "miniprogram_state":"developer", // 跳转小程序类型
        "lang":"zh_CN", // 语言类型
        "data": {
            "time24": {
                "value": "2019年11月11日 20:20"
            },
            "time27": {
                "value": "2019年11月11日 20:20"
            },
            "thing21": {
                "value": "小程序通知签到提醒"
            },
            "thing23": {
                "value": "小程序通知签到提醒"
            }
        }
      }
    const { data:result } = await ctx.curl(urlStr, {
        method:"POST",
        data,
        dataType: 'json',
        headers:{
            "Content-type":"application/json"
        }
    });

    ctx.body = {
        code: 200,
        msg: '操作成功',
        data:result,
      };
  }

当你做到这儿的时候就说明订阅消息基本上完成了;我做的这个可能比较粗糙,大家可以根据文档做一些优化功能!

希望小伙伴们有所收获哦!拜拜啦!下次再见

往期文章