やりたいこと
毎日決まった時間にJiraの未完了課題をSlackの各チャンネルに投稿します。
未完了課題の確認漏れを無くします。
全体の流れ
- Jira APIを使ってJiraから未完了の課題データを取得します。
- Slack APIを使ってのSlackの各チャンネルに投稿します。
手順
Jira APIトークンを作成
まずはJiraのAPIトークンを取得します。
下記リンクへログインします。
https://id.atlassian.com/manage/api-tokens
「API トークンの作成」をクリックします。

ダイアログが表示されるので「Label」欄に簡単なラベル名を入力して「作成」をクリックしてください。

APIトークンが発行されますのでコピーしてから「閉じる」を押してください。
一度しか表示されませんので必ずコピーして大切に保管してください。

Jira APIの作成は以上です。
SlackでIncoming Webhook URLを取得
次にSlackで課題を投稿したいチャンネルのIncoming Webhook URLを取得します。
アプリの作成
Slackアプリが必要ですので下記リンクから作成します。
https://api.slack.com/apps/new
「Create a Slack App」ダイアログが表示させますのでApp Nameにアプリ名を記入し、「Development Slack Workspace」で課題を投稿したいワークスペースを選択して「Create App」をクリックします。

アプリの設定
作成したアプリの設定をします。
OAuth & Permissionsの設定
左のメニューから[OAuth & Permissions]をクリックする。

Scopeの設定をします。「Scopes」>「Bot Token Scopes」のAdd an OAuth Scopeをクリックして「chat:write」、「incoming-webhook」を追加します。


ページ上部の「Install to Workspace」をクリックします。

投稿先のチャンネルを選択し、「許可する」をクリックします。

Bot User OAuth Access Tokenの欄にトークンが表示されれば成功です。

OAuth & Permissionsの設定は以上です。
Incoming Webhooksを設定
次に左のメニューから「Incoming Webhooks」をクリックして「Active Incoming Webhooks」をOnになっていることを確認します。なっていなければOnにしてください。

ページ下部にWebhook URLとChannelが追加されています。
このWebhook URLは後ほど使います。
投稿するチャンネルを増やす場合は「Add New Webhook to Workspace」で追加できます。

これでSlackでチャンネルのWebhook URLを取得できました!
プログラムを作成
今回はGoogle AppScriptでプログラムを書いていきます。
Jiraからデータを取得
まずはJiraからプロジェクト毎の未完了タスクを取得する処理を書きます。
const EMAIL = "[YOUR_EMAIL]";
const JIRA_API_TOKEN = "[JIRAのAPIトークン]";
const BASE_URL = 'https://[Jiraドメイン]';
const SEARCH_URL = BASE_URL + '/rest/api/2/search?';
const ISSUE_URL = BASE_URL + '/rest/api/2/issue/';
const PROJECTS = [{key:"プロジェクトKEY",name:"プロジェクト名", url:"投稿先チャンネルのWebhook URL"},
{key:"プロジェクトKEY",name:"プロジェクト名", url:"投稿先チャンネルのWebhook URL"}];
function get_project_issues(project_key){
let issues = serach_project_issues(project_key);
//project_keyをキーにして検索します。
let array = [];
add_objects(issues,array);
//プロジェクトの二次元配列を作ります。
return array;
};
function serach_project_issues(project_key) {
let status = 'Done, 完了';
let query = "&jql=project[key]=" + project_key + " AND status NOT IN(" + status + ") ORDER BY duedate asc";
//未完了のissueを期日が近い順に取得するクエリ。
let issues = search(query);
return issues;
};
function add_objects(issues,array) {
issues.forEach(function(issue){
obj = {};
obj["key"] = issue.key;
obj["summary"] = issue.fields.summary;
obj["status"] = issue.fields.status.name;
obj["priority"] = issue.fields.priority.name;
obj["duedate"] = issue.fields.duedate?issue.fields.duedate: '期日未定';
obj["assignee"] = issue.fields.assignee?issue.fields.assignee.displayName: '未割当';
array.push(obj);
});
};
function search(query) {
let sort = "&fields=self,issuetype,summary,status,priority,assignee,duedate";
let url = SEARCH_URL + sort + query;
let data = get_data(url);
let decoded = decode(data);
//帰ってきたJSONデータをデコードする。
let issues = decoded["issues"];
return issues;
};
function get_data(url) {
let token = Utilities.base64Encode(EMAIL + ":" + JIRA_API_TOKEN);
let headers = {
"Content-Type": "application/json",
'Authorization': 'Basic ' + token,
};
//EMAILとJiraのAPIトークンで認証する。
let options = {
"method": "get",
"headers" : headers,
};
let response = UrlFetchApp.fetch(url, options);
return response;
};
function decode(data) {
let json = JSON.parse(data.getContentText());
return json;
};
function run_project_issues(){
let projects = PROJECTS;
projects.forEach(project => {
let issue_keys = get_project_issues(project["key"]);
//Jiraから課題データ取得
send_to_project(project,issue_keys);
//Slackに投稿
});
}
Slackに投稿
次にSlackに投稿する処理を書きます。
function send_to_project(project, issues){
let text = "*" + project["name"]+ "の未完了タスクです。*\n";
let number = 0;
issues.forEach( issue => {
let url = "https://[Jiraドメイン]/browse/" + issue["key"];
number = number +1;
text = make_text(number,text,issue,url);
});
Logger.log(text);
send_to_slack(project["url"], text);
};
function make_text(number,text,issue,url) {
text = text + "\n" + number + ". " + issue["assignee"] + " "+ issue["duedate"] + " " +
issue["priority"] + " " + issue["status"] +"<" + url + "|" + issue["summary"] + "> " ;
return text;
//担当者、期日、優先度、ステータス、URLをテキストに追加
};
function send_to_slack(webhook_url, text) {
let json_data = {
"text" : text,
};
let payload = JSON.stringify(json_data);
var options = {
"method" : "post",
"contentType" : "application/json",
"payload" : payload,
};
UrlFetchApp.fetch(webhook_url, options);
};
コードは完成です。
ウェブアプリケーションとして導入
コードが書けたら次はウェブアプリケーションとして導入します。
上部のメニューから「公開」をクリックします。

モーダルが表示されたら各項目を設定して「デプロイ」します。
今回は
Execute the app as : User accessing the web app(アクセスユーザーが実行ユーザー)
Who has access to the app : Anyone within [ドメイン名](G Suiteに登録している{ドメイン名}のアカウントでログインしていればアクセス可能)

これでウェブアプリケーションとして公開できました。
トリガーを設定
次に決まった時間にアプリケーションを実行するようトリガーを設定します。
上部メニューの時計マークをクリックしてトリガー作成ページを開きます。

ページ右下の「+ トリガーを追加」から新規トリガーを作成します。

今回は毎朝9時〜10時にrun_project_issues関数を実行したいので、以下のように設定します。
設定が完了したら「保存」して完成です。

これで以下のように毎朝SlackのチャンネルにJiraの未完了課題が投稿されます。

コメント