由于团队人比较懒,不是经常关注TFS的Web门户,CI/CD设置了邮件通知但也不会经常去看邮件。
最近看到企业微信上开放了一个群聊机器人API,挺简单的不用获取Token,觉得可以做个通知插件,于是便动手了。
企业微信机器人API:https://work.weixin.qq.com/api/doc?notreplace=true#90000/90135/91760
前期准备
VSCode、NodeJS、TypeScript
以上的东西码农们基本都有
然后就是要装一个 TFS Cross Platform Command Line Interface (tfx-cli)
npm i -g tfx-cli
开始动手
首先新建文件夹,再到文件夹下执行
npm init
初始化一个npm项目
接着添加一下引用库和相关的TypeScript定义,顺便初始化tsc
#添加库 npm install azure-pipelines-task-lib --save #添加TypeScript定义 npm install @types/node --save-dev npm install @types/q --save-dev #初始化tsc tsc --init
之后注意把 tsconfig.json 的 es5 改为 es6
定义一个任务
task.json
{ "id": "dd3a7ed0-5a5e-446a-8617-e463af51e3ff", "name": "往企业微信发送消息", "friendlyName": "通过Webhook机器人往企业微信群发送消息", "description": "通过Webhook机器人往企业微信群发送文本消息", "helpMarkDown": "", "category": "Utility", "author": "算神", "version": { "Major": 0, "Minor": 1, "Patch": 0 }, "instanceNameFormat": "通过Bot往企业微信群发送 $(content)", "inputs": [ { "name": "key", "type": "string", "label": "Key", "defaultValue": "", "required": true, "helpMarkDown": "企业微信机器人Key" }, { "name": "content", "type": "string", "label": "Content", "defaultValue": "", "required": true, "helpMarkDown": "文本内容" } ], "execution": { "Node": { "target": "index.js" } } }
其中 inputs 节点下的 key 和 content 就是 两个可输入的参数
撸码
准备工作完成后,可以开始撸码了。代码也很简单,就是一段NodeJS的Post Json代码,新建 index.ts
import tl = require('azure-pipelines-task-lib/task'); import https = require('https'); async function run() { try { const key: string = tl.getInput('key', true); const content: string = tl.getInput('content', true); var data = { msgtype: "text", text: { content: content } }; var json = JSON.stringify(data); var options = { host: 'qyapi.weixin.qq.com', port: 443, path: '/cgi-bin/webhook/send?key=' + key, method: 'POST', json: true, headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(json) } } var req = https.request(options, res => { res.setEncoding('utf8'); }); req.on('error', e => { console.log('problem with request: ' + e.message); tl.setResult(tl.TaskResult.Failed, e.message); }); req.write(json, 'utf8'); req.end(); } catch (err) { tl.setResult(tl.TaskResult.Failed, err.message); } } run();
由于上面task.json配置了参数,所以这里可以通过 tl.getInput() 把参数读进来
编译
执行
tsc
可把 index.ts 编译为 index.js
发布
新建一个插件的元数据文件,vss-extension.json
{ "manifestVersion": 1, "id": "wechat4work", "name": "WeChat Of Work", "version": "0.1.3", "publisher": "lishewen", "targets": [ { "id": "Microsoft.VisualStudio.Services" } ], "description": "往企业微信发送消息", "categories": [ "Azure Pipelines" ], "icons": { "default": "images/wechatofwork.png" }, "files": [ { "path": "wechat4work" } ], "contributions": [ { "id": "custom-wechat4work-task", "type": "ms.vss-distributed-task.task", "targets": [ "ms.vss-distributed-task.tasks" ], "properties": { "name": "wechat4work" } } ], "galleryFlags": [ "Public" ], "content": { "details": { "path": "overview.md" } }, "screenshots": [ { "path": "screenshots/screen1.png" }, { "path": "screenshots/screen2.png" }, { "path": "screenshots/screen3.png" } ], "links": { "home": { "uri": "http://blog.lishewen.com/" }, "repository": { "uri": "https://github.com/lishewen/WeChat4Work-VSS-Extension" }, "issues": { "uri": "https://github.com/lishewen/WeChat4Work-VSS-Extension/issues" } }, "repository": { "type": "git", "uri": "https://github.com/lishewen/WeChat4Work-VSS-Extension" } }
然后执行指令
tfx extension create --manifest-globs vss-extension.json
便可把撸的代码打包为vsix,上传发布
成果展示
项目成品地址:https://marketplace.visualstudio.com/items?itemName=lishewen.wechat4work
项目开源地址:https://github.com/lishewen/WeChat4Work-VSS-Extension