第三方应用开发 服务端API 通讯录管理 通讯录展示组件
通讯录展示组件

目录

  •       1. 背景介绍
  •       2. 浏览器方案
  •             2.1 环境要求
  •             2.2 使用方法
  •             2.3 API 列表
  •             2.4 事件列表
  •             2.5 元素属性
  •             2.6 前端框架适配
  •             2.7 示例代码
  •       3. 小程序方案
  •             3.1 环境要求
  •             3.2 使用方法
  •             3.3 开发调试
  •             3.4 示例程序
  •       4. canvas 支持方案
  •             4.1 作用
  •             4.2 使用方式
  •       5. 发送应用消息支持id转译
  •       6. 人名或部门名搜索方案
  •       7. 包含人名部门名的文件导出方案
  •       8. 通讯录用户排序方案
  • FAQ
  • 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

    无论是微信、企业微信的内置浏览器还是第三方浏览器,都需要通过wx.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 元素属性](#17172/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 事件列表](#17172/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 元素上的属性控制需要渲染的内容:

    属性类型必填说明
    typestring开放数据类型
    openidstring数据ID,根据type取值而定
    corpidstring企业ID,用户所属的企业 corpid
    假设有上下游企业 A 和 B, 开发者需要在页面同时渲染 A和B的通讯录数据,这时可以通过填入特定企业的 corpid,去指定要渲染的企业数据

    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=""/>

    参数说明:

    属性类型必填说明
    corpidstring用户所属的企业corpid
    typestring开放数据类型
    openidstring数据ID,根据type取值而定
    type与openid属性参考[2.5 元素属性](#17172/2.4 元素属性)
    假设有上下游企业 A 和 B, 开发者需要在页面同时渲染 A和B的通讯录数据,这时可以通过填入特定企业的 corpid,去指定要渲染的企业数据

     

    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
    		corpid: string, // corpid (非必须)
    	}
    ]
    
    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 元素
    7. 如何自定义显示内容,比如表单需要显示“提交人+提交日期+业务类型”?
      将需要替换通讯录名称的文本替换为ww-open-data标签引用,其它保留不变。比如,
      <ww-open-data type="userName" openid="{{openid}}"></ww-open-data>+提交日期+业务类型

    8. 通讯录展示组件,是否可以一次性显示多个名称?
      组件的每个ww-open-data标签引用对应到一个通讯录名称,显示多个名称,则引用多个ww-open-data。比如,显示完整的部门路径,只需要将路径的部门id依次引用即可。
    9. 第三方管理端,如何实现成员搜索?
      调用接口:通讯录搜索,传入搜索的关键词,获取搜索结果的userid/departmentid。
      再调用通讯录展示组件,显示出搜索的成员名称/部门名称。
    10. 如何实现搜索后的结果按拼音排序?
      调用接口:通讯录userid排序,支持指定的用户列表按拼音升序/降序,返回的结果为排序后的列表。
    11. 第三方管理端,导入业务数据文件(如打卡记录),包括了通讯录名称,如何识别?
      如果业务数据文件中记录中有唯一字段标识,则可以直接对应关联;
      如果通过通讯录名称关联用户,调用 通讯录搜索 接口,获取搜索结果的userid/departmentid,对应关联到用户
    12. 第三方管理端,支持导出业务数据文件(如打卡列表),需要包含通讯录名称,如何实现?
      解决方案参考:通讯录ID转译。以模板参数填入数据文件中,并上传至企业微信后台,数据文件中的模板参数就会替换为通讯录名称,并获取到一个文件访问地址。
      该文件访问地址,需要用户通过企业微信登录至第三方管理端,才可下载。
    13. 页面请求数据报错403

      通常是由于用户未登录至第三方业务页面导致,可以访问 open-data 调试页面 查看登录信息。
      注意,在单点登录的场景(包括有扫码登录,应用安装完成跳转,以及从企业微信Web管理端业务跳转),在指定的redirect_uri的域名,才会有登录用户身份。
      比如,扫码登录后跳转到域名A,在域名B下使用组件,是会报错403的。
    14. 已删除的成员或部门,是否能通过通讯录组件展示名字
      可以。对于同一个userid或部门ID,企业微信仅展示最后一个删除的成员或部门的名字;删除之后再重新添加相同的userid或部门ID,则只展示新成员或新部门的名字。(注:部门名仅支持展示2021年10月1号之后删除的部门)
    上一篇
    异步任务完成通知
    下一篇
    通讯录搜索