背景と目的
Google スプレッドシートには「Jira Cloud for Sheets」というアドオンが有り、Jira Cloud から指定した条件にマッチする課題を簡単に抽出することができます。
先日、Atlassian からこのアドオンの提供が終了するという発表が有りましたが、コミュニティからの猛反対が有り、撤回されました。
ただし、個人的には
- 今後何かの理由でアドオンの提供・アップデートが停止される可能性は 0 ではない
- アドオンではカスタマイズできない設定などをカスタマイズしたい
という思いがあったので、「それなら REST API と GAS を使って同じような機能を実装しよう」と思い立ち、JQL で指定した条件にマッチする課題を抽出する GAS を実際に実装しました。
今回はその実装方法を紹介しようと思います。
JQL とは
最初に JQL について簡単に説明します。
JQL は Jira Query Language の略で、Jira で特定の課題を検索するためのクエリ言語です。
以下に Atlassian の記事を貼っておきますので、JQL を使ったことが無い方は是非ご参照ください。
- はじめてのJQL 第1回:Jiraでの検索の概要とJQLの基礎 | Atlassian Community
- Jira クエリ言語 (JQL) で高度な検索を使用する | Atlassian Support
Jira Cloud REST API を使用する準備
API トークンの取得
Atlassian 製品の REST API を使用するには API トークン が必要になります。
API トークンを取得するには、自分の Atlassian アカウント管理ページの [セキュリティ] → [API トークン] → [API トークンの作成と管理] にアクセスし、作成します。
Basic 認証方法
Jira Cloud REST API を実行する場合、取得した API トークン your-api-token
と自分の Atlassian アカウント your-account@example.com
を使用して Basic 認証します。
詳しい仕様については以下の記事をご確認ください。
リクエストを送信するためのサンプルコード
以下にリクエストを送信するためのサンプルコードを掲載します。
function sendRequest(method, resource, params) {
let url = "https://your-domain.atlassian.net" + resource;
const account = "your-account@example.com";
const apiToken = "your-api-token";
let options = {
"method" : method,
"headers" : {
"Content-Type" : "application/json",
"Authorization" : "Basic " + Utilities.base64Encode(account + ":" + apiToken),
},
"muteHttpExceptions" : true
}
if (params!=""){
options["payload"] = JSON.stringify(params);
}
const response = UrlFetchApp.fetch(url, options);
const responseCode = response.getResponseCode();
const responseBody = response.getContentText();
if ([200, 201].indexOf(responseCode)<0){
throw new Error(responseCode + " : " + responseBody);
}
return JSON.parse(responseBody);
}
-
https://your-domain.atlassian.net
のyour-domain
はご自身の環境に合わせて設定してください。 -
method
にはGET
やPOST
を指定します。 -
resource
には/rest/api/3/<resource-name>
など、使用したい REST API のリソースを指定します。 -
params
にはオプションのパラメーターなどを指定します。
課題フィールドの一覧を取得する
REST API で Jira の課題を取得すると、カスタムフィールドは customfield_10000
のように表示されます。これだと何の課題フィールドなのかわからないので、課題フィールドの一覧を取得し、課題フィールドの ID と名前の対応表を準備しておきます。
課題フィールドの一覧を取得するには resource
に /rest/api/3/field
を指定します。
詳しい仕様は以下の記事をご確認ください。
サンプルコード
以下に課題フィールドを取得するサンプルコードを掲載します。
function getIssueFields() {
try{
const resource = "/rest/api/3/field";
const fields = sendRequest("GET", resource, "");
return fields;
} catch(e) {
return {"error": e.message};
}
}
取得した課題フィールドの情報 fields
を加工し、お好みの形式で Google スプレッドシートに書き出して課題フィールドの ID と名前の対応表を作成してください。
JQL で指定した課題を取得する
JQL で指定した課題を取得するには resource
に /rest/api/3/search
を指定します。
詳しい仕様は以下の記事をご確認ください。
サンプルコード
以下に JQL で指定した条件にマッチする課題を取得するサンプルコードを掲載します。
- 1回のリクエスト送信で取得できる課題は、デフォルトでは50件です。今回は1回に100件取得できるように
maxResults
に100
を設定しています。また、maxResults
に設定できる最大値は100
です。 - 条件にマッチする課題が100件以上ある場合、全ての情報を取得するまでリクエスト送信を行います。
-
jql
に条件を設定しないでリクエストを送信した場合、ご自身の Jira インスタンスに存在するアクセス可能なすべての課題が条件にマッチする課題になります。ただし、上記の仕様を組み込んでいるため、意図せず大量の課題を取得してしまわないようにjql
が未設定の場合はエラーになるようにしています。
function getIssuesbyJql(jql) {
const resource = "/rest/api/3/search";
const maxResults = 100;
let startAt = 0;
let total = 0;
try{
if (jql==""){
throw new Error("jqlが未設定です。設定して実行してください。");
}
let issues = [];
do {
let params = {
"maxResults" : maxResults, // 1回に最大100件まで取得可能
"startAt" : startAt, // オフセット
"jql" : jql // JQL
}
const response = sendRequest("GET", resource, params);
//console.log(response);
for (const issue of response.issues){
issues.push(issue);
}
total = response.total;
startAt += maxResults;
} while(total>startAt)
return issues;
} catch(e) {
return {"error": e.message};
}
}
例えば、開発A
というプロジェクトの Epic
を 更新日
で降順にソートして取得したい場合、以下の JQL を getIssuesbyJql
に指定して実行すると取得できます。
project = 開発A AND issuetype = Epic ORDER BY updated DESC
取得した課題 issues
を加工し、お好みの形式で Google スプレッドシートに書き出して課題リストを作成してください。
また、一定時間で自動的に課題リストを更新したい場合は、GAS の時間トリガーを使用することで実現可能です。
まとめ
今回は Jira Cloud REST API と GAS を使用し、 JQL で指定した条件にマッチする課題を抽出する方法を紹介しましたが、如何だったでしょうか?
余談になりますが、Jira Cloud には自動化機能があり、Web リクエストを送信することができますので、REST API を自動化機能で使用することで、例えばプロジェクトの自動生成などが可能です。
以前、Jira Cloud の自動化機能に関する記事を書いているので、ご興味があればこちらもご確認ください。
最後まで読んでいただきありがとうございました!