介绍

微信小程序接口对接,主要涉及以下几个方面:

  1. 模块Config
  2. 客服系统
  3. 小程序登录
  4. CabloyJS后端调用
  5. 微信API调用

1. 模块Config

CabloyJS提供了两种方式来配置Config参数:

  1. 后台管理页面:页面路径为系统应用/基础管理/认证管理

  2. 项目配置:直接在项目配置文件中覆盖模块Config中的参数

关于如何覆盖模块Config,请参见:Config

a-wechat/backend/src/config/config.js

  1. 1 // account.wechatmini
  2. 2 config.account.wechatmini = {
  3. 3 scope: 'snsapi_userinfo',
  4. 4 scenes: {
  5. 5 default: {
  6. 6 title: 'AuthDefault',
  7. 7 appID: '',
  8. 8 appSecret: '',
  9. 9 message: {
  10. 10 token: appInfo.name,
  11. 11 encodingAESKey: '',
  12. 12 },
  13. 13 },
  14. 14 },
  15. 15 };
  • scenes: 支持多个微信小程序。为了实际开发上的便利,我们默认提供一个default小程序。如果需要开发其他微信小程序,直接在scenes添加新的配置即可

2. 客服系统

模块a-wechat已经对客服系统的通讯机制进行了封装,并且通过event机制进行扩展。如果我们要对用户发送的消息进行定制化的回复,可以这样操作:

关于event机制,请参见:后端事件

2.0 消息推送配置

名称 说明
服务器地址(URL) https://xxx.yyy.com/api/a/wechat/message/wechatmini/{providerScene}
令牌(Token) 随机值
消息加解密密钥(EncodingAESKey) 随机值
消息加解密方式 安全模式(推荐)
数据格式 JSON
名称 说明
providerScene 小程序场景名,默认为default

2.1 meta

test-wechat/backend/src/meta.js

  1. 1event: {
  2. 2 implementations: {
  3. 3 'a-wechat:wechatMessageMini': 'wechatMessageMini',
  4. 4 },
  5. 5},
名称 说明
a-wechat:wechatMessageMini 模块名称:事件名称
wechatMessageMini 响应事件的Bean组件

2.2 定义Bean组件

在本示例中,响应事件a-wechat:wechatMessageMini,回复用户发送的消息

src/module/test-wechat/backend/src/bean/event.wechatMessageMini.js

  1. 1module.exports = ctx => {
  2. 2 // const moduleInfo = ctx.app.meta.mockUtil.parseInfoFromPackage(__dirname);
  3. 3 class eventBean {
  4. 4 async execute(context, next) {
  5. 5 const { beanProvider, message } = context.data;
  6. 6 // message
  7. 7 if (message.MsgType === 'text') {
  8. 8 const text = `${ctx.text.locale('zh-cn', 'Reply')}: ${message.Content}`;
  9. 9 await ctx.bean.wechat.mini[beanProvider.providerScene].sendText(message.FromUserName, text);
  10. 10 // break
  11. 11 return;
  12. 12 }
  13. 13 // next
  14. 14 await next();
  15. 15 }
  16. 16 }
  17. 17
  18. 18 return eventBean;
  19. 19};
名称 说明
context.data 外部传入的参数
next event采用洋葱圈模型,调用next从而允许其他事件实现的执行

2.3 注册Bean组件

src/module/test-wechat/backend/src/beans.js

  1. 1const eventWechatMessage = require('./bean/event.wechatMessage.js');
  2. 2
  3. 3module.exports = app => {
  4. 4 const beans = {
  5. 5 // event
  6. 6 'event.wechatMessageMini': {
  7. 7 mode: 'ctx',
  8. 8 bean: eventWechatMessageMini,
  9. 9 },
  10. 10 };
  11. 11 return beans;
  12. 12};
注册名称 场景 所属模块 global beanFullName
wechatMessageMini event test-wechat false test-wechat.event.wechatMessageMini

3. 小程序登录

测试模块test-wechat已经包含了一个微信小程序的demo程序

如何导入demo程序,请参见:快速开始 - 微信小程序开发

这里对demo中涉及到的登录机制进行说明:

3.1 app.js

当小程序启动时,Cabloy SDK会通过wx.loginwx.getUserInfo获取用户信息,并调用CabloyJS后端接口,自动注册用户信息,从而完成用户登录,并返回用户数据

test-wechat/front/demo/miniprogram/app.js

  1. 1// 初始化cabloy
  2. 2const cabloyOptions = {
  3. 3 base: {
  4. 4 providerScene: 'default',
  5. 5 locale: 'en-us',
  6. 6 },
  7. 7 api: {
  8. 8 baseURL: 'http://yourdomain.com',
  9. 9 },
  10. 10};
  11. 11this.cabloy = Cabloy(this, cabloyOptions);
  12. 12// 登录
  13. 13this.cabloy.util.login().then(res => {
  14. 14 // 由于 login 是网络请求,可能会在 Page.onLoad 之后才返回
  15. 15 // 所以此处加入 callback 以防止这种情况
  16. 16 if (this.cabloyLoginReadyCallback) {
  17. 17 this.cabloyLoginReadyCallback(res);
  18. 18 }
  19. 19}).catch(err => {
  20. 20 console.log(err);
  21. 21});
  1. 首先要初始化一个cabloy实例
  2. 其次调用cabloy.util.login进行登录

3.2 pages/index/index.js

因为获取更详细的用户信息,需要用户授权。所以在进入首页后,判断如果没有得到用户授权,仍然可以显示按钮: 获取头像昵称,其属性为open-type="getUserInfo"。响应此按钮事件,当用户授权后会调用方法getUserInfo。在此方法可以再一次调用cabloy.util.login进行登录,并返回用户数据

test-wechat/front/demo/miniprogram/pages/index/index.js

  1. 1getUserInfo(e) {
  2. 2 // 判断是否成功取得用户授权
  3. 3 if (e.detail.errMsg.indexOf(':fail') > -1) return;
  4. 4 // 登录
  5. 5 app.cabloy.util.login({ detail: e.detail }).then(res => {
  6. 6 this.setData({
  7. 7 user: res.op,
  8. 8 hasUserInfo: !!res.op.userName,
  9. 9 });
  10. 10 }).catch(err => {
  11. 11 console.log(err);
  12. 12 });
  13. 13},

4. CabloyJS后端调用

Cabloy SDK提供了便捷的API组件app.cabloy.api,用于小程序前端访问CabloyJS的后端API接口

src/module/test-wechat/front/demo/miniprogram/pages/index/index.js

  1. 1getOpenid(){
  2. 2 app.cabloy.api.post('/test/wechat/test/getOpenidMini', {
  3. 3 providerScene: app.cabloy.config.base.providerScene,
  4. 4 }).then(data => {
  5. 5 this.setData({
  6. 6 openid: data.openid,
  7. 7 });
  8. 8 });
  9. 9},

5. 微信API调用

模块a-wechat提供了全局Bean组件wechat,用于调用所有微信API

比如,通过ctx.bean.wechat.mini.{providerScene}访问微信小程序API

providerScene:是小程序的场景名,缺省为default

src/module-system/a-wechat/backend/src/service/authMini.js

  1. 1// mini
  2. 2const apiMini = this.ctx.bean.wechat.mini[providerScene];
  3. 3const res = await apiMini.code2Session(code);

微信API基于node-webot/co-wechat-api。为了便于更灵活的添加新API,CabloyJS对主仓库发起了一个新分支,详细的API清单请参见:co-wechat-api

6. 如何判断是否在微信小程序

由于CabloyJS后端架构的普适性,我们有时候需要判断当前是否在微信小程序中,从而做出相应的处理

6.1 通过中间件判断

可以通过中间件inWechat来判断该api接口是否被微信小程序调用,如果不是则自动阻止后续逻辑的执行

src/module/test-wechat/backend/src/routes.js

  1. 1 { method: 'post', path: 'test/getOpenidMini', controller: test, middlewares: 'inWechat',
  2. 2 meta: {
  3. 3 inWechat: {
  4. 4 providerName: 'wechatmini',
  5. 5 providerScene: null,
  6. 6 },
  7. 7 },
  8. 8 },
名称 说明
meta.inWechat 中间件inWechat的参数
providerName 认证提供者名称,如果指定wechatmini,表示该api只能被微信小程序调用
providerScene 如果认证提供者支持多个场景,这里可以指定场景名

6.2 通过代码判断

可以直接通过代码进行判断

  1. 1ctx.bean.wechat.util.in({ providerName, providerScene })