通讯录展示组件

[TOC]

1. 背景介绍

企业通讯录是企业的重要敏感数据,第三方将不再直接获取到授权企业的通讯录数据(接口将不再返回人名与部门名)。第三方页面若需要展示用户的通讯录信息,可使用如下的 open-data 组件,以提供更加安全良好的体验。

相关概念可以参考微信小程序的 open-data 组件。
常见问题可参考:通讯录展示控件 - FAQ

2. 浏览器方案

2.1 环境要求

  • 企业微信APP需 2.8.10 及以上版本

2.2 使用方法

1. 通过企业微信登录应用管理后台

非微信、企业微信内置浏览器中使用 open-data 时,需要通过企业微信管理端跳转第三方登录授权进行登录。

需要注意,通过上述方法登录跳转的目标域名要和使用 open-data 的页面域名保持一致。

在开发过程中,我们可以在 open-data 调试页面中查看当前浏览器登录的应用信息。

2. 引入 open-data SDK

在页面上引入以下SDK:

<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>

  • sdk 内容是动态返回的,请严格按照上面的方式引入,不要保存到项目本地后打包引入

  • referrerpolicy 声明为 origin 是为了让 sdk 能够顺利识别关键域名,不能去掉

3. 进行 agentConfig

无论是微信、企业微信的内置浏览器还是第三方浏览器,都需要通过 agentConfig 登记第三方应用的身份信息。

需要注意,在第三方浏览器中调用 wx.agentConfig 前不需要进行 wx.config。

注意:在企业微信客户端的页面上,进行 agentConfig 的调用,必须要等 wx.config 完成后才调用(即 wx.config 的成功回调)

4. 绑定 open-data 元素

上述步骤完成后,我们就可以通过 WWOpenData.bind 方法对页面上的元素进行绑定,完成后 SDK 将在绑定的元素上渲染出对应的开放数据:

<!-- 注意:这里的 openid 是 userid 和 departmentid 的统称 -->
<ww-open-data type="userName" openid="{{openid}}"></ww-open-data>
<script>
    WWOpenData.bind(document.querySelector('ww-open-data'))
</script>

open-data 元素上的属性请参考2.5 元素属性章节。
在支持 custom elements 的浏览器中,SDK 会自动对 <ww-open-data> 元素进行绑定。

2.3 API 列表

WWOpenData.bind(el: Element)

绑定 open-data 元素,在获取数据后,SDK 将在元素内渲染出对应的开放数据。

WWOpenData.bindAll(nodeList: NodeList | Array<Element>)

批量绑定 open-data 元素,参考 WWOpenData.bind。

注意:为了保证在所有环境下表现正常,一旦 open-data 元素的内容发生了变化,必须调用 WWOpenData.bind 接口重新绑定一次

WWOpenData.on(event: string, callback: Function)

为兼容旧版本终端,使用前需要判断函数是否存在

添加事件监听函数,事件列表参考2.4 事件列表

WWOpenData.off(event: string, callback: Function)

为兼容旧版本终端,使用前需要判断函数是否存在

移除事件监听函数。

WWOpenData.checkSession(params: CheckSessionParams)

为兼容旧版本终端,使用前需要判断函数是否存在

检查登录态信息。

if (WWOpenData.checkSession) {
    WWOpenData.checkSession({
        success() {
            console.log('有登录态')
        },
        fail() {
            console.error('登录态过期')
        }
    })
}

WWOpenData.initCanvas()

启动 canvas 支持功能

WWOpenData.prefetch(params: PrefetchParams)

预加载通讯录数据

if (WWOpenData.prefetch) {
    WWOpenData.prefetch({ items }, (err, data) => {
        if (err) {
            // 错误处理
        }
        // 数据处理
    })
}

注意:出于安全设计和浏览器策略,prefetch 接口必须在 https 的网页下调用,否则会报运行错误

2.4 事件列表

sessionTimeout

当 SDK 检测到登录态过期时触发。

error

当 SDK 获取数据失败时触发。

update

当 open-data 元素渲染内容发生变更时触发。

2.5 元素属性

页面通过 open-data 元素上的属性控制需要渲染的内容:

属性 类型 必填 说明
type string 开放数据类型
openid string 数据ID,根据type取值而定

type 的合法值

说明
userName 用户名称
departmentName 部门名称

若 type=userName,此时 openid 对应 userid
若 type=departmentName,此时 openid 对应 departmentid
每 20ms 最多绑定 1000 个 open-data 元素,超出的部分将被忽略

2.6 前端框架适配

若页面使用了 vue、react 等前端框架,可在框架提供的钩子函数中调用 WWOpenData.bind 进行绑定:

Vue

<template>
    <ww-open-data :type="type" :openid="openid" />
</template>

<script>
export default {
    props: ['type', 'openid'],
    mounted() {
        WWOpenData.bind(this.$el)
    }
}
</script>

React

import React, { useRef, useLayoutEffect } from 'react'

export default function WWOpenDataCom({ type, openid }) {
    const ref = useRef(null)
    useLayoutEffect(() => {
        WWOpenData.bind(ref.current)
    })
    return <ww-open-data ref={ref} type={type} openid={openid} />
}

2.7 示例代码

<html>
<body>
    <ww-open-data type="userName" openid="{{openid}}"></ww-open-data>
    <script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="//open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
    <script>
        (async () => {
            if (/MicroMessenger/i.test(navigator.userAgent)) {
                await config(configParams)
            }
            await agentConfig(agentConfigParams)
            // 注意: 在企业微信平台下,只有 agentConfig 成功回调后,WWOpenData 才会注入到 window 对象上面
            WWOpenData.bindAll(document.querySelectorAll('ww-open-data'))
        })()
        function config(config) {
            return new Promise((resolve, reject) => {
                wx.config(config)
                wx.ready(resolve)
                wx.error(reject)
            })
        }
        function agentConfig(config) {
            return new Promise((success, fail) => {
                wx.agentConfig({ ...config, success, fail })
            })
        }
    </script>
</body>
</html>

更加完整的示例程序,可以参考 open-data 控件 demo

3. 小程序方案

3.1 环境要求

  • 企业微信APP需 2.8.9 及以上版本
  • 微信上小程序基础库版本需 1.9.6 及以上版本
  • 开发者工具中不要在企业微信小程序模式下运行插件

注意:当前小程序通讯录展示插件不支持显示头像

3.2 使用方法

(1) 开发者在小程序管理后台申请使用插件,添加路径:设置 ->第三方服务 -> 插件管理 -> 添加插件,搜索并添加插件ID: wx5917c8c26f85c588,无需审核确认。
(2) 开发者在小程序app.json 文件中添加对插件的引用

"plugins": {
    "contactPlugin": {
        "version": "1.2.1",
        "provider": "wx5917c8c26f85c588"
    }
}

(3) 开发者在具体引用插件的页面文件json文件中,添加对组件的引用,例如:

"usingComponents": {
    "ww-open-data":"plugin://contactPlugin/ww-open-data"
}

(4) 调用ww-open-data组件获取用户信息 当corpid openid type 都有值的时候再加载这个组件

<ww-open-data wx:if="{{corpid && openid && type}}" corpid="" openid="" type=""/>

参数说明:

属性 类型 必填 说明
corpid string 用户所属的企业corpid
type string 开放数据类型
openid string 数据ID,根据type取值而定

type与openid属性参考2.5 元素属性

3.3 开发调试

在开发者工具开发调试,需要用企业微信扫码运行时,需要在“添加编译模式”里的启动参数添加如下参数:debug_extinfo=true&debug_plugin=true,才能正常调起授权登录。添加方法请参考下图:


3.4 示例程序

开发者可参考 open-data 小程序 demo

4. canvas 支持方案

4.1 作用

  • 支持三方应用在 canvas 中安全渲染通讯录数据
  • 支持 echarts、antv g2 等第三方图形库,在 canvas 渲染模式下,正确渲染通讯录数据

4.2 使用方式

1 . 在完成了 WWOpenData 的初始化后,调用 initCanvas 方法

if (WWOpenData.initCanvas) {
    WWOpenData.initCanvas()
}

2 . 调用 WWOpenData 的 prefetch 方法,将需要在图形显示的名称,进行预获取。可以参考以下代码

const result = await new Promise((resolve, reject) => {
    WWOpenData.prefetch({ items }, (err, data) => {
        if (err) {
            return reject(err)
        }
        resolve(data)
    })
})

其中,itemsresult 的格式分别是:

items: [
    {
        type: string, // userType
        id: string, // openid
    }
]

result: [
    {
        type: string,
        id: string,
        data: string, // 重要,这里的数据需要传入到 canvas 图形库中
    }
]

3 . 到了这一步,已经完备了 canvas 展示通讯录数据的将, result 返回的 data,开发者可以理解成是 加密过的通讯录数据,接下来,开发者只需要把这些加密过的通讯录数据,当成正常的数据,放到 canvas 的接口 或者 第三方图形库的接口上,进行渲染即可。

4 . 一般情况下,为了避免页面受到 xss 攻击时,泄漏图片数据,默认情况下,渲染过通讯录信息的 canvas,是禁止使用 toDataUrl 导出图片的。如果确实有这样的需求,服务商可以在渲染 canvas 前,调用 WWOpenData.enableCanvasSharing 这个 api,调用后,渲染出来的 canvas 就能通过 toDataUrl 导出图片。与之相对,WWOpenData.disableCanvasSharing 这个 api 可以重新禁止 canvas 导出图片。

5. 发送应用消息支持id转译

应用在下发消息时,可以在内容中以模板参数语法包含id,企业微信在下发时会将其替换为成员名或部门名,目前支持文本/文本卡片/图文/图文(mpnews)这四种消息类型,参数使用说明具体参见“发送应用消息”,注意需要在原接口参数上添加 enable_id_trans 字段且置为1,才能开启转译.

6. 人名或部门名搜索方案

通过通讯录搜索接口,可以根据名字或拼音搜索出对应的userid或部门id。

7. 包含人名部门名的文件导出方案

先将文件通过“上传需要转译的文件”接口上传到企业微信服务端,接着调用“异步通讯录id转译”接口提交转译任务,然后通过“获取异步任务结果”获取最终下载文件的url,注意该url仅能在有用户登录态的浏览器打开以下载文件,详情参见“通讯录ID转译”。

8. 通讯录用户排序方案

通过通讯录userid排序,可以根据姓名拼音升序或者降序排列。

FAQ

  1. 页面使用了 iframe,iframe 内找不到 WWOpenData
    解决方法:针对应用页面使用了 iframe 的情况,可以通过 window.parent 的方式往最外层的 webview 访问 WWOpenData 对象

  2. agentConfig 签名一直报错
    注意点:agentConfig 的签名参数 和 wx.config 是不一样的,参考文档

  3. 第三方浏览器,其他浏览器工作正常,safari 工作不正常
    解答:由于 Safari 浏览器对 cors 策略的处理和其他浏览器不一样,在第三方浏览器上,请务必按照文档完成 wx.agentConfig 的处理

  4. 关于 jWeixin sdk 版本的处理,请注意:在企业微信上,必须引入的是 1.2.0 版本的 jWeixin sdk,在微信 或者 其他第三方浏览器,可以引入其他版本的 jWeixin sdk

  5. 单页面应用,在 windows 客户端可以渲染,但是在 iOS 客户端不能渲染
    解答:由于目前 windows 客户端 和 iOS 存在差异,为了保证各个端运行正确,请严格保证如下标准:如果单页面应用使用了 browser history 作为路由,请保证每次 url 变更后,都正常完成 wx.config 和 wx.agentConfig 初始化。

  6. 页面在浏览器,在 iOS,Mac,Android 上面的企业微信都表现正常,但是在 windows 企业微信下,会偶发不能渲染通讯录控件内容
    解答:由于 企业微信的 windows 客户端浏览器内核不支持 customElements,每次更新了 open-data 元素后,需要用 bind 或者 bindAll 接口对目标元素进行一次更新,这样才能保证 open-data 元素实时渲染正确的数据。遇到上面的情况,请检查一下页面代码,看看有没有可能出现时序问题:先执行了 bind,然后才渲染出对应的 open-data 元素

© 1998 - 2021 Tencent Inc. All Rights Reserved