介绍

企业微信自建应用接口对接,主要涉及以下几个方面:

  1. 模块Config
  2. 消息推送
  3. 网页登录
  4. 网页前端JSSDK
  5. 企业微信网页布局
  6. 企业微信API调用

1. 模块Config

我们可以通过在项目Config文件中覆盖模块Config中的参数,从而配置与企业微信有关的信息

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

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

  // account.wxwork
  config.account.wxwork = {
    corpid: '',
    // apps
    apps: {
      selfBuilt: {
        agentid: '',
        secret: '',
        token: appInfo.name,
        encodingAESKey: '',
        message: {
          reply: {
            default: 'You are welcome!',
          },
        },
        jssdk: {
          debug: false,
          jsApiList,
        },
        jssdkAgent: {
          jsApiList: jsApiListAgent,
        },
      },
      contacts: {
        secret: '',
        token: appInfo.name,
        encodingAESKey: '',
      },
    },
  };
名称 说明
apps 配置所有微信应用的参数,包括:企业微信内置应用、第三方应用,以及自建应用。如需访问其他应用提供的API接口,直接在apps添加新的配置即可
apps.selfBuilt 自建应用
apps.contacts 企业微信内置应用 - 通讯录应用

2. 消息推送

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

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

2.0 消息推送配置

名称 说明
服务器地址(URL) https://xxx.yyy.com/api/a/wxwork/message/index
令牌(Token) 随机值
消息加解密密钥(EncodingAESKey) 随机值

2.1 meta

test-wxwork/backend/src/meta.js

event: {
      implementations: {
        'a-wxwork:wxworkMessage': 'event/wxworkMessage',
    },

声明一个event实现,通过api路由event/wxworkMessage来响应事件a-wxwork:wxworkMessage,从而实现自定义的消息响应逻辑

2.2 路由

test-wxwork/backend/src/routes.js

{ method: 'post', path: 'event/wxworkMessage', controller: event, middlewares: 'inner,wxwork', meta: { auth: { enable: false } } },
名称 说明
middlewares: inner 声明该api只能被内部调用
middlewares: wxwork 注入wxwork api对象,便于通过ctx.meta.wxwork来调用微信api接口
auth: { enable: false } 由于是内部调用,所以禁用中间件auth,从而不需要对ctx.user进行处理

2.3 Controller

test-wxwork/backend/src/controller/event.js

    async wxworkMessage() {
      const res = await this.service.event.wxworkMessage({
        event: this.ctx.request.body.event,
        data: this.ctx.request.body.data,
      });
      this.ctx.success(res);
    }

2.4 Service

test-wxwork/backend/src/service/event.js

    async wxworkMessage({ event, data }) {
      const message = data.message;
      if (message.MsgType === 'text') {
        event.break = true;
        return {
          ToUserName: message.FromUserName,
          FromUserName: message.ToUserName,
          CreateTime: new Date().getTime(),
          MsgType: 'text',
          Content: `${this.ctx.text.locale('zh-cn', 'Reply')}: ${message.Content}`,
        };
      }
    }
名称 说明
event.break=true 由于同一个事件可以有多个模块进行订阅,并提供自定义的逻辑。如果想阻止后续的订阅响应,可以通过event.break=true进行终止

3. 网页登录

模块a-wxwork自动判断,如果当前网页处于企业微信app中,会自动转向企业微信登录,然后自动进行用户认证

4. 网页前端JSSDK

模块a-wxwork提供了便捷的组件,可以自动注入微信JSSDK,并且自动进行config配置

测试模块test-wxwork演示了如何调用微信的二维码扫描操作:

test-wechat/front/src/pages/test/index.vue

  created() {
    const action = {
      actionModule: 'a-wxwork',
      actionComponent: 'jssdk',
      name: 'config',
    };
    this.$meta.util.performAction({ ctx: this, action }).then(res => {
      this.wx = res && res.wx;
    }).catch(e => {
      this.$view.toast.show({ text: e.message });
    })
  },
  mounted() {
    this.messagebar = this.$refs.messagebar.f7Messagebar;
  },
  methods: {
    onPerformScanQRCode() {
      this.wx.scanQRCode({
        needResult: 1,
        scanType: ['qrCode', 'barCode'],
        success: res => {
          this.$view.toast.show({ text: res.resultStr });
        },
        fail: res => {
          this.$view.toast.show({ text: res.errMsg });
        }
      });
    },
  }
  1. 先通过this.$meta.util.performAction调用模块a-wxwork提供的组件,返回wx对象
  2. 调用wx对象执行扫描二维码的微信接口

5. 企业微信网页布局

CabloyJS可以一站式开发PC端和移动端的网页,此外,CabloyJS通过event机制可以灵活定制不同场景下前端页面的布局组合

测试模块test-wxwork演示了如何定制Mobile场景下的前端布局:

5.1 meta

test-wxwork/backend/src/meta.js

event: {
      implementations: {
        'a-base:loginInfo': 'event/loginInfo',
    },

5.2 路由

test-wxwork/backend/src/routes.js

{ method: 'post', path: 'event/loginInfo', controller: event, middlewares: 'inner', meta: { auth: { enable: false } } },

5.3 Controller

test-wxwork/backend/src/controller/event.js

    async loginInfo() {
      const res = await this.service.event.loginInfo({
        event: this.ctx.request.body.event,
        data: this.ctx.request.body.data,
      });
      this.ctx.success(res);
    }

5.4 Service

test-wxwork/backend/src/service/event.js

    async loginInfo({ /* event,*/ data }) {
      const info = data.info;
      const provider = info.user && info.user.provider;
      if (provider && provider.module === 'a-wxwork' && provider.providerName === 'wxwork') {
        info.config = extend(true, info.config, {
          modules: {
            'a-layoutmobile': {
              layout: {
                login: '/a/login/login',
                loginOnStart: true,
                toolbar: {
                  tabbar: true, labels: true, bottomMd: true,
                },
                tabs: [
                  { name: 'Test', tabLinkActive: true, iconMaterial: 'group_work', url: '/test/wxwork/test/index' },
                  { name: 'Home', tabLinkActive: false, iconMaterial: 'home', url: '/a/base/menu/list' },
                  { name: 'Mine', tabLinkActive: false, iconMaterial: 'person', url: '/a/user/user/mine' },
                ],
              },
            },
          },
        });
      }
    }

判断info.user.provider,如果是通过企业微信app登录的账户,就提供自定义的前端布局参数

6. 企业微信API调用

模块a-wxwork通过中间件机制提供了一个中间件wxwork,如果要在后端API接口中访问企业微信API,只需要在API接口路由中指定中间件wxwork即可。然后按如下方式调用企业微信API

this.ctx.meta.wxwork.app.${appName}

名称 说明
appName 应用名称,比如selfBuilt(自建应用)

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

下面以JSSDK Config为例:

6.1 路由

a-wxwork/backend/src/routes.js

{ method: 'post', path: 'jssdk/jsconfig', controller: jssdk, middlewares: 'wxwork' },

6.2 Controller

a-wxwork/backend/src/controller/jssdk.js

    async jsconfig() {
      const res = await this.service.jssdk.jsconfig({
        url: this.ctx.request.body.url,
      });
      this.ctx.success(res);
    }

6.3 Service

a-wxwork/backend/src/service/jssdk.js

    async jsconfig({ url }) {
      // config
      const config = this.ctx.config.account.wxwork;
      const configAppSelfBuilt = config.apps.selfBuilt;
      // params
      const params = {
        debug: configAppSelfBuilt.jssdk.debug,
        jsApiList: configAppSelfBuilt.jssdk.jsApiList,
        url,
      };
      return await this.ctx.meta.wxwork.app.selfBuilt.getJsConfig(params);
    }

直接通过this.ctx.meta.wxwork.app.selfBuilt访问相应的企业微信API

7. 如何判断是否在企业微信

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

7.1 通过中间件判断

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

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

  { method: 'post', path: 'test/getMemberId', controller: test, middlewares: 'inWxwork',
      meta: {
        inWxwork: {
          scene: 'wxwork,wxworkweb,wxworkmini',
        },
      },
    },
名称 说明
meta.inWxwork 指定中间件inWxwork的参数
scene 如果指定wxwork,表示该api只能被企业微信调用

scene支持以下值:

名称 说明
空字符串 默认为wxwork,代表企业微信
wxworkweb 代表企业微信Web应用
wxworkmini 代表企业微信小程序
wxworkmini${scene} 指定更明确的某个小程序,如wxworkminidefault
wxwork,wxworkweb,wxworkmini 该api可被任何一个指定的场景调用

7.2 通过代码判断

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

this.ctx.meta.wxwork.util.in(scene)

名称 说明
scene 场景名,如wxwork