Amazon API GatewayとAWS LambdaでつくるインタラクティブなSlackAppその１（Slash Command）

GitHub Organizationの管理をしているのですが、運用が少し面倒なのでなんとかできないかといろいろ考えています。
今回はチャットボットでの運用を導入できないかと考えて検証してみたのでまとめました。
（いろいろな制約により残念ながら実用には至ってません。）

今回の記事ではSlackAppにおける機能として`Slach Command`を利用しています。

また、この記事では以下の要素を利用して、SlackAppを構築するための基本的な部分を実装していますが、
個々の要素の具体的な利用方法や言語の実装についてはあまり触れません。

- Amazon API Gateway
- AWS Lambda (Golang)
- CloudFormation (AWS SAM)

# TL;DR

SlackとAWSを利用して対話型なインターフェイスを作成するサンプルを作りました。
以下のアニメーションにある`コマンドで呼び出し → 選択肢の応答 → ボタン押下による応答 → メッセージ書き換えによる応答`の流れのうち、選択肢の応答までを説明しています。

以下のような動作をします。
![command.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/0c79e1b8-03df-c750-3aed-e7c2d8dd45bd.gif)

# 前提条件

- Slackのワークスペースの管理権限を持っていること
- AWSの対象の各サービスの操作権限と基礎知識をもっていること
- (ソースコードを読むのであれば)Golangの基礎知識をもっていること

# Amazon API Gatewayの構築

このコマンドを実行する事でAWS上に本記事で使うAPIを構築します。
また、最終行にそのAPIのURLが出力されます。SlackApp構築時に設定に利用するのでメモっておいてください。

なお、環境変数AWS_PROFILEについてはデフォルト以外のプロファイルを利用する場合に指定してください。

```bash
$ git clone https://github.com/ikeisuke/slack-app-example.git
$ cd slack-app-example
$ export AWS_PROFILE=xxx
$ make all
```

また、これ以外に各コマンドから利用するためにいくつか環境変数がありますが、必要に応じてアップデートをしますのでここでは未指定で進めてください。

# Slack Appの作成

[https://api.slack.com/apps](https://api.slack.com/apps) にアクセスし「Create New App」ボタンをクリックして新しいアプリケーションを作成します。
![スクリーンショット 2019-12-08 0.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/22761d51-c5ab-d50b-21e4-560acb955a34.png)

クリックすると「App Name」と「Development Slack Workspace」の入力を求められるので、好きな名前と自分の管理しているワークスペースを選択します。
![スクリーンショット 2019-12-08 0.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/c6a4b7d9-39fe-0741-60cd-0a4b43a0404d.png)

## コマンドを作成する

アプリケーション作成完了後に表示されるページの左メニューからSlash Commandsを選んで「Create New Command」ボタンをクリックして新しいコマンドを追加します。
![スクリーンショット 2019-12-08 0.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/d8fc287c-0c6c-66d8-8f49-373a705156a7.png)


「Command」には作成したいコマンド（既存のコマンドに被らないもの）、「Request URL」にはAWSにデプロイした際に表示されたURLの後ろに「slash」（そのようなパスでAPIをデプロイしています）を追加したURLを設定します。画像にはないですがその下にある「Short Description」も入力しないと進めないので注意してください。
![スクリーンショット 2019-12-07 23.31.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/7424a543-2160-4e42-78c5-05c977c2858f.png)

## ボットを作成する

今回のコマンドでは、コマンド送信後Botがチャネルの一覧のボタンを送ってくるだけのプログラムになっています。送信のためにボットユーザーを用意します。
左のメニューから「Bot Users」を選択し「Add a Bot User」ボタンをクリックします。基本項目は入力されているので問題なければそのまま「Add Bot User」ボタンをクリックして完了です。

![スクリーンショット 2019-12-07 23.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/1f099e9c-8548-3309-f353-74609ade0576.png)


## ワークスペースにアプリケーションをインストールする

ここまでの作業を完了させてたら、ワークスペースにアプリケーションをインストールするために左のメニューから「Install App」を選択し、「Install App to Workspace」ボタンをクリックしてインストールします。

![スクリーンショット 2019-12-07 23.31.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/8fb336b3-8f75-334a-403f-c845572fd421.png)

インストールが完了するとアクセストークンが表示されていますので、「Bot User OAuth Access Token」をコピーして次の環境変数の設定で使います。

![スクリーンショット_2019-12-08_0_19_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/7e2b75b8-e2f0-2025-a33b-2a97f6d344b5.png)


## アプリケーションの環境変数を設定する

Slackから送られてくるメッセージの署名の確認用のシークレットキーとボットユーザーがメッセージを送信するためのトークンを環境変数に設定します。

左のメニュの「Basic Information」をクリックして、少し下にスクロールした位置にある「App Credentials」グループ内の「Signing Secret」の部分を「Show」ボタンを押すと表示できるので表示してコピーします。
![スクリーンショット_2019-12-07_23_42_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45645/f366226c-e989-516c-99d9-5eb5ed309713.png)


本項でコピーしたシークレットキーと前項でコピーしたボット用トークンを以下のように環境変数に設定してデプロイコマンドを実行します。

```
$ export SLACK_SIGNING_SECRET=xxxx
$ export BOT_USER_ACCESS_TOKEN=xoxb-xxxxx
$ make deploy
```

## 動作確認

`/[作成したコマンド] channel list`とメッセージ欄に入力して送信した後に、ワークスペースの登録済みチャネルの一覧がボタンでボットユーザーにより投稿されればコマンドは完成です。

# 参考

- ソースコード [ikeisuke/slack-app-example](https://github.com/ikeisuke/slack-app-example)
- [Slack API](https://api.slack.com/)
- [動画をアニメーションGifに変換](https://qiita.com/takuya-ki/items/13e445096752b8181de7) （動画をQiitaに貼るのにやり方を参考にさせてもらいました。）

# あとがき

botからのメッセージにあるボタンを押した後のインタラクションについてまでをかこうと思っていたのですが、
思ったより記事が長くなってしまったので、今回はここまでにします。
次回は続きとしてインタラクション周りについて書きたいと思います。