nodejs 开发企业微信第三方应用入门教程

最近公司要开发企业微信端的 Worktile,以前做的是企业微信内部应用,所以只适用于私有部署客户,而对于公有云客户就无法使用,所有就准备开发企业微信的第三方应用,本文主要介绍在调研阶段遇到的山珍海味。

开发之前你需要前注册为第三方服务商,然后用第三方服务商的账号创建应用,创建之后只需要管理员授权应用,第三方服务商即可为用户提供服务。

一、注册第三发服务商

登陆服务商官网,注册成为服务商,并登陆服务商管理后台。

二、配置开发信息

在创建应用之前,首先要配置好通用开发参数

20190312111602.png

在填写系统事件接收 url 时,要正确响应企业微信验证 url 的请求。这个可以参考企业微信后台,自建应用的接收消息的 api 设置。
在企业的管理端后台,进入需要设置接收消息的目标应用,点击“接收消息”的“设置API接收”按钮,进入配置页面。

20190225120700.png

要求填写应用的 URL、Token、EncodingAESKey 三个参数

  • URL 是企业后台接收企业微信推送请求的访问协议和地址,支持 http 或 https 协议(为了提高安全性,建议使用 https)。
  • Token 可由企业任意填写,用于生成签名。
  • EncodingAESKey 用于消息体的加密,是 AES 密钥的 Base64 编码。

2.1 验证 url 有效性

当点击保存的时候,企业微信会发生一条 get 请求到填写的 url

比如 url 设置的是https://api.worktile.com, 企业微信将发送如下验证请求:

请求地址:https://api.worktile.com/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS×tamp=13500001234&nonce=123412323&echostr=ENCRYPT_STR

参数说明msg_signature企业微信加密签名,msg_signature 结合了企业填写的 token、请求中的 timestamp、nonce 参数、加密的消息体timestamp时间戳nonce随机数echostr加密的字符串。需要解密得到消息内容明文,解密后有random、msg_len、msg、receiveid 四个字段,其中 msg 即为消息内容明文

2.1.1 通过参数 msg_signature 对请求进行校验

首先要把刚才配置时随机生成的 token, timestamp, nonce, msg_encrypt 进行 sha1 加密,这里我们可以直接使用 npm 模块 sha1 进行加密,然后判断得到的 str 是否和 msg_signature 相等。

function sha1(str) {
  const md5sum = crypto.createHash('sha1');
  md5sum.update(str);
  const ciphertext = md5sum.digest('hex');
  return ciphertext;
}
function checkSignature(req, res, encrypt) {
  const query = req.query;
  console.log('Request URL: ', req.url);
  const signature = query.msg_signature;
  const timestamp = query.timestamp;
  const nonce = query.nonce;
  let echostr;
  console.log('encrypt', encrypt);
  if (!encrypt) {
    echostr = query.echostr;
  } else {
    echostr = encrypt;
  }
  console.log('timestamp: ', timestamp);
  console.log('nonce: ', nonce);
  console.log('signature: ', signature);
  // 将 token/timestamp/nonce 三个参数进行字典序排序
  const tmpArr = [token, timestamp, nonce, echostr];
  const tmpStr = sha1(tmpArr.sort().join(''));
  console.log('Sha1 String: ', tmpStr);
  // 验证排序并加密后的字符串与 signature 是否相等
  if (tmpStr === signature) {
    // 原样返回echostr参数内容
    const result = _decode(echostr);
    console.log('last', result);
    console.log('Check Success');
    return result;
  } else {
    console.log('Check Failed');
    return 'failed';
  }
}
2.1.2 解密 echostr 得到 msg 并返回

密文解密过程:

  1. 对刚才生成的 AESKey 进行 base64 解码
const EncodingAESKey = '21IpFqj8qolJbaqPqe1rVTAK5sgkaQ3GQmUKiUQLwRe';
let aesKey = Buffer.from(EncodingAESKey + '=', 'base64');
  1. 对 AESKey 进行 aes-256-cbc 解密
function _decode(data) {
  let aesKey = Buffer.from('21IpFqj8qolJbaqPqe1rVTAK5sgkaQ3GQmUKiUQLwRe' + '=', 'base64');
  let aesCipher = crypto.createDecipheriv("aes-256-cbc", aesKey, aesKey.slice(0, 16));
  aesCipher.setAutoPadding(false);
  let decipheredBuff = Buffer.concat([aesCipher.update(data, 'base64'), aesCipher.final()]);
  decipheredBuff = PKCS7Decoder(decipheredBuff);
  let len_netOrder_corpid = decipheredBuff.slice(16);
  let msg_len = len_netOrder_corpid.slice(0, 4).readUInt32BE(0);
  const result = len_netOrder_corpid.slice(4, msg_len + 4).toString();
  return result; // 返回一个解密后的明文-
}
function PKCS7Decoder (buff) {
  var pad = buff[buff.length - 1];
  if (pad < 1 || pad > 32) {
    pad = 0;
  }
  return buff.slice(0, buff.length - pad);
}
  1. 然后返回 result 即可
res.end(result);

2.2 回调 url 验证失败问题

验证 URL 时,经常会碰到 URL 验证失败的问题,解决思路是借助微信企业号接口调试工具

三、创建应用

20190228143529.png

四、测试应用

应用创建成功后,服务商可以授权 10 个测试企业

20190225143525.png

从企业微信应用市场发起授权时,企业微信给刚才应用设置的指令回调 url 发送一个 post 请求,比如:
https://api.worktile.com/worktile?msg_signature=b99605616153ffbfbe6ebbb500bd211e67ed714d&timestamp=1551076894&nonce=1551709703,直接返回成功即可。

各个事件的回调,服务商在收到推送后都必须直接返回字符串 “success”,若返回值不是 “success”,企业微信会把返回内容当作错误信息。

app.post('/worktile', function (req, res) {
  console.log('req.body', req.body);
  res.send('success');
});

测试应用注意事项

  1. 用于安装测试的企业微信帐号需服务商自行注册,每个应用支持同时添加 10 个测试企业微信账号
  2. 安装测试的企业微信帐号使用的是当前的应用配置信息,后续的修改不会进行同步;如需更新应用信息请重新授权安装
  3. 同一企业微信帐号,不支持同时安装测试应用和正式发布的应用

五、应用上线

已认证企业微信的服务商,可进入应用管理—点击提交上线—勾选应用—提交上线。

六、用户网页授权登录

6.1 构造第三方应用网页授权链接

如果第三方应用需要在打开的网页里面携带用户的身份信息,名列前茅步需要构造如下的链接来获取 code:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

参数必须说明appid是第三方应用 id(即 ww 或 wx 开头的 suite_id)。注意与企业的网页授权登录不同redirect_uri是授权后重定向的回调链接地址,请使用 urlencode 对链接进行处理 ,注意域名需要设置为第三方应用的可信域名response_type是返回类型,此时固定为:codescope是应用授权作用域。snsapi_base:静默授权,可获取成员的基础信息(UserId与DeviceId);snsapi_userinfo:静默授权,可获取成员的详细信息,但不包含手机、邮箱等敏感信息;snsapi_privateinfo:手动授权,可获取成员的详细信息,包含手机、邮箱等敏感信息。state否重定向后会带上 state 参数,企业可以填写 a-zA-Z0-9 的参数值,长度不可超过 128 个字节#wechat_redirect是终端使用此参数判断是否需要带上身份信息

auth.png

企业员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,第三方应用可根据 code 参数获得企业员工的 corpid 与 userid。code 长度最大为 512 字节。

6.2 获取访问用户身份

请求方式:GET(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/service/getuserinfo3rd?access_token=SUITE_ACCESS_TOKEN&code=CODE

参数必须说明access_token是第三方应用的 suite_access_token,参见“获取第三方应用凭证”code是通过成员授权获取到的 code,最大为 512 字节。每次成员授权带上的 code 将不一样,code 只能使用一次,5 分钟未被使用自动过期。

6.2.1 获取第三方应用的 suite_access_token

请求方式:POST(HTTPS)
请求地址: https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token

参数是否必须说明suite_id是以 ww 或 wx 开头应用 id(对应于旧的以 tj 开头的套件 id)suite_secret是应用 secretsuite_ticket是企业微信后台推送的 ticket

由于第三方服务商可能托管了大量的企业,其安全问题造成的影响会更加严重,故 API 中除了合法来源 IP 校验之外,还额外增加了 suite_ticket 作为安全凭证。
获取 suite_access_token 时,需要 suite_ticket 参数。suite_ticket 由企业微信后台定时推送给“指令回调 URL”,每十分钟更新一次,见推送 suite_ticket
suite_ticket 实际有效期为 30 分钟,可以容错连续两次获取 suite_ticket 失败的情况,但是请永远使用最新接收到的 suite_ticket。
通过本接口获取的 suite_access_token 有效期为 2 小时,开发者需要进行缓存,不可频繁获取。

6.2.2 获取推送 suite_ticket

企业微信服务器会定时(每十分钟)推送 ticket。ticket 会实时变更,并用于后续接口的调用。
请求方式:POST(HTTPS)
请求地址:https://api.ninesix.cc/worktile?msg_signature=87276aaf15a13e1eb2ebb6d93732ca668c3ddef8&timestamp=1551850300&nonce=1551051655

在发生授权、通讯录变更、ticket 变化等事件时,企业微信服务器会向应用的“指令回调 URL”推送相应的事件消息,nodejs 接收到的是 xml,解析后拿到 encrypt 字段,然后使用上面配置通用开发参数的 url 时用的解密方式,就可以得到 suite_ticket。

20190306153526.png

6.3 获取用户敏感信息

请求方式:POST(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/service/getuserdetail3rd?access_token=SUITE_ACCESS_TOKEN

{
   "user_ticket": "USER_TICKET"
}

参数必须说明access_token是第三方应用的 suite_access_token,参见“获取第三方应用凭证”user_ticket是成员票据

返回结果:

{
   "errcode": 0,
   "errmsg": "ok",
   "corpid": "wwxxxxxxyyyyy",
   "userid": "lisi",
   "name": "李四",
   "mobile": "15913215421",
   "gender": "1",
   "email": "xxx@xx.com",
   "avatar": "http://shp.qpic.cn/bizmp/xxxxxxxxxxx/0",
   "qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcfc13b01dfs78e981c"
}

七、用户授权成功

首页

home.png

详情页

task-detail.png

八、给用户发消息

我们可以给推送文本、图片、视频、文件、图文等类型。

请求方式:POST(HTTPS)
请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN

推送的时候需要 access_token 和 应用的 agentId,第三方服务商,可通过接口 获取企业授权信息 获取该参数值,其实可以直接通过 获取企业永久授权码直接取到这两个值。

在我们测试安装应用成功之后,企业微信会 post 一条请求给指令回调 URL,通过上面的解密方式,可以解析到 xml 中的 auth_code

20190306190621.png

然后通过https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=SUITE_ACCESS_TOKEN和 auth_code 可以获取到 access_token 和 agentId,返回的 agent 是一个数组,但仅旧的多应用套件授权时会返回多个agent,对新的单应用授权,永远只返回一个 agent。

再通过 access_token 和 agentId 就可以愉快的给用户发送消息了。

WechatIMG5.jpg

当点击链接时,可以跳到指定任务或者日程等,只不过返回时还是在企业微信的消息模块,并不能自动打开第三方应用,客服回复不支持这么做。

九、注意事项

文章标题:nodejs 开发企业微信第三方应用入门教程,发布者:刘佳,转载请注明出处:https://worktile.com/kb/p/6520

(1)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
刘佳刘佳认证作者
上一篇 2022年3月20日 上午1:27
下一篇 2022年3月20日 上午1:31

相关推荐

  • 教程:如何管理技术债务以维护研发效能

    管理技术债务以维护研发效能的教程:1、识别技术债务;2、量化技术债务;3、制定偿还计划;4、实施技术债务解决方案;5、避免未来的技术债务;6、监控和反馈;7、文化和意识;8、利用工具和自动化;9、持续改进。技术债务的管理是一个持续的过程,它要求团队对现有问题保持透明、积极寻找解决方案,并且不断学习和改进。

    2023年11月12日
    27800
  • 看板管理的原则是什么

    看板管理的原则是:1.后道工序的领取原则;2.前道工序的生产原则;3.不良品不送往后工序;4.均匀领取零部件原则;5.看板使用量减少原则;6.依赖看板进行作业原则。看板管理是一种生产的微调手段,它能够使各生产工序稳定化和合理化。 1.后道工序的领取原则 后道工序只在必要的时刻,才从前道工序领取必要数…

    2022年11月24日
    98400
  • 三菱plc用什么编程软件

    三菱PLC主要使用GX Developer、GX Works2和GX Works3编程软件。这些软件支持三菱PLC系列的程序设计、调试和维护工作。GX Developer是较早的软件版本,适用于小型控制器的简单应用程序开发;GX Works2和GX Works3则是较新且功能更为强大的工程软件,它们…

    2024年4月26日
    300
  • oa男装是什么牌子

    OA男装 是一家专注于现代都市男性时尚的品牌,它致力于打造既适合商务场合又能满足休闲时刻的服饰。初步了解显示,OA可能并不是一个全球知名度极高的品牌,它更多可能是一个定位于中高端市场的品牌,渴望为男性顾客提供既有品味又不失舒适度的服装选择。OA男装 主要的产品线包括但不限于正装、休闲装、外套、配饰等…

    2024年1月11日
    1.4K00
  • 团队管理需要有哪些能力

    团队管理应具备以下能力:1、沟通能力;2、协调能力;3、规划与统整能力;4、决策与执行能力;5、培训能力;6、统驭能力。团队就是一群人为了共同的目标集结在一起相互协作,而作为团队管理者要想带好团队,让大家拧成一股绳朝着目标努力。 一、沟通能力 为了了解组织内部员工互动的状况,倾听职员心声,一个管理者…

    2022年11月6日
    4.1K00
  • ChatGPT在机器人工程中的应用前景有多大

    聊天机器人技术ChatGPT在机器人工程中扮演关键角色,展现了巨大的应用前景。1、增强人机交互体验:通过自然语言处理能力,ChatGPT能够提供更直观、自然的人机对话接口。2、促进自主学习与适应性:ChatGPT的自我学习能力有助于机器人在未知环境中的表现。3、提供决策支持:通过理解复杂指令,Cha…

    2023年12月6日
    36400
  • oa协同办公系统推荐

    OA协同办公系统推荐包括流程自动化、高度可定制性、数据安全性、良好的用户体验、易于集成其他应用五个关键因素。其中,流程自动化尤为关键因为它能显著提高工作效率,减少手动错误,并加快决策过程。 流程自动化:OA系统应可以实现审批流程的自动化、任务分配、和跟踪。例如,当一个员工提交请假申请时,系统自动将申…

    2024年1月15日
    26500
  • 校园办公自动化系统

    校园办公自动化系统的设计意图在于提升教育机构行政效率、简化日常事务处理、增强数据处理的准确性。该系统包含多个核心模块:文档管理、学生信息系统、考勤追踪、资源调配和财务管理。重点在于学生信息系统,它整合并维护学生的个人资料、成绩记录以及其他学习相关信息,为教师、家长和学生本身提供快速而准确的数据存取服…

    2024年1月15日
    21700
  • edge dev版有什么区别

    Microsoft Edge Dev版与其他版本的区别有:1.更新频率和稳定性不同;2.新功能和测试环境不同;3.目标用户和使用场景不同。Microsoft Edge Dev版的目标用户主要针对开发者、测试人员和技术爱好者,适合开发者测试新功能和与即将发布的Web标准的兼容性。其他版本如Stable…

    2023年8月9日
    2.1K00
  • 项目部员工如何管理工作

    项目部员工可以通过制定明确目标、优化沟通机制、时间管理、技能提升、使用工具和技术、强化团队合作等方式高效管理自己的工作。在这些策略中,优化沟通机制是至关重要的一环,它涉及到如何有效地与团队沟通任务进度、解决问题以及分享信息。沟通机制的优化可以提高项目部门的协同工作效率,减少误会和冲突,保证项目顺利进…

    2024年4月11日
    5800

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部