由于团队人比较懒,不是经常关注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