家政预约小程序10公众号集成

news2025/1/22 9:23:32

目录

  • 1 使用测试号
  • 3 工作流配置
  • 4 配置关注事件脚本
  • 5 注册开放平台
  • 6 获取公众号access_token
  • 6 实现关注业务逻辑
  • 总结

我们本次实战项目构建的相当于一个预约平台,既有家政企业,也有家政服务人员还有用户。不同的人员需要收到不同的消息,比如用户可以收到订单状态变更的消息,客服可以收到下单的消息,家政服务人员可以收到派单的消息。

如果是使用小程序订阅消息,存在的问题是订阅消息必须对方主动订阅才可以发,而且订阅一次才可以发一次。

对于用户可能问题不大,但是对于客服和家政人员就不太合适。因为他们接收消息是被动的,而且是接收多次消息。

对于这种需求,我们就需要和公众号集成来完成消息的接收。

1 使用测试号

登录到公众号后台,找到开发者工具,点击公众号测试号
在这里插入图片描述
用你自己的号扫码登录
在这里插入图片描述
登录之后,系统会给你初始化一个测试账号
在这里插入图片描述
这里的appID和appsecret在调用公众号接口的时候需要传入,下边的接口配置信息,主要是用来获取用户关注的事件,这里配置了微搭工作流的地址,我们接下来介绍一下工作流的配置

3 工作流配置

打开应用编辑器,切换到工作流视图,点击+号创建工作流
在这里插入图片描述
选择处理微信消息的通知模板
在这里插入图片描述
选择第一个节点,配置公众号的appid,token和secret我们选择随机生成
在这里插入图片描述
然后复制一下接收推送的URL,贴入到我们公众号的接口配置里,这样当用户在接收推送的时候就调用了微搭的工作流作为响应

4 配置关注事件脚本

在工作流里我们具体的关注事件响应是在js脚本里设置的,选中我们的js脚本节点,点击编辑
在这里插入图片描述
在这里插入图片描述
脚本的逻辑是先看表存不存在,不存在就创建一个,然后给用户返回一个欢迎信息

我们这里要修改一下,我们的表是事先创建好的,切换到数据源视图,找到我们的用户注册数据源,切换到基本信息,复制一下表信息
在这里插入图片描述
关注的时候需要写入正式表,点击立即发布
在这里插入图片描述
为了给用户发送消息,我们需要添加一列是公众号的openid
在这里插入图片描述
再添加一列公众号unionid
在这里插入图片描述
这里解释一下为什么要添加unionid,微信体系下如果公众号、小程序要进行关联的,需要用到unionid,前提是你的公众号和小程序都绑定到微信开放平台

5 注册开放平台

打开微信开发平台,按照提升进行注册
在这里插入图片描述
第二步登记主体信息
在这里插入图片描述
第三歩确认主体信息,注册成功后就可以将我们刚刚输入的邮箱和密码作为登录的用户名和密码了
在这里插入图片描述
登录之后先需要进行认证
在这里插入图片描述
在这里插入图片描述
认证通过之后,就需要将我们的公众号和小程序都绑定到开放平台
在这里插入图片描述
绑定之后我们的各个主体账号就统一到了开放平台下,这样就可以返回同一个unionid

6 获取公众号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 ? "感谢您的关注" : "感谢您再次关注" };

总结

本篇我们介绍了如何和公众号集成,将公众号的信息和小程序的信息关联是必备的功能,后续章节中我们介绍一下小程序注册用户时如何和公众号进行关联

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11- Redis 中的 SDS 数据结构

字符串在 Redis 中是很常用的,键值对中的键是字符串类型,值有时也是字符串类型。 Redis 是用 C 语言实现的,但是它没有直接使用 C 语言的 char* 字符数组来实现字符串,而是自己封装了一个名为简单动态字符串(simple d…

基于强化学习的控制率参数自主寻优

1.介绍 针对控制建模与设计场景中控制参数难以确定的普遍问题,提出了一种基于强化学习的控制律参数自主优化解决方案。该方案以客户设计的控制律模型为基础,根据自定义的控制性能指标,自主搜索并确定最优的、可状态依赖的控制参数组合。 可…

ToDesk提示会话数通道限制 - 解决方案及兑惠码分享

如果您最近在体验ToDesk这款远程操控工具时,遇到了提示信息告知“高速通道服务已到期”或“会话数受限”,这表明您本月享受的免费额度——即120小时的使用时间和最多300次的连接机会——已经耗尽。为了解锁无限制的使用时长与连接次数,建议您…

自动驾驶中的长尾问题

自动驾驶中的长尾问题 定义 长尾问题(Long-Tail Problem)是指在数据分布中,大部分的数据集中在少数类别上,而剩下的大多数类别却只有少量的数据。这种数据分布不平衡的现象在许多实际应用中广泛存在,特别是在自动驾驶…

20240531在飞凌的OK3588-C开发板上跑原厂的Buildroot测试USB摄像头

20240531在飞凌的OK3588-C开发板上跑原厂的Buildroot测试USB摄像头 2024/5/31 20:04 USB摄像头分辨率:1080p(1920x1080) 默认编译Buildroot的SDK即可点亮USB摄像头。v4l2-ctl --list-devices v4l2-ctl --list-formats-ext -d /dev/video74 …

双指针法 ( 快乐数 )

「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1,那么这个数就是快乐数 编写一个算法来判断一个…

linux /www/server/cron内log文件占用空间过大,/www/server/cron是什么内容,/www/server/cron是否可以删除

linux服务器长期使用宝塔自带计划任务,计划任务执行记录占用服务器空间过大,导致服务器根目录爆满,需要长期排查并删除 /www/server/cron 占用空间过大问题处理 /www/server/cron是什么内容?/www/server/cron是否可以删除&#xf…

基于VGG16使用图像特征进行迁移学习的时装推荐系统

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…

AutoMQ 自动化持续测试平台技术内幕

01 背景 AutoMQ[1] 作为一款流系统,被广泛应用在客户的核心链路中,对可靠性的要求非常的高。所以我们需要一套模拟真实生产场景、长期运行的测试环境,在注入各种故障场景的前提下验证 SLA 的可行性,为新版本的发布和客户的使用提…

c# - 运算符 << 不能应用于 long 和 long 类型的操作数

Compiler Error CS0019 c# - 运算符 << 不能应用于 long 和 long 类型的操作数 处理方法 特此记录 anlog 2024年5月30日

【论文精读】SAM

摘要 本文提出Segment Anything&#xff08;SA&#xff09;&#xff0c;一个可prompt的视觉分割模型&#xff0c;通过一个 能实现视觉特征强大泛化的任务在包含大量图像的数据集上对模型进行预 训练&#xff0c;旨在通过使用prompt工程解决新数据 分布上的一系列下游分割问题。…

深入了解diffusion model

diffusion model是如何运作的 会输入当时noise的严重程度&#xff0c;根据我们的输入来确定在第几个step&#xff0c;并做出不同的回应。 Denoise模组内部实际做的事情 产生一张图片和产生noise难度是不一样的&#xff0c;若denoise 模块产生一只带噪声的猫说明这个模块已经会…

【Python】 Python中的递增和递减操作符:简单易懂的指南

基本原理 在Python中&#xff0c;递增&#xff08;increment&#xff09;和递减&#xff08;decrement&#xff09;操作符是用于快速增加或减少变量值的快捷方式。这些操作符在很多编程语言中都有出现&#xff0c;它们提供了一种方便的方式来对变量进行自增&#xff08;&#…

【JavaEE进阶】——带你详细了解Spring日志以及配置日志

目录 &#x1f6a9;Spring日志的认识 &#x1f6a9;Spring日志的作用 &#x1f6a9;观察日志 &#x1f6a9;使用日志 &#x1f388;在程序中得到日志对象 &#x1f388;使⽤⽇志对象输出要打印的内容 &#x1f6a9;日志框架的介绍 &#x1f388;门面模式(外观模式&…

鸿蒙ArkTS声明式开发:跨平台支持列表【透明度设置】 通用属性

透明度设置 设置组件的透明度。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版…

GIS Java 生成四至图

目录 前言 操作步骤&#xff1a; 1&#xff0c;求出多边形的四至点 2&#xff0c;下载地图 3&#xff0c;绘制多边形 前言 对于地图上的一个多边形地块&#xff0c;其四至图就是能够覆盖这个多边形的最小矩形&#xff0c;也就是求出这个多边形的最东点&#xff0c;最西点&…

如何从浅入深理解transformer?

前言 在人工智能的浩瀚海洋中&#xff0c;大模型目前无疑是其中一颗璀璨的明星。从简单的图像识别到复杂的自然语言处理&#xff0c;大模型在各个领域都取得了令人瞩目的成就。而在这其中&#xff0c;Transformer模型更是成为大模型技术的核心。 一、大模型的行业发展现状如…

AI实时免费在线图片工具3:人物换脸、图像编辑

1、FaceAdapter 人物换脸 https://huggingface.co/spaces/FaceAdapter/FaceAdapter 2、InstaDrag https://github.com/magic-research/InstaDrag

M-G364PD惯性测量单元:相机及微小层面的革命性应用

在现代科技飞速发展的今天&#xff0c;精准控制和精确测量是众多高端设备实现卓越性能的关键。爱普生推出的M-G364PD惯性测量单元&#xff08;IMU&#xff09;&#xff0c;因其卓越的性能和微小尺寸&#xff0c;成为相机以及其他微小层面应用的理想选择&#xff0c;为科技创新提…

实现计算器的基本操作:加减乘除与百分数

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、加减乘除的实现 1. 操作数与操作符 2. 逻辑处理 3. 示例代码 三、求百分数…