写点什么

【玩转云函数】打通 Github 到企微的消息通知

作者:小鑫同学
  • 2022-10-13
    北京
  • 本文字数:2566 字

    阅读完需:约 8 分钟

【玩转云函数】打通Github到企微的消息通知

大家好,我是小鑫同学。一位从事过 Android 开发混合开发,现在长期从事前端开发的编程爱好者,我觉得在编程之路上最重要的是知识的分享,所谓三人行必有我师。所以我开始在社区持续输出我所了解到、学习到、工作中遇到的各种编程知识,欢迎有想法、有同感的伙伴加我fe-xiaoxin微信交流~

     在昨天 18 号的团队内部知识分享会上同事将近期为团队工程化所做的企微机器人做了详细的分享,主要是每天会有不少的时间都是在处理 Merge 或在找同事 Merge 的路上,为了优化这块的时间我们同事使用 NodeJs 开发服务来连接内部使用的工蜂平台和企微平台,做到自动发送和提醒对应的同事来做代码评审,当评审通过后主动通知发起人来完成合并。

那么我想做什么?

     在之前我写了一篇《【Serverless版】企微群机器人开发》,主要是通过定时主动去拉取请求来解析后再通知到企微机器人,这次我就想利用腾讯云函数来做服务打通 Github 到企微的消息通知,这样就进一步扩展了我们对云函数的认识,那我们就做起来吧。


     本次的案例我们需要准备创建 GitHub 演示项目,腾讯云函数和一个企微机器人,当有用户新增一条评论时可以通知到企微群的管理人员。


为演示项目配置 Webhooks:

演示的 Github 项目自行创建不做要求,Webhook 允许在指定的事件发生时向我们预先配置的 url 接口发送 POST 请求。


  1. 菜单位置:演示项目/Settings/Webhooks;

  2. 点击 Add webhook 开始配置;

  3. 配置信息包括:

  4. 请求地址,可以等创建好云函数后再配置;

  5. 内容格式:选择目前最通用的 Json 数据传输;

  6. 安全密钥:配置一个随机密钥,可以通过工具生成长度 32 位,云函数对数据验证时会使用;

  7. 选择事件:勾选Let me select individual events.选择 Issue comments。

  8. 事件文档: webhook-events-and-payloads

开发云函数:

创建云函数:

     这次我们为了节省时间就基于模板来创建云函数,选择 Express 框架模版,函数名称我们指定为【github-webhook-issues-comments】来与其已有函数区分。



检测服务连通性:

     创建后切换到触发管理菜单就能看到服务的访问路径了,默认的模板提前创建好了默认页面路由,/logo 路由,/user 路由,/user/:id 路由,/404 路由和/500 路由,我们都可以访问试一下效果,我们除了保留默认路由来检查服务是否正常外其他的路由可以考虑删除掉。


     打开首页看到“欢迎访问 Express.js 应用腾讯云 Serverless 为您提供服务”就说明服务已经正常启动了。


配置/Webhook 路由:

  1. 我们预定路由为/webhook,接收请求的方式为POST,接收的内容格式为JSON,这时候我们就可以去 GitHub 的 Webhook 去填写信息了。



  1. 通过云端编辑器来新增/webhook 路由,具体实现暂时不做,我们想通过在 Github 提交一次 Issues 来验证连通性。


app.post(`/webhook`, (req, res) => {  res.send({code: 200});});
复制代码


在 Github 上查看请求日志:


实现/Webhook 路由:

  1. 为了调试(本地)方便,我们最好是将云端代码下载后在本地的 VSCode 中编写,拉取代码后就可以通过nodemon ./app.js启动服务,服务默认端口为9000且在云端函数中不允许修改,这个需要特别注意;



  1. 还记得我们在 Github 配置 Webhook 配置的安全密钥吗?为了保证数据的安全,我们需要在云函数中使用相同的密钥来验证数据的有效性(GitHub文档)。


app.post(`/webhook`, (req, res) => {  const signature = req.headers["x-hub-signature-256"];  if (signature) {    const payload = req.body;    const ret = verify(signature, payload);    // 输出验证结构    console.log("[ ret ] >", ret);  }  res.send({ code: 200 });});
复制代码


const crypto = require("crypto");const SECRET_TOKEN = "";
function sign(data) { return `sha256=${crypto .createHmac("sha256", SECRET_TOKEN) .update(JSON.stringify(data)) .digest("hex")}`;}
module.exports = { verify: (signature, data) => { const sig = Buffer.from(signature); const signed = Buffer.from(sign(data)); if (sig.length !== signed.length) { return false; } return crypto.timingSafeEqual(sig, signed); },};
复制代码


说明:
* 因为很少做加解密所以一开始设置的16位秘钥使得两次加密结果不相同,花费的很长时间,所以注意需要设置最少32位秘钥,有了解这块的XD可以给解释一下😘。* 秘钥建议是存到服务器的环境变量中,禁止直接存储到代码中。
复制代码


  1. 通过查阅Github文档来确定我们下面需要拼装信息的字段,我将代码放到下方就不对字段做解释了,更多的字段内容可查询文档:



packaging: (issue, comment, repository, sender) => {    return `**有一条新的评论**:\n    用户[${sender.login}](${sender.html_url})在【[${issue.title}](${issue.html_url})】主题下新增了一条评论,说[${comment.body}](${comment.html_url}),请注意查看!\n\n**所属项目**:<font color="info">[${repository.name}](${repository.html_url})</font>\n**评论时间**:<font color="comment">${comment.updated_at}</font>\n    `;},
复制代码


  1. 再次改造/webhook 路由,支持向企微机器人发送消息,企微机器人的配置和发送请看上一篇《【Serverless版】企微群机器人开发》,源码丢失了,云端的代码需要的可以留言联系:


if (verify(signature, payload)) {  const { action, issue, comment, repository, sender } = payload;  if (action === "created") {    const content = packaging(issue, comment, repository, sender);    notice.requestMDNotice(config.ENTERPRISE_WECHAT_ROBOT_WEB_HOOK, {      content,    });  }}
复制代码


我们在企微中就可以收到下面的卡片信息了:


同步本地代码到云端步骤:

  1. 选择本地代码根文件夹:



  1. 点击部署开始上传:



  1. 代码部署上传中:



  1. 检测到与现部署的不一致需要重新发布:



  1. 在 Github 创建 Issuse 后可通过云端日志查询的到正确反馈:


总结:

     我们通过在 Github 上配置 WebHook 监听 Issuse 评论的事件,当事件发生后将按照固定格式发送消息到我们创建的腾讯云函数中,在验证数据的合法性后解析报文并组装卡片转发到企微机器人。在开发中遇到了很少使用的 Hmac256 加密耽误的时间最长,原因是秘钥长度不够导致。不知道这一篇的云函数开发有没有讲的明白呢?🤔




欢迎关注我的公众号“前端小鑫同学”,原创技术文章第一时间推送。


发布于: 刚刚阅读数: 3
用户头像

小鑫同学

关注

⚡InfoQ签约作者 2018-12-10 加入

还未添加个人简介

评论

发布
暂无评论
【玩转云函数】打通Github到企微的消息通知_前端_小鑫同学_InfoQ写作社区