微信小程序-云开发实现接收公众号事件推送(不同主体)

一、前言

通常情况下,小程序如果需要进行留粉或者随时下发实时通知给用户,都会搭配一个服务号进行开发,同时,随着业务的增长以及功能的迭代,可能还需要对服务号进行一些开发,例如拉新(邀请用户关注)活动等。

选择云开发后,在同主体(即小程序与服务号同一主体)的情况下可以很方便的与服务号进行联合开发,不需要额外的代码编写,只需要进行配置即可接收服务号的事件推送(关注事件、公众号消息等)。

但是在不同主体的情况下,就不能使用环境共享来进行公众号的事件接收,因此本文实现的是在非同主体下的公众号事件接收。
当然,同主体也是可以使用本文中的方式去实现,但是没必要,建议直接使用云开发提供的能力即可。

二、实现流程

这里就不说服务号、小程序的注册、认证以及云开发环境开通的流程了。直接进入核心的部分。

2-1、创建一个云函数

首先,我们需要创建一个云函数,作为接收事件的处理函数,可以理解为一个服务端的接口。
命名随意,但是后面的步骤保持一致即可。
这里我的命名为:publicEventHttp
在这里插入图片描述

2-2、开启云函数http访问服务

第二步是对上面创建的云函数开启公网访问,开启后会得到一个网址,这个网址就会作为在公众号的服务器配置中的回调地址。

前往腾讯云官网登录,选择小程序公众号方式登录。
在这里插入图片描述

扫码登录即可(注意:这里必须要小程序管理员进行扫码登录)
在这里插入图片描述

登录成功后进入控制台,搜索云开发。
在这里插入图片描述

选择你的环境,点击进入云开发环境的控制台。
在这里插入图片描述

在这里插入图片描述
新建一个访问服务
在这里插入图片描述

点击确认后,等待服务新建完成即可,大概需要10分钟(生效)。
点击触发路径,不会出现以下页面信息就是生效了。
在这里插入图片描述

2-3、上传此云函数代码

按照下图的文件目录创建即可。
其中node_modules不需要管。上传云函数时选择云端安装依赖即可。
service也不需要,这是后续的实际业务逻辑,我的不一定符合你的需求。

在这里插入图片描述

utils.js

const crypto = require("crypto");
const xml2js = require("xml2js");

/**
 * 校验信息是否来自微信服务器
 * @param {*} token 设置的token
 * @param {*} nonce
 * @param {*} timestamp
 * @param {*} signature
 * @returns 验证成功返回 echostr 否则返回 false
 */
const handle_wx = (token, nonce, timestamp, signature) => {
  const list = [token, nonce, timestamp].sort().join("");
  const hash = crypto.createHash("sha1").update(list).digest("hex");
  if (signature === hash) return true;
  return false;
};

/**
 * 获取回调事件中的参数
 * @param {*} base64Data 回调事件的base64数据
 */
const getEventData = (base64Data) => {
  const buffer = Buffer.from(base64Data, "base64");
  const xmlData = buffer.toString("utf-8");
  const parser = new xml2js.Parser();
  return new Promise((resolve, reject) => {
    parser.parseString(xmlData, (err, res) => {
      if (err) reject(err);
      const eventDataObj = res.xml;
      let eventData = {};
      for (const key in eventDataObj) {
        eventData[key] = eventDataObj[key][0];
      }
      resolve(eventData);
    });
  });
};

module.exports = { handle_wx, getEventData };

config.js

const EncodingAESKey = "随机生成即可,见下图"
const Token = "你的token,后续配置在公众号中,3-32为随机字符。见下图"

module.exports = {
    EncodingAESKey,
    Token,
}

在这里插入图片描述

package.json

在你的package.json的dependencies中新增xml2js依赖

"xml2js": "^0.6.2"

在这里插入图片描述

index.js


const { Token } = require("./config");
const { handle_wx, getEventData } = require("./utils/utils");

exports.main = async (event) => {
  console.log("event :>> ", event);
  const { queryStringParameters, body } = event;
  // 校验信息是否来自微信服务器
  let isVerify = false;
  const { echostr, signature, timestamp, nonce } = queryStringParameters;
  // 服务器校验
  if (echostr && timestamp && nonce) {
    isVerify = handle_wx(Token, nonce, timestamp, signature);
    if (isVerify) {
      return {
        headers: {
          "content-type": "text/plain; charset=utf-8",
        },
        body: echostr,
      };
    }
  }

  // 事件校验
  if (signature && timestamp && nonce && !echostr)
    isVerify = handle_wx(Token, nonce, timestamp, signature);

  // 校验通过
  if (isVerify) {
    // 处理逻辑
    if (body) {
      const eventData = await getEventData(body);
       console.log("事件消息对象 :>> ", eventData);
      // 不得超5s
      await eventExe(eventData);
    }
    return "success";
  }
  // 校验不通过
  else return "";
};

/**
 * 处理不同的事件分发
 * @param {*} eventData 事件数据
 */
const eventExe = async (eventData) => {
  // 分发事件 事件类型自行前往官方文档查看,我这里只列出一些常用的
  // 这里放入你要执行的逻辑即可,例如关注下发欢迎语等
  const { MsgType, Event } = eventData;
  let resList = [];
  // 基础事件
  if (MsgType === "event") {
    switch (Event) {
      // 订阅
      case "subscribe":
        break;
      // 取消订阅
      case "unsubscribe":
        break;
      // 菜单栏点击
      case "CLICK":
        break;
      // 位置上报
      case "LOCATION":
        break;
    }
  }
  // 收到消息
  else {
    switch (MsgType) {
      // 收到文本消息
      case "text":
        break;
    }
  }
};

上传云函数

在这里插入图片描述

2-4、配置公众号

我这已经启用了,如果未启用的话,会有配置按钮,点击进去即可。
在这里插入图片描述

在这里插入图片描述

这里先不要点击提交!!!
这里先不要点击提交!!!
这里先不要点击提交!!!

复制Token和EncodingAESKey,放到云函数的config.js中,然后
记得更新云函数
记得更新云函数
记得更新云函数
在这里插入图片描述
等待云函数上传完成后,点击公众号中的提交按钮,此时微信服务器会进行token校验,如果没有出问题,会校验通过。

首次配置成功后,这里默认是未启用的,点击启用即可。
在这里插入图片描述

三、验证结果

上面全部都执行完没问题后,尝试到公众号中发送消息/关注/取关公众号,然后前往云函数日志中查看。看看是否会打印对应事件解析出来的数据对象。

发送消息:123

在这里插入图片描述

取关公众号事件
在这里插入图片描述

关注公众号事件
在这里插入图片描述

四、结语

最后来一下常规结语:
实际开发中的其他逻辑就不写了。需要同学们自己去考虑异常情况处理等问题啦。

有任何疑问可以在评论区留下。我每天都会进行回复,私聊不回。(为了刷积分)

以上均是本人开发过程中的一些经验总结与领悟,如果有什么不正确的地方,希望大佬们评论区斧正。

💥最后!!!不管这篇文章对你有没有用,既然都看到最后了。
👍赞一个!!!
🤩当然,顺带收藏就最好了。
😎欢迎转载,原创不易,转载请注明出处✍️。

😊如果你对小程序开发有兴趣或者正在学习小程序开发,可以关注我。每一篇都是原创,每一篇都是干货噢~。

————————————————
版权声明:本文为CSDN博主「super–Yang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44702572/article/details/135295980

  • 26
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

super--Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值