Suppose you have a task like this:

You need to synchronize tasks on Jira to Microsoft Teams on a regular basis and alert the responsible person of the current task.

For example: at 10:01am every weekday (Monday through Friday), send a message via the robot to your team’s channel and @ the relevant task leader.

1.

  1. Built for every member of a Software team, Jira Software can be used to plan, track, and deliver exceptional Software.
  2. Microsoft Teams Communication assistance software.
  3. Channel: a team’s channel. A team can have multiple channels.

Basic work

We want to implement a service, as a front-end slice, we use NodeJS to develop. The Koa framework is chosen here.

Because the function is relatively simple and does not involve front-end development, there is no front-end technology selection here.

Background development involves retrieving Jira data, which we directly use the related package jIRa-Client.

To sum up, you only need to install the key package files as follows:

npm install koa / / nodejs framework
npm install jira-client // Get jIRA data
npm install aixos / / HTTP library
npm install node-cron // Scheduled task processing# or NPM install koa jira-client axios node-cronCopy the code

Get the data from Jira

We are just porters of Jira data, and the JIRa-Client documentation details how we can get the relevant data.

Such as:

/ * * * delete specified Jira Issue * [Jira Doc] (HTTP: / / http://docs.atlassian.com/jira/REST/latest/#id290791)
* @name deleteIssue
* @function* @param {string} issueId - Id of Issue to delete */ deleteIssue(issueId) {return this.doRequest(this.makeRequestHeader(this.makeUri({
    pathname: `/issue/${issueId}`
  }), {
    method: 'DELETE',
    followAllRedirects: true}}))Copy the code

Of course, what we want to implement is the task of querying, using the searchJira method.

The methods provided by the JIRA-Client package are encapsulated as follows:

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}) // searchJira 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 this field is a Jira query condition, such as: projectin(Project1, Project2) AND resolution = Unresolved ORDER BY priority DESC, updated DESC. The contents of these queries can be adjusted in Jira and added to the searchString field on the request URL.Copy the code

Through the above operations, you can obtain the related Jira Issues data as follows:

Card data assembly

We successfully obtained the data on Jira above, so we beautify the obtained data and assemble them into corresponding cards.

Detailed format cards can be linked for details.

Since we need the person in charge of @ task, the card type we choose is adaptive-card.

const body_list = [];
const msteams_entities = [];

body_list.push({
  "type": "TextBlock"."text": `<at>${_item.username}</at> Current task '."weight": "bolder"."wrap": true
}, {
  "type": "TextBlock"."text": 'Due Task:${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=The ${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": "Details"}]."msteams": {
              "width": "Full"."entities": msteams_team_entities
          }
      }
  }]
};
Copy the code

In order to be compatible with mobile and PC, please choose the attributes supported by the document. Do not write markdown to beautify the content.

Send data to the Microsoft Teams Channel

Check out the documentation for Microsoft Teams. If we need to get through Microsoft Teams, we need to create an incoming Webhook. Create an incoming Webhook, the official has a very detailed introduction, here is not a cumbersome introduction.

We created Channel-02 in our own team.

The content is then transferred to this channel.

We choose axiOS HTTP library to send data.

const axios = require('axios');

axios.post(channel.url, page_json).then(res= > {
  console.log(res)
});

/ / because it is a regular task, we also introduced the treatment timing library - [node - cron] (https://www.npmjs.com/package/node-cron)
const cron = require('node-cron');
cron.schedule("01 01 10 * * 1-5".() = > {
  // call up the relevant request
  // init()
}, {
  scheduled: true.timezone: "Asia/Shanghai".// China time zone, adjusted according to your team's time zone
})
Copy the code

The effect we sent to channel-02 is as follows:

The red @ in the upper right corner of the image indicates that it has been triggered and alerts the person in charge of the current task, such as myself, Jimmy. Relevant reminders will also be displayed in the top right corner of the banner banner.

Thanks for reading