JIRA APIを使用してslackに直近のリリース案件を通知しよう with PHP

# 課題定義
Jiraでたくさんの案件管理をしていると、どの案件がリリースがいつあるのか忘れることがよくあります。

- え、明日リリースだっけ？
- このページバグってるんですけど、今日誰かリリースしたんですか(同チームより)
- 同じコンテンツでリリースあるの知らなくてgit-flowのリリースブランチ作っちゃったんですけど・・・

などなど、リリース日をチーム間で把握していないと上記のような事象が発生していました。

# 解決策
これらの課題を解決するためにJiraAPIを使用して直近のリリース日を通知する機能を作ってみました。

![jira.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153118/fd2fb21b-7b02-0d9a-2cfa-e4d712ca944f.png)

JiraAPIを叩いて、Webhookでslackに通知するだけです。

# 必要なもの
- Jiraのアカウント
- slackのアカウント
- slackのIncoming WebhookのURLを発行する([発行方法](https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8))
- PHP実行環境(他言語でも書き換えればOK)

# リリース日時を取得する
JiraAPIを使用して、直近のリリース日のチケットを取得しましょう。
今回は向こう5日以内のチケットを取得します。

```php
/** JIRAの課題データを取得する(リリース日が直近5日) */
function get_issue_data(){
	$project = 'DEVELOP_PROJECT';// Jiraのプロジェクト名を入力する
	$release_day_column = 'リリース日';// 案件のリリース日カラムに該当する情報を入力する
	$issue_data = [];
	$url = "https://[jira-domain]/jira/rest/api/2/search?";
	for($day=0; $day<5; $day++){
		$params = [
			'fields' => 'summary',
			'jql' => "project = {$project} AND {$release_day_column} = {$day}d"
		];
		// curl_procはあとで出てきます
		$day_data = curl_proc($url.http_build_query($params));
		$d_day_data = json_decode($day_data, true);
		if($d_day_data['total'] > 0){
			$issue_data[$day] = $d_day_data['issues'];	
		}
	}
	return $issue_data;
}
```

以下のJiraAPIを使用しています。
https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/#searching-for-issues-examples

上記ソースの「jql」に記載されている条件はJiraの検索欄に書くように条件を書いてください。
![jira_search](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153118/17edd03f-a5cc-931e-8b11-97d255d7dcf2.png)

# メッセージを生成する
メッセージ生成は各々が自由に設定いただいて大丈夫だと思います。
JiraのsearchAPIで取得した情報はそれぞれのissueの中の['self']という要素を取ると、自身のチケット情報を取得することができます。
自分の場合は以下のようにリリース通知文言を組み立てました。

```php
function create_message_text($issue_data){
	$message_text = "直近(5日間)のリリース予定をお知らせするよ！\n";
	$issue_tenp = "%s(%s)\n";
	if(count($issue_data) == 0){
		return $message_text . "直近(5日間)のリリースはないよ！";
	}

	foreach ($issue_data as $day => $issue_list) {
		$message_text .= '▼'.(new DateTime("+{$day} days"))->format('Y-m-d')."\n";
		foreach($issue_list as $issue) {
			// curl_procはあとで出てきます(issue['self']で対象チケットの情報を取得)
			$data = curl_proc($issue['self']);
			$d_data = json_decode($data);
			$field_data = $d_data->fields;
			$message_text .= sprintf(
				$issue_tenp,
				$field_data->summary, // タイトル
				$field_data->assignee->displayName // 担当者
			);
		};
	}
	return $message_text;
}
```

summary→JiraAPIを使ってslack通知する、assignee->displayName→ONO-SOICだとすると

```
直近(5日間)のリリース予定をお知らせするよ！
▼2020-08-27
JiraAPIを使ってslack通知する(ONO-SOIC)
```

みたいな文章を作るようにしました。複数のチケットがあれば縦に並ぶようになっています。
ちなみに上記の`$issue_list`の中身を見ると以下のようになっています。

```
array(1) {
  [0]=>
  array(5) {
    ["expand"]=>
    string(69) "operations,versionedRepresentations,editmeta,changelog,renderedFields"
    ["id"]=>
    string(6) "333333"
    ["self"]=>
    string(59) "https://[jira-domain]/jira/rest/api/2/issue/333333"
    ["key"]=>
    string(20) "DEVELOP_PROJECT-3333"
    ["fields"]=>
    array(1) {
      ["summary"]=>
      string(30) "JiraAPIを使ってslack通知する"
    }
  }
}
```

上記の"self"のURLを実行すると更に詳細なチケット情報が取得できるので、より深い情報を用いて文章構築ができます。

# slack通知する
以下のような感じでwebhookを設定して通知処理を作ります。

```php
/** slackに送信する */
function send_to_slack($message) {
  $webhook_url = 'https://hooks.slack.com/services/[webhookToken]';
  $payload = [
  	'text' => $message,
	'blocks' => array(
		array(
			"type" => "section",
			"text" => array(
				"type" => "mrkdwn",
				"text" => $message
			)
		)
	)
  ];
  $options = array(
	'http' => array(
	  'method' => 'POST',
	  'header' => 'Content-Type: application/json',
	  'content' => json_encode($payload),
	)
  );
  $response = file_get_contents($webhook_url, false, stream_context_create($options));
  return $response === 'ok';
}
```

# URL実行
これは上の処理で`curl_proc`といたのですが、curl実行処理を関数化してます。

```php
/** curl実行 */
function curl_proc($url){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_USERPWD, [USER_PASS]);
	curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
	$result = curl_exec($ch);
	curl_close($ch);
	return $result;
}
```

JiraAPIを実行する際はアカウント情報が必要です。
`USER_PASS`はJiraの「アカウント名:パスワード」を指定してください。

# 全体のコード

```php
<?php
define('USER_PASS', "アカウント名:パスワード");

$issue_data = get_issue_data();
$message_text = create_message_text($issue_data);
send_to_slack($message_text);

/** JIRAの課題データを取得する(リリース日が直近5日) */
function get_issue_data(){
	$project = 'DEVELOP_PROJECT';// Jiraのプロジェクト名を入力する
	$release_day_column = 'リリース日';// 案件のリリース日カラムに該当する情報を入力する
	$issue_data = [];
	$url = "https://[jira-domain]/jira/rest/api/2/search?";
	for($day=0; $day<5; $day++){
		$params = [
			'fields' => 'summary',
			'jql' => "project = {$project} AND {$release_day_column} = {$day}d"
		];
		// curl_procはあとで出てきます
		$day_data = curl_proc($url.http_build_query($params));
		$d_day_data = json_decode($day_data, true);
		if($d_day_data['total'] > 0){
			$issue_data[$day] = $d_day_data['issues'];	
		}
	}
	return $issue_data;
}

function create_message_text($issue_data){
	$message_text = "直近(5日間)のリリース予定をお知らせするよ！\n";
	$issue_tenp = "%s(%s)\n";
	if(count($issue_data) == 0){
		return $message_text . "直近(5日間)のリリースはないよ！";
	}

	foreach ($issue_data as $day => $issue_list) {
		$message_text .= '▼'.(new DateTime("+{$day} days"))->format('Y-m-d')."\n";
		foreach($issue_list as $issue) {
			// curl_procはあとで出てきます(issue['self']で対象チケットの情報を取得)
			$data = curl_proc($issue['self']);
			$d_data = json_decode($data);
			$field_data = $d_data->fields;
			$message_text .= sprintf(
				$issue_tenp,
				$field_data->summary, // タイトル
				$field_data->assignee->displayName // 担当者
			);
		};
	}
	return $message_text;
}

/** slackに送信する */
function send_to_slack($message) {
  $webhook_url = 'https://hooks.slack.com/services/[webhookToken]';
  $payload = [
  	'text' => $message,
	'blocks' => array(
		array(
			"type" => "section",
			"text" => array(
				"type" => "mrkdwn",
				"text" => $message
			)
		)
	)
  ];
  $options = array(
	'http' => array(
	  'method' => 'POST',
	  'header' => 'Content-Type: application/json',
	  'content' => json_encode($payload),
	)
  );
  $response = file_get_contents($webhook_url, false, stream_context_create($options));
  return $response === 'ok';
}

/** curl実行 */
function curl_proc($url){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_USERPWD, [USER_PASS]);
	curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
	$result = curl_exec($ch);
	curl_close($ch);
	return $result;
}
```

上記のphpファイルを実行するとSlackに通知が来ます。
会社botを使ったのでアイコンはピカチュウになってます。

![Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153118/ff88a7da-8148-913e-11bd-35c32eb22bf3.png)

是非みなさんもJiraAPIを活用してslack通知をしてみてください！