Slackアプリ開発のためのTips

Slackアプリの開発を少し経験する機会がありましたので、自分が今のところ知っている概念、開発プロセスやツールなどを紹介したいと思います。開発中に気になった内容をまとめた記事で、これからSlackアプリを作ってみるという方に少しでも参考になればとの思いで書きました。ただ、自分も未経験者に近いので、不正確な内容などありましたらご指摘お願いします。

# Slackアプリ開発

Slackを拡張するにはWorkflowsかアプリを作成することになります。Workflowsの場合、Workflow Builderを使ってコーディングの必要が無くタスクを自動化することができます。アプリを作成する場合でも、「Webhookを使って他のサービスから通知を受け取る」などのコーディングする必要がないケースもありますが、もっと複雑な深い連携が求められる場合は必ずコーディングが必要になります。

僕の場合、タスクのローテーションを作成するためのアプリを開発しました。ユーザーにmodalを表示し、ローテーションの情報を入力してもらい、そのスケジュールに応じて担当者に通知するためのものです。今回、開発したアプリケーションのお話はあまりしませんが、Slackアプリの開発もある程度幅が広いので、この記事を書く背景にはこちらのローテーションアプリがあったことが分かれば、紹介する内容のイメージがつきやすいのかもしれません。

# アプリとSlackのやり取り

アプリとSlackの基本的なやり取りは以下のような流れで行われます：

## 1. Trigger

まずはアプリをトリガーする出来事が起こります。一番分かりやすいのはユーザーによる何かしらのアクションですね。

ユーザーがアプリをトリガーする仕組みはいくつかありますが、その中でinteraction entry pointsと呼ばれるのが以下になります。

- Shortcut - 検索バー、メッセージ入力欄や各メッセージのケバブメニューから選択できるアクション。
- Slash commands - メッセージの入力で実行できるアクション。
- Block Kit interactive components - Slack上に表示できるUIコンポーネント。例：Modal。

| Shortcut | Slash command |
| --- | --- |
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/05c62fb8-a7c8-a38f-d3a3-a8605d9c38ee.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/b2b91d18-1eaa-08e3-53bf-502cfcbced8d.png) |

どちらのentry pointが使われても、interaction payloadというデータがアプリに送信されます。具体的には我々がアプリの設定で指定したURLに行なったアクションの内容が含まれたJSONがPOSTされます。

## 2. Response

アプリはSlackから届いたpayloadを処理し、responseを返します。例えば、triggerに対してメッセージをあるチャンネルに送信する、ユーザーからもっと情報を得るためにmodalを表示するなどが考えられます。僕のローテーションアプリの場合、ユーザーはshortcutでローテションの作成を選択し、アプリはローテーションの詳細を入力してもらうためにmodalを表示します。

どのようなアプリでもSlackからinteraction payloadが届いた際には最低でもacknowledge responseというものをSlackに返さなくてはいけません。こちらは問題なくinteraction payloadを受け取ったことを知らせるためで、ただのHTTP 200 OKですが、3秒以内に返す必要があります。返したところでユーザーには特に何も表示されませんが、もし3秒以内に返されなかった場合はエラーが表示されます。

# サンプルアプリ

実際にコーディングを始める際にはSlackが提供している以下のサンプルアプリの確認をお勧めします。

https://github.com/slackapi/node-tasks-app

アプリに関して複数の動画が以下のYouTubeプレイリストに上げられていてとても分かりやすいです。

https://www.youtube.com/playlist?list=PLWlXaxtQ7fUb0B4uNTKirvrQ0JOTCBFae

# 開発環境の問題

上記で説明したようにSlackは我々が開発したWeb APIに対してinteraction payloadをPOSTしてきます。本番のサーバーではイメージしやすいですが、こちらは開発中にローカルPCで立ち上がっているアプリケーションがSlackのリクエストを受け取る必要があるということになります。普通は開発環境で立ち上がっているアプリケーションをインターネットに公開することはないので、Slackにアクセスしてもらうための手段が必要になります。

# NgrokとQuick Tunnels

この問題を皆さんがどのように解決しているのかを調べてみると高確率でNgrokというサービスが見つかります。Ngrokを使えばとても手軽にローカルで実行されているアプリケーションが`https://〇〇.ngrok.io`のようなURLでインターネットからアクセスできるようになります。

https://ngrok.com/

ただ、僕の場合は別のサービスを使ってみました。Cloudflare社が提供しているQuick Tunnelsというサービスを使いました。Ngrokは無料で使えますが、利用用途によってはライセンス的に少し怪しくなるのかもしれません。以下のリンクによるとQuick Tunnelsの場合はそのような懸念はなさそうです。

https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/do-more-with-tunnels/trycloudflare/

ちなみに利用方法はどちらも結構似ています。Quick Tunnelsの場合、`cloudflared`というコマンドをインストールしてから以下のコマンドを実行できます。

```shell
$ cloudflared tunnel --url http://localhost:8080
```

そうすれば`https://〇〇.trycloudflare.com`のようなURLがターミナルで表示され、ローカルで立ち上がっているアプリケーションをアクセスすることができます。

```shell
Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):
https://〇〇.trycloudflare.com
```

アプリをテストする際にはSlack側でこのURLをRequest URLとして設定する必要があります。そして、立ち上がるたびにURLが変わり、Slackの設定をし直す必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/70ebb984-3034-1b05-02b9-3100a2670127.png)

## Chromeの警告

自分がQuick Tunnelsを試している際にChromeで`https://〇〇.trycloudflare.com`をアクセスしたら、セキュリティの警告が表示される場合もありました。ただ、調べたところこのような報告はNgrokを利用している方からもありましたので、あまり気にしていません。

# Socket Mode

今まで紹介してきたやり方だとSlackがアクセスするためのHTTP endpointをインターネットに公開する必要があります。ただ、公開したくない、もしくは会社のfirewall内にアプリケーションが置いてあるなどの場合は[Socket Mode](https://api.slack.com/apis/connections/socket)という仕組みを使うことができます。Socket Modeの場合、アプリケーション側から通信が開始されWebSocketを使ってやり取りが行われるからです。

# IP制限

アプリケーションのSlackへのアクセスは設定で特定のIPに制限することができますが、Slackからアプリへのリクエストは制限することができません。

# Payloadの認証

SlackからのリクエストにIP制限をかけることができませんが、リクエストの認証をすることができますので、実際にSlackからのリクエストだということは確認できます。認証の仕方は[ドキュメント](https://api.slack.com/authentication/verifying-requests-from-slack)に詳しく記載されていますが、以下のSDKを使えば自動的に認証してもらえるのでおすすめです。

# SDK - Bolt

Slackはアプリケーションの開発を楽にしてくれるためにBoltというSDKを提供しています。JavaScriptでの開発の場合、リポジトリは以下になります。

https://github.com/slackapi/bolt-js

上記で紹介したpayloadの認証に加え、payloadの処理、ackやエラーresponseの実装などをサポートしてくれます。

# Block Kit

ModalなどUI上のコンポーネントを定義するためにBlock KitというUI frameworkを利用します。そして、各コンポーネントは下記画像(Block Kit Builderを使って生成しました)のようにJSONを使って定義します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/6fecd49f-3048-5405-976e-7bdf6d489a6d.png)

ユーザーにmodalを表示したい場合は、shortcutなどのresponseに上記のようなJSONで定義されたUIを返す必要がありますが、このJSONを作成するためにも便利なライブラリが存在します。僕の場合、Node.jsで開発しましたので、[Slack Block Builder](https://github.com/raycharius/slack-block-builder)というライブラリを使ってUIを定義しました。

# 参考

Slackアプリの公式ドキュメント：<https://api.slack.com/start>