Skip to content

企业微信

织信采用自建应用的模式对接企业微信,关于自建应用的说明可参考 https://open.work.weixin.qq.com/help2/pc/17693

1.在企业微信创建自建应用

创建完团队后,需要进入 应用管理 创建一个自建应用。 在新创建的应用详情页面,将参数 AgentId 和 Secret 记录下来。

2.设置可信域名与企业可信IP

  • 2.1 在企业微信后台管理中找到「应用管理中 >> 开发者接口」
  • 2.2 在网页授权及JS-SDK中配置可信域名
  • 2.3 在企业可信IP中添加服务器网络出口IP

3.织信第三方集成企业微信

在织信工作台「团队 >> 团队设置」下,找到「第三方集成」,选择「企业微信」,点击「启用此功能」,填入企业微信CorpId、AgentId 和 Secret后,点击「保存」。

设置项说明
CorpId企业微信的是企业ID,点击进入我的企业
AgentId自建应用的应用凭证中的AgentId,见上一步
Secret自建应用的应用凭证中的Secret,见上一步

4.获取织信团队ID

打开织信工作台,选择「团队 >> 团队设置」,找到「团队ID」。

5.配置企业微信应用主页

打开企业微信 >> 应用管理,在「自建应用」里找到第一步创建的应用,点击进入应用设置。 点击「应用主页 >> 设置」

6.织信团队成员设置企业微信账号ID

  • 6.1 在织信工作台「团队 >> 团队设置」下,找到「成员」,点击「编辑」按钮,打开成员编辑页面。
  • 6.2 打开企业微信通讯录 ,找到织信成员对应的企业微信成员,点击对应成员「姓名」打开成员详情,找到「帐号」(企业微信用户ID),并复制。
  • 6.3 在5.1打开的编辑织信团队成员页面里,找到「企业微信账号ID」,填入上一步复制的企业微信用户ID,并保存

7.企业微信扫码登录

  • 7.1 在织信工作台「团队 >> 团队设置 >> 登录页面」下,点击「启用团队登录页面」、「启用第三方扫码登录」。
  • 7.2 在织信工作台「团队 >> 团队设置 >> 第三方集成」下找到「企业微信」,点击「启用登录」,启用企业微信扫码登录。

需要注意,扫码登录需要给团队成员绑定企业微信账号ID

8.配置可信域名需完成域名归属认证

1.请下载文件“WW_verify_cT8pvS8MqFSkUe.txt"下载文件 2.将下载的文件上传至填写域名根目录下http://{ip}/WW_verify_cT8pvS8MqFSkUe.txt, 确保可以访问

  • 修改nginx informat-next.conf配置文件
  • 在 location ^~ /account/ 下添加如下内容:
location ^~ /account/ {
	access_log /var/log/nginx/informat_next_account_api_web.log;
	if ($request_method = 'OPTIONS') {
   		return 204;
	}
	proxy_pass http://backend_account$request_uri;
}
location /WW_verify_cT8pvS8MqFSkUe.txt {
	default_type text/plain;  
	return 200 "WW_verify_cT8pvS8MqFSkUe.txt文件内容";
}
  • 重载配置nginx配置即可
shell
nginx -s reload

9.对接钉钉同步组织架构和成员

9.1 概述

企业内部通常会使用企业微信(WeCom)作为办公沟通工具。它提供了组织架构、用户管理、消息通知等能力。 下面是对接企业微信并同步组织架构和成员到织信的步骤。

9.2 实现步骤

已完成「第三方集成 >> 企业微信」的应用集成。 应用需开通以下权限:

  • 通讯录组织架构读取权限
  • 通讯录成员基本信息(含手机号、邮箱)
  • 部门管理权限

9.3 实现代码

javascript
const defaultRole = 'normal'; // 授权给新用户的团队角色
const defaultPassword = '123456'; // 新用户设置的密码,用户名为手机号
const syncMembers = true; // 是否同步成员
let rootDeptId = null;

export function syncWechatOrg() {
    var deptList = getWechatDeptList();
    console.log("企业微信部门列表---------------->", JSON.stringify(deptList));
    
    // 获取织信平台的根部门ID
    rootDeptId = (informat.dept.queryDeptList({
        pageSize: 1,
        filter: {
            conditionList: [
                {"fieldId": "parentId", "opt": "isnull"}
            ]
        }
    })[0] || {}).id;
    console.log('织信根部门ID', rootDeptId);
    
    if (deptList != null) {
        deptList.forEach(item => {
            var dept_id = `${item.id}`;
            var dept = informat.dept.getDept(dept_id);
            console.log('处理部门ID', dept_id);
            
            if (dept == null) {
                console.log('新增部门', item);
                informat.dept.addDept({
                    'id': dept_id,
                    'name': item.name,
                    'remark': item.name || '',
                    'parentId': item.parentid === 0 || item.parentid === 1 ? rootDeptId : `${item.parentid}`
                });
            } else {
                console.log('编辑部门', item);
                informat.dept.updateDept({
                    'id': dept_id,
                    'name': item.name,
                    'parentId': item.parentid === 0 || item.parentid === 1 ? rootDeptId : `${item.parentid}`
                });
            }
        });
    }
    
    // 同步成员
    if (syncMembers) {
        syncWechatMemberList(deptList);
    }
}

function syncWechatMemberList(deptList) {
    if (Array.isArray(deptList)) {
        deptList.forEach(dept => {
            const memberList = getWechatMemberList(dept.id);
            memberList.forEach(member => {
                var memberList = informat.company.queryCompanyMemberList({
                    pageIndex: 1,
                    pageSize: 1,
                    filter: {
                        conditionList: [{
                            "fieldId": "weworkUserId",
                            "opt": "eq",
                            "value": member.userid
                        }]
                    }
                });
                
                var departmentList = getDeptIdListWithWechatDeptIdList(member.department);
                if (memberList.length == 0) { // 新增
                    var accountId = addWechatAccount(member);
                    var roleList = defaultRole == null ? [] : [defaultRole];
                    console.log('新增团队成员', member, departmentList);
                    informat.company.addCompanyMember(accountId, departmentList, roleList);
                    informat.company.updateCompanyMember({
                        id: accountId,
                        weworkUserId: member.userid,
                    });
                } else { // 编辑
                    console.log('编辑团队成员', member, departmentList);
                    var memberObj = memberList[0];
                    informat.company.updateCompanyMember({
                        id: memberObj.id,
                        departmentList: departmentList,
                    });
                }
            });
        });
    } else {
        console.log("syncWechatMemberList, deptList is not array. deptList: ", deptList);
    }
}

function getDeptIdListWithWechatDeptIdList(deptIds) {
    return deptIds.map(id => {
        if (id === 0 || id === 1) {
            return rootDeptId;
        }
        return `${id}`;
    });
}

function getWechatMemberList(dept_id) {
    var accessToken = informat.app.wechatAccessToken();
    var url = `https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=${accessToken}&department_id=${dept_id}&fetch_child=0`;
    var rs = httpGet(url);
    
    if (rs.errcode === 0) {
        return rs.userlist || [];
    }
    return [];
}

function getWechatDeptList() {
    var accessToken = informat.app.wechatAccessToken();
    var url = `https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=${accessToken}&id=`;
    var rs = httpGet(url);
    
    if (rs.errcode === 0) {
        return rs.department || [];
    }
    return [];
}

function addWechatAccount(item) {
    var mobile = item.mobile;
    if (mobile == null) {
        throw new Error('员工手机号不能为空,请开放查看手机权限');
    }
    
    var accountList = informat.system.queryAccountList({
        pageIndex: 1,
        pageSize: 1,
        filter: {
            conditionList: [
                {
                    fieldId: 'mobileNo',
                    opt: 'eq',
                    value: mobile
                }
            ]
        }
    });
    
    var accountId = null;
    if (accountList.length == 0) { // 账号不存在
        console.log('新增账号', item);
        accountId = informat.system.addAccount({
            oid: item.userid,
            name: item.name,
            avatar: 'pic15.png',
            userName: mobile,
            mobileNo: mobile,
            email: item.email || '',
            password: defaultPassword
        });
    } else {
        var oldAccount = accountList[0];
        accountId = oldAccount.id;
        console.log('编辑账号', item, oldAccount);
        informat.system.updateAccount({
            id: oldAccount.id,
            name: item.name,
            userName: mobile,
            mobileNo: mobile
        });
    }
    return accountId;
}

function httpGet(url) {
    console.log("企业微信API请求URL----------------->", url);
    var resp = informat.http.request({
        headers: {
            "Content-Type": "application/json;charset=utf-8"
        },
        method: "GET",
        timeout: 30000,
        url: url
    });
    
    if (200 != resp.statusCode()) {
        console.log('请求失败,状态码:', resp.statusCode());
        console.log('响应体:', resp.body());
        throw new Error('发起企业微信API请求失败,请联系开发人员');
    }
    
    var result = JSON.parse(resp.body());
    console.log("企业微信API响应----------->", JSON.stringify(result));
    return result;
}

9.4 常见错误