GASで手軽に SlackへのKPI通知Botを作る

この記事は2019/1/22のData Driven Developper meetupでのLTの発表内容の補足です。
https://d3m.connpass.com/event/115217/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221497/846eaa7b-971d-a512-946a-a1417bfbe788.png)


## はじめに
みなさん、KPIってどうやって周知してますか？
ダッシュボードやスプレッドシートに表示しておくだけだと見に行こうとしない限り見えないため中々広く定着させることが難しいですよね。
LookerというBIツールならデフォルトでSlackへの通知ができますが、BIツールって高価で中々手が出せない。。。
そんな風に悩んでいる方も多いのではないでしょうか？

この記事では、そんな方たちに向けて、簡単にSlackにKPIを定期的に配信できる仕組みを説明していこうと思います。

##GAS（Google Apps Script）とは？
僕は会社の勉強会で少し習った程度なので詳しくは知りませんが、以下のように理解しています。

* サーバレスでJavascriptを実行できる環境（無料！！）
* Gsuiteのサービス同士を数行のコードで連携させられる（外部APIも叩ける）
* 定期実行のトリガーを簡単に設定できる

本来はGsuiteのサービスを簡単に連携させるのに使われるイメージがあります（googleカレンダーの予定をスプレッドシートに吐き出すとか）
しかし外部のAPIも叩けるので、今回はそれを利用します。

##条件
* BigQueryにデータを貯めている
* Slackを利用している

こんな感じでSlackにメッセージが飛びます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221497/f25a81b7-f32c-268e-9b60-0e5f936d82c3.png)


##実装
GASはJavascriptベースでしか記述できませんが、今回はあんまりJavascriptの知識は必要ありません。
それは、それぞれの処理がほぼテンプレ化していて、変えるところはほとんど変数の値だからです。

```javascript
//BigQueryにクエリを投げてデータをとってくる部分
function runQuery() {
	var projectId = 'GCPのプロジェクトID';
	var request = {
	  "query" : "データを返したいクエリ",
	  "useLegacySql": false,
	};
	var queryResults = BigQuery.Jobs.query(request, projectId);
	var jobId = queryResults.jobReference.jobId;

	var sleepTimeMs = 500;
	while (!queryResults.jobComplete) {
	  Utilities.sleep(sleepTimeMs);
	  sleepTimeMs *= 2;
	  queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
	}

	var rows = queryResults.rows;
	while (queryResults.pageToken) {
	  queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
		pageToken: queryResults.pageToken
	  });
	  rows = rows.concat(queryResults.rows);
	}

	return rows
  }

// Slackメッセージを組み立て、Slackにポストする
function postSlack() {

	var rows = runQuery();
	var value1 = rows[0].f[1].v;
	var value2 = rows[0].f[2].v;
	var value3 = rows[0].f[3].v;
	var value4 = rows[0].f[4].v;

	// Slackメッセージを組み立てる
	var body =
	{
		"attachments" : [
			{
				"fallback": "何かテキスト",
				"color": "色コード",
				"pretext": "何かテキスト",
				"title": "title",
				"author_name": "author name",
				"author_link": "url",
				"author_icon": "icon url",
				"fields": [
					{
						"title": "value1",
						"value": value1,
						"short": true
					},
					{
						"title": "value2",
						"value": value2,
						"short": true
					},
					{
						"title": "value3",
						"value": value3,
						"short": true
					},
					{
						"title": "value4",
						"value": value4,
						"short": true
					},
				],
			},
		],
		"actions": [
			{
				"type": "button",
				"text": "なんかコメント",
				"url": "飛ばしたいURL",
				"style": "primary"
			},
		]
	};

	var webhookURL = 'SlackのWebhookURL';

	var options = {
		'method' : 'POST',
		'contentType' : 'application/json',
		'payload' : JSON.stringify(body),
	};

	UrlFetchApp.fetch(webhookURL, options);
}
```

こんな感じで変える部分は投げたいクエリとかGCPのプロジェクトIDとかSlackのWebhookURLだけです。

少しだけトリッキーなのが、BigQueryからデータをとってくる部分で、二次元配列のような形でデータが返ってきます。
`rows[取りたいデータの行].f[取りたいデータの列].v`という形で取りたいデータをとってこれます。

Slackのメッセージを組み立てる部分で、どんな感じのメッセージになるのかイメージしたい方は、Slackのメッセージビルダを使うと便利です。上のコードの`{ "attachments" : `以下を貼り付けると、自動でこんな感じの見た目になるよとプレビューを生成してくれます。

https://api.slack.com/docs/messages/builder

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221497/b6652781-6b6c-7fec-89de-22e9b330aa14.png)

あとはGAS上からトリガーを配信したい期間に設定するだけで完了です！！
超簡単なのでぜひやってみてください！

## SlackにKPIを通知するメリット
[Rettyさんのブログ](https://engineer.retty.me/entry/2018/12/18/115020#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%A3%8F%E3%81%AB%E3%81%82%E3%82%8B%E7%9C%9F%E5%AE%9F%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E6%9C%AC%E8%B3%AA)にも書いてありますが、

* 数値感が定着する（あの数値はだいたいこれくらい）
* それにより変化を検知しやすくなる

というのが最も大きいところかなと思います。
他には、最近「データの民主化」という言葉が流行していますが、組織をデータ・ドリブンに変えていくという大きなことを考えるとどこから手をつけて良いのかわからなくなりがちです。
しかし、今回のネタである「GASでSlackにKPIを通知する」というのであれば、データがBigQueryにありさえすれば無料で簡単に始められます。
よりメンバーの多いチャンネルに通知するようにすれば、普段データに触れることのない人たちにも興味を持ってもらいやすいかなと思います。

## 終わりに
僕自身社内の勉強会でGASを少しかじったくらいでしたが、年末年始の空き時間を利用してやってみたら意外と簡単にできました。
皆さんも興味をお持ちでしたらぜひやってみてください。