假设你有这么一个任务:
你需要将 Jira
上的任务定时同步到 Microsoft Teams
上,并提醒相关的负责人当前的任务。
举个例子:在每个工作日(周一到周五)早上 10 点钟 01 分 01 秒
的时候,通过机器人发送一条消息到你所在团队的 channel 上,并 @ 相关的任务负责人员。
相关解析:
- Jira Software 专为软件团队中每个成员构建,可用于规划、跟踪和发布卓越的软件。
- Microsoft Teams 微软协助沟通软件。
- channel: 团队的频道,一个团队可以有多个频道。
基础工作
我们要实现一个服务,作为一个前端切图仔,我们选用nodejs来开发。这里选用了Koa框架。
因为实现的功能比较简单,不涉及到前端的开发,所以这里不进行前端技术的选型。
后台的开发涉及到获取 Jira
的数据,我们直接使用相关的包 jira-client 来获取。
综上,你只需要安装的关键包文件如下:
代码语言:javascript复制npm install koa // nodejs 框架
npm install jira-client // 获取 jira 数据
npm install aixos // http 库
npm install node-cron // 定时任务处理
# 或
npm install koa jira-client axios node-cron
从 Jira 获取数据
我们只是 Jira 数据的搬运工,jira-client 文档 已经详细介绍了我们能够通过何种方式获取到相关数据。
比如:
代码语言:javascript复制/**
* 删除指定 Jira 的 Issue
* [Jira Doc](http://docs.atlassian.com/jira/REST/latest/#id290791)
* @name deleteIssue
* @function
* @param { string } issueId - 要删除的 Issue 的 Id
*/
deleteIssue(issueId) {
return this.doRequest(this.makeRequestHeader(this.makeUri({
pathname: `/issue/${issueId}`
}), {
method: 'DELETE',
followAllRedirects: true
}))
}
当然,我们要实现的是查询的任务,使用的是 searchJira
方法。
我们对 jira-client
包提供的方法封装如下:
import JiraApi from 'jira-client';
// jira-client 实例
const instance = new JiraApi({
protocol: config.jira.protocol,
host: config.jira.host,
username: config.jira.username,
password: config.jira.password,
apiVersion: config.jira.apiVersion,
strictSSL: config.jira.strictSSL
})
// 搜索 Jira
export.searchJira = async (ctx, next) => {
let ctx_query = ctx.query
try {
const issue = await instance.searchJira(ctx_query.searchString, {
maxResult: 1
});
ctx.body = {
success: true,
data: issue
}
} catch (err) {
ctx.body = err
}
await next()
}
// searchString 这个字段是 Jira 查询条件,比如:project in (Project1, Project2) AND resolution = Unresolved ORDER BY priority DESC, updated DESC 。 这些查询的内容可以在 Jira 中自行调整后在请求 url 上的 searchString 字段上带上就好。
通过上面的操作,你可以获取到相关 Jira
的 Issues
数据,如下:
卡片数据组装
上面我们能够成功获取到了 Jira
上的数据,那么我们把获取到的数据进行美化,组装成相应的卡片。
详细的格式卡可戳链接了解详情。
因为我们需要 @任务的负责人
,所以我们选择的卡片类型是 adaptive-card。
const body_list = [];
const msteams_entities = [];
body_list.push({
"type": "TextBlock",
"text": `<at>${_item.username}</at> 当前任务`,
"weight": "bolder",
"wrap": true
}, {
"type": "TextBlock",
"text": `到期任务: ${personalOverdueIssuesCount}`,
"wrap": true,
"color": `${personalOverdueIssuesCount >= 1 ? "attention" : "default"}`
});
msteams_entities.push({
"type": "mention",
"text": `<at>${_item.username}</at>`,
"mentioned": {
"id": `${_item.email}`,
"name": `${_item.display_name}`
}
})
let postMoreLink = `${config.jira.jira_hostname}/issues/?jql=${encodeURIComponent(`resolution = Unresolved AND assignee in (${_item.username}) ORDER BY priority DESC, duedate ASC`)}`;
const page_json = {
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"body": body_team_list,
"actions": [
{
"type": "Action.OpenUrl",
"url": postMoreLink,
"title": "详情"
}
],
"msteams": {
"width": "Full",
"entities": msteams_team_entities
}
}
}]
};
为了很好地兼容移动端和pc端,请选用文档支持的属性,不可自己编写相关的 markdown 进行内容美化。
发送数据到 Microsoft Teams 的 Channel 上
查看 Microsoft Teams 的相关文档,如果我们需要打通 Microsoft Teams
软件的话,我们需要创建传入 Webhook
。创建传入 Webhook,官方已经有很详细的介绍了,这里不累赘介绍。
我们在自己的团队中创建了 channel-02
。
然后将内容传送到这个频道上。
我们选用了 axios HTTP 库进行数据的发送。
代码语言:javascript复制const axios = require('axios');
axios.post(channel.url, page_json).then(res => {
console.log(res)
});
// 因为是定时的任务,我们还引入了处理定时的库 - [node-cron](https://www.npmjs.com/package/node-cron)
const cron = require('node-cron');
cron.schedule("01 01 10 * * 1-5", () => {
// 调起相关的请求
// init()
}, {
scheduled: true,
timezone: "Asia/Shanghai", // 中国时区,根据你团队所在的时区进行调整
})
我们发送到 channel-02
上的效果如下:
上图右上角出现的红色的 @ 表示已经触发并提醒当前任务的负责人,比如图上我自己
Jimmy
。相关提醒还会在电脑的右上角进行banner
横幅跳出展示。
【完】感谢阅读~