腾讯云即时通信IM小程序_AI解决方案_同尘科技

即时通信 IM 2年前 (2023-07-27) 浏览 68

本文以使用 Node.js 开发一个简单的小程序消息通知 Demo 为例,为您介绍基于腾讯云即时通信 IM 的微信小程序消息通知的基本流程。说明示例仅供参考,正式上线前需要进一步完善,例如服务器负载均衡、接口并发控制、信息持久化存储等。此类优化操作不在本文介绍范围内,请开发者根据实际情况自行实现。

场景效果图




流程图



前提条件

注册 小程序。准备一台可以运行 Node.js 的公网开发服务器或云服务器。业务服务器和微信服务器打通,指引文档。已 创建即时通信 IM 应用 并购买旗舰版套餐(查询用户在线状态)。IM 控制台上 配置第三方回调。小程序 订阅消息 并 登录 腾讯云即时通信 IM。

操作步骤

步骤1:创建开发项目并安装依赖

npm init -y
// express 框架npm i express@latest --save // 加密模块npm i crypto@latest --save// 发起 http 请求npm i axios@latest --save// 计算 userSignpm i tls-sig-api-v2@latest --save

步骤2:填入 IM 应用信息并计算 UserSig

// ------------ IM ------------const IMAxios = axios.create({  timeout: 10000,  headers: {    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',  },});
// IM 应用及 App 管理员信息,请登录即时通信 IM 控制台获取const SDKAppID = 0; // 填入 IM 应用的 SDKAppIDconst secrectKey = ''; // 填入 IM 应用的密钥const AppAdmin = 'user0'; // 设置 user0 为 App 管理员账号// 计算 UserSig,调用 REST API 时需要用到,详细操作请参考 Githubconst api = new TLSSigAPIv2.Api(SDKAppID, secrectKey);const userSig = api.genSig(AppAdmin, 86400*180);console.log('userSig ->', userSig);

步骤3:配置消息推送的 URL 和 Token

1. 登录微信小程序管理后台。2. 选择开发管理 > 开发设置 > 消息推送3. 填写相关信息:URL:业务服务器地址,用作接收微信消息和事件的接口 URL,必填参数。Token:可任意填写,用作生成签名,该 Token 会和接口 URL 中包含的 Token 进行比对,从而验证安全性,必填参数。EncodingAESKey:手动填写或随机生成,用作消息体加解密密钥,选填参数。

步骤4:启动 Web 服务,并正确响应微信服务器发送的 Token 验证

// ------------ Web 服务 ------------var app = express();
// 处理所有进入80端口的 get 请求app.get('/', function(req, res) { // ------------ 接入微信公众平台 ------------ // 详细请参考微信官方文档 // 获取微信服务器 Get 请求的参数 signature、timestamp、nonce、echostr var signature = req.query.signature; // 微信加密签名 var timestamp = req.query.timestamp; // 时间戳 var nonce = req.query.nonce; // 随机数 var echostr = req.query.echostr; // 随机字符串 var myToken = ''; // 填入配置的 token
// 将 token、timestamp、nonce 三个参数进行字典序排序 var array = [myToken, timestamp, nonce]; array.sort();
// 将三个参数字符串拼接成一个字符串进行 sha1 加密 var tempStr = array.join(''); const hashCode = crypto.createHash('sha1'); // 创建加密类型 var resultCode = hashCode.update(tempStr,'utf8').digest('hex'); // 对传入的字符串进行加密
// 开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信 if (resultCode === signature) { res.send(echostr); getAccessToken(); } else { res.send('404 not found'); }});

步骤5:处理微信服务器的消息推送

// 处理微信的 post 请求app.post('/', function(req, res) {  var buffer = [];  // 监听 data 事件,用于接收数据  req.on('data', function(data) {    buffer.push(data);  });  // 监听 end 事件,用于处理接收完成的数据  req.on('end', function() {    const tmpStr = Buffer.concat(buffer).toString('utf-8');    const tmpObject = JSON.parse(tmpStr);    const { MsgType, Event, FromUserName } = tmpObject;    if (MsgType === 'event') {      if (Event === 'subscribe_msg_popup_event') {        // 订阅消息事件        const { TemplateId, SubscribeStatusString } = tmpObject.List;        // 订阅结果        if (SubscribeStatusString === 'accept') {          // 订阅 | FromUserName - 用户 openID | TemplateId - 订阅的模板 ID          // 接入侧需要管理小程序用户 openID 和模板 ID 的关系        } else if (SubscribeStatusString === 'reject') {          // 拒收        }      }    }    console.log('data from wx ->', tmpStr);  });});

步骤6:处理 IM 消息回调,查询用户在线状态

// 处理 IM 第三方回调的 post 请求app.post('/imcallback', function(req, res) {  var buffer = [];  // 监听 data 事件 用于接收数据  req.on('data', function(data) {    buffer.push(data);  });  // 监听 end 事件 用于处理接收完成的数据  req.on('end', function() {    const tmpStr = Buffer.concat(buffer).toString('utf-8');    console.log('imcallback ->', tmpStr);    const imData = JSON.parse(tmpStr);    const { CallbackCommand } = imData;    if (CallbackCommand === 'State.StateChange') {      // 在线状态变更      const { To_Account, Action } = imData.Info;      if (Action === 'Login') {        // 用户主动登录      } else if (Action === 'Logout') {        // 用户主动登出      } else if (Action === 'Disconnect') {        // 链接断开,离线,如小程序切后台,或用户主动 kill 客户端进程      }    } else if (CallbackCommand === 'C2C.CallbackBeforeSendMsg') {      // 发单聊消息之前回调      const { From_Account, To_Account, MsgBody } = imData;      // From_Account - 消息发送方 | To_Account - 消息接收方      // 查询 To_Account 是否在线      IMAxios({        url: `https://console.tim.qq.com/v4/openim/query_online_status?` +          + `sdkappid=${SDKAppID}&identifier=${AppAdmin}&usersig=${userSig}`          + `&random=${Math.floor(Math.random() * 1000000)}&contenttype=json`,        data: {          IsNeedDetail: 1, // 是否需要返回详细的登录平台信息。0表示不需要,1表示需要          To_Account: [To_Account]        },        method: 'POST'      }).then((res) => {        console.log('query_online_status res.data ->', res.data);        const { Status } = res.data.QueryResult[0];        if (Status === 'Offline') {          // 离线才调用微信接口推送         sendSubscribeMessage(From_Account);      }).catch((error) => {        console.log('query_online_status failed ->', error);      });    }
res.send({ "ActionStatus": "OK", "ErrorInfo": "", "ErrorCode": 0 // 0表示允许发言,1表示拒绝发言 }); });});

步骤7:调用微信接口,发送订阅消息

const sendSubscribeMessage = function(fromAccount) {  getAccessToken().then((accessToken) => {    // 接入侧需处理腾讯云 IM userID,微信小程序 openID,订阅消息模板 ID 的映射关系    pushToUser({      access_token: accessToken,      touser: wxOpenID,      template_id: templateID,      // 模板数据格式跟用户选择的模板有关,以下数据结构仅供参考      data: {        thing16: {          value: fromAccount,        },        time3: {          value: '2022年08月11日',        },        phrase8: {          value: '来电提醒',        },        thing2: {          value: '三年二班班主任来电'        }      }    });  });};
// 获取小程序全局唯一后台接口调用凭据(access_token)。// 调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存const getAccessToken= function() { // 小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且账号没有异常状态) let appid = ''; // 小程序唯一凭证密钥,即 AppSecret,获取方式同 appid let secret = ''; let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential` + `&appid=${appid}&secret=${secret}`; return new Promise(function(resolve, reject) { IMAxios({ url: url, method: 'GET' }).then((res) => { console.log('getAccessToken res.data ->', res.data); resolve(accessToken); }).catch((error) => { console.log('getAccessToken failed ->', error); reject(error); }); });}
// 发送订阅消息const pushToUser = function(options) { console.log('pushToUser options ->', options); const { access_token, touser, template_id, data } = options; IMAxios({ url: `https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${access_token}`, data: { touser, // 接收者(用户)的 openID template_id, // 所需下发的订阅模板 ID data, // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } }, method: 'POST' }).then((res) => { console.log('pushToUser res.data ->', res.data); }).catch((error) => { console.log('pushToUser failed ->', error); });};

参考文档

小程序订阅消息腾讯云 IM 第三方回调SDK API(Web & 小程序 & uni-app)

注意事项

微信小程序只支持微信内通知。为了更好的用户体验,对于接收到多条服务通知后仍保持离线的用户,开发者可以对后续的服务通知合并后再下发,减少下发的次数。一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,微信提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放。

对即时通讯IM解决方案有疑惑?想了解解决方案收费? 联系解决方案专家

腾讯云限时活动1折起,即将结束: 马上收藏

同尘科技为腾讯云授权服务中心,购买腾讯云享受折上折,更有现金返利:同意关联,立享优惠

阿里云解决方案也看看?: 点击对比阿里云的解决方案

- 0人点赞 -

发表点评 (0条)

not found

暂无评论,你要说点什么吗?