我们本次实战项目构建的相当于一个预约平台,既有家政企业,也有家政服务人员还有用户。不同的人员需要收到不同的消息,比如用户可以收到订单状态变更的消息,客服可以收到下单的消息,家政服务人员可以收到派单的消息。
如果是使用小程序订阅消息,存在的问题是订阅消息必须对方主动订阅才可以发,而且订阅一次才可以发一次。
对于用户可能问题不大,但是对于客服和家政人员就不太合适。因为他们接收消息是被动的,而且是接收多次消息。
对于这种需求,我们就需要和公众号集成来完成消息的接收。
1 使用测试号
登录到公众号后台,找到开发者工具,点击公众号测试号
用你自己的号扫码登录
登录之后,系统会给你初始化一个测试账号
这里的appID和appsecret在调用公众号接口的时候需要传入,下边的接口配置信息,主要是用来获取用户关注的事件,这里配置了微搭工作流的地址,我们接下来介绍一下工作流的配置
2 工作流配置
打开应用编辑器,切换到工作流视图,点击+号创建工作流
选择处理微信消息的通知模板
选择第一个节点,配置公众号的appid,token和secret我们选择随机生成
然后复制一下接收推送的URL,贴入到我们公众号的接口配置里,这样当用户在接收推送的时候就调用了微搭的工作流作为响应
3 配置关注事件脚本
在工作流里我们具体的关注事件响应是在js脚本里设置的,选中我们的js脚本节点,点击编辑
脚本的逻辑是先看表存不存在,不存在就创建一个,然后给用户返回一个欢迎信息
我们这里要修改一下,我们的表是事先创建好的,切换到数据源视图,找到我们的用户注册数据源,切换到基本信息,复制一下表信息
关注的时候需要写入正式表,点击立即发布
为了给用户发送消息,我们需要添加一列是公众号的openid
再添加一列公众号unionid
这里解释一下为什么要添加unionid,微信体系下如果公众号、小程序要进行关联的,需要用到unionid,前提是你的公众号和小程序都绑定到微信开放平台
4 注册开放平台
打开微信开发平台,按照提升进行注册
第二步登记主体信息
第三歩确认主体信息,注册成功后就可以将我们刚刚输入的邮箱和密码作为登录的用户名和密码了
登录之后先需要进行认证
认证通过之后,就需要将我们的公众号和小程序都绑定到开放平台
绑定之后我们的各个主体账号就统一到了开放平台下,这样就可以返回同一个unionid
5 获取公众号access_token
如果需要调用公众号接口的,先需要获取公众号的access_token,我们先创建一个数据源用来保存我们的access_token
先添加一列access_token类型选择文本
再添加一列expire_in类型选择数字
然后切换到工作流,新增一个工作流,选择空模板
第一个节点我们选择指定时间触发
选择重复周期为分钟,我们设置为每15分钟
然后拖入一个运行js脚本节点
将两个节点连接起来
在脚本里输入如下代码用来更新我们的token信息
const cloudbase = require('@cloudbase/node-sdk')
const fetch = require('node-fetch');
const app = cloudbase.init({
env: cloudbase.SYMBOL_CURRENT_ENV
})
// 1. 获取数据库引用
const db = app.database()
// 获取access_token的函数
async function getAccessToken(appId, appSecret) {
const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data && data.access_token) {
return data.access_token;
} else {
console.error('获取access_token失败:', data);
return null;
}
} catch (error) {
console.error('获取access_token出错:', error);
return null;
}
}
// 查找存储access_token的文档的函数
async function findAccessTokenDoc() {
console.log("-----------ssss-----------------")
try {
const tokenDocs = await db.collection('lcap-data-3ThdFDXPo-gzhtoken_uwynyav')
.get()
console.log("----------------------------", tokenDocs)
if (tokenDocs.data && tokenDocs.data.length > 0) {
return tokenDocs.data[0];
} else {
return null;
}
} catch (error) {
console.error('查找access_token文档出错:', error);
return null;
}
}
// 写入云开发数据库中的access_token的函数
async function addAccessTokenToDatabase(accessToken, expiresIn) {
try {
const res = await db.collection('lcap-data-3ThdFDXPo-gzhtoken_uwynyav').add({
access_token: accessToken,
expire_in: expiresIn,
createdAt: new Date().getTime(), // 存储为毫秒值
createBy: "",
updateBy: "",
_openid: "",
updatedAt: new Date().getTime(), // 存储为毫秒值
});
console.log('access_token写入成功,文档ID:', res);
return res
} catch (error) {
console.error('access_token写入失败:', error);
return null
}
}
// 更新云开发数据库中的access_token的函数
async function updateAccessTokenInDatabase(docId, accessToken, expiresIn) {
try {
const res = await db.collection('lcap-data-3ThdFDXPo-gzhtoken_uwynyav').doc(docId).update({
access_token: accessToken,
expire_in: expiresIn,
updatedAt: new Date().getTime(), // 存储为毫秒值
});
console.log('access_token更新成功');
return res
} catch (error) {
console.error('access_token更新失败:', error);
return null
}
}
const appId = '';
const appSecret = '';
let res = null
const tokenDoc = await findAccessTokenDoc();
if (tokenDoc) {
const docId = tokenDoc._id;
const accessToken = await getAccessToken(appId, appSecret);
if (accessToken) {
res = await updateAccessTokenInDatabase(docId, accessToken, 7200);
}
} else {
const accessToken = await getAccessToken(appId, appSecret);
console.log("accessToken", accessToken)
if (accessToken) {
res = await addAccessTokenToDatabase(accessToken, 7200);
}
}
return {
res
}
代码的逻辑是,如果还没有写入token,那么就调用新增接口写入,如果已经写入了,就调用更新接口做更新操作
在工作流中,我们调用第三方接口的需要用到node-fetch包,其次如果我们想操作数据库的需要引入数据库的sdk
6 实现关注业务逻辑
相关配置都准备好之后,我们就可以写关注的逻辑了。我们的想法是如果用户关注,我们先获取到用户的openid,然后根据openid调用用户信息接口获取unionid,将获得的信息写入到数据源中,完成一个注册,代码如下:
const cloudbase = require("@cloudbase/node-sdk");
const fetch = require('node-fetch');
const app = cloudbase.init({
env: cloudbase.SYMBOL_CURRENT_ENV // 这里可以修改为其他环境
});
const db = app.database();
const tokenDocs = await db.collection('lcap-data-3ThdFDXPo-gzhtoken_uwynyav')
.get()
console.log("tokenDocs",tokenDocs)
const access_token = tokenDocs.data[0].access_token;
console.log("access_token",access_token)
const openid =""// wxTrigger.output.FromUserName;
const response = await fetch(`https://api.weixin.qq.com/cgi-bin/user/info?access_token=${access_token}&openid=${openid}&lang=zh_CN`);
console.log("response",response)
const data = await response.json();
console.log("data",data)
const unionid = data?.unionid
const users = await db.collection("lcap-data-3Rr9TzWzJ-yhgl_2rtx1m9");
const { total } = await users.where({ gzhopenid: openid }).count();
console.log("total",total)
const isNewUser = total === 0;
console.log("isNewUser",isNewUser)
if (isNewUser) {
await users.add({ gzhopenid: data.openid ,gzhunionid:unionid});
}
return `${isNewUser ? "感谢您的关注" : "感谢您再次关注" };
总结
本篇我们介绍了如何和公众号集成,将公众号的信息和小程序的信息关联是必备的功能,后续章节中我们介绍一下小程序注册用户时如何和公众号进行关联