はじめに
Slack APIには、Web API、Events API、RTM API などの種類があります。(詳細は公式サイト参照)
今回は、その中でも所謂WebHookの一種であるSlack Events APIの使い方をまとめていきます。
1. Slack Appの作成
Slack Events APIを使用するためには、まずSlack Appを作成する必要があります。
① Slack API の公式サイトにアクセス(サインインした状態で)し、「Your Apps」に移動
⑤ 無事にアプリが作成されると「Basic Information」というページに遷移する
次に、サイドメニューから「OAuth & Permissions」をクリックして、アプリに必要な権限設定に進みます
2. 権限の設定
作成したSlack Appに必要な権限を設定します。
① 「OAuth & Permissions」ページを下にスクロールし、「Scopes」セクションで、アプリに必要な権限の範囲を設定します。
(Slack Appのボットが行う操作に必要な一般的な権限はボット権限 (Bot Token Scopes)に追加します。)
⚠️ユーザー権限 (User Token Scopes)とボット権限 (Bot Token Scopes)について
- ユーザー権限 (User Token Scopes)
- 個々のユーザーに関連する情報や操作が可能です。
- ユーザーの個人情報にアクセスするための権限が含まれます。例えば、users:read スコープを使用すると、ユーザーの基本情報を取得できます。
- ユーザートークンを使用すると、そのユーザーがアクセスできるすべての情報や操作が可能になります。これには、ユーザーが参加しているすべてのパブリックチャンネルの情報を取得することも含まれます。
- ボット権限 (Bot Token Scopes)
- Slackアプリのボットが行う操作に必要な権限です。
- ボットはプログラムによって制御され、与えられた権限に基づいてのみ操作を行います。
- 例えば、chat:write スコープを使用すると、ボットがチャンネルにメッセージを投稿できるようになります。
- ボットトークンを使用すると、ボットが参加しているチャンネルの情報のみを操作や取得が可能です。
- トークンの種類とスコープの違い
- ユーザートークンは、特定のユーザーができる操作をアプリが代行できるようにします。これにより、ユーザーがアクセスできるすべての情報や機能にアプリがアクセスできるようになります。
- ボットトークンは、アプリがSlack内で自動化された活動を行うために使用されます。ボットは、そのトークンで許可された操作のみを実行できます。
② 「Add an OAuth Scope」ボタンをクリックして必要なスコープを追加
主なスコープの説明
-
channels:history
このスコープは、ボットがパブリックチャンネルのメッセージ履歴にアクセスするために必要です。メッセージを読み取る際に使用します。 -
chat:write
ボットがチャンネルにメッセージを投稿するために必要なスコープです。メッセージを送信する機能を実装する際に必要になります。 -
app_mentions:read
ボットが自身へのメンションをリアルタイムで読み取るために使用します。ボットがメンションされた際に反応する機能を持たせたい場合に必要です。 -
im:history
ボットがダイレクトメッセージの履歴にアクセスするために必要なスコープです。プライベートな会話の内容を取得する場合に使用します。
※ 公式サイトのPermission scopesから権限一覧を確認できるので、必要な権限を追加しましょう
③ スコープを追加したら変更を保存し、ページ上部までスクロールを戻し、「Install to Workspace」ボタンをクリックして、アプリをワークスペースにインストールします。
これにより、新しい権限がアプリに適用されます。
3. Bot User OAuth Tokenの取得
Slack Appをワークスペースにインストールした後、ページに表示される「Bot User OAuth Access Token」をコピーしておきます。(必要であれば)
⚠️Bot User OAuth Access Tokenとは
SlackのWeb APIを使用する場合、Bot User OAuth Access Tokenが必要です。
Events APIを使用して単にイベントを受け取るだけであれば、トークンは必要ありません。
つまり...
-
Events API
- Slackからのイベント(例えばメッセージが投稿されたときなど)を受け取るために設定します。
- このAPIは、指定されたURL(あなたのサーバー上のエンドポイント)にHTTP POSTリクエストを送信してイベントを通知します。
- このプロセスにはトークンは不要です。
-
Web APIの使用
- Slackの機能をプログラム的に操作するためにAPIを呼び出す際には、Bot User OAuth Access Tokenが必要です。
- これにはメッセージの送信、チャンネルの管理などが含まれます。
したがって、もし単にEvents APIを使ってSlackからのイベントを受け取り、それに基づいて何か処理を行うだけであれば、トークンは必要ありません。
しかし、そのイベントに応じてSlackに対して何かアクションを起こす(例えばメッセージを送るなど)場合は、そのアクションを認証するためにトークンが必要になります。
4.Event Subscriptionsの登録
作成したSlack Appに「トリガーとなるイベント」と「実行させたい処理のエンドポイント」を設定します。
① 「Event Subscriptions」ページを開き、「Enable Events」をオン
② リクエストを受け取るエンドポイントのURLを「Request URL」に入力します。
(このURLは、Slackからのイベントを受け取るためのものです。)
③ URLを入力すると、Slackはそのエンドポイントに一時的な検証リクエストを送信し、応答を確認します。
このプロセスはURLの検証と呼ばれ、エンドポイントが正しく設定されていることを確認するために必要です。
...???
どういうことかというと...
Slackから「あるパラメーター」が送られてくるので、それをそのまま「レスポンスとして返す」コードを書いておき、その状態で一度URLを設定する必要があるのです。
これだけだと何のことか分からないので、URLの検証については、次でもう少し詳しく記載していきます。
URLの検証プロセス
Slackは、設定されたRequest URLが正しいかどうかを確認するために、以下のステップでURL検証プロセスを実施します。
(1) URL設定
Slackアプリの設定ページで、Events APIのRequest URLを入力します。
(2) 検証リクエストの送信
SlackからそのURLに対してHTTP POSTリクエストが送られます。
このリクエストには、以下JSON形式のパラメータが含まれています。
{
"token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
"type": "url_verification"
}
(3) レスポンスの返送
サーバーは、受け取ったchallengeパラメータをそのままレスポンスとして返す必要があります。
(4) 検証の完了
Slackは返されたchallengeパラメータを確認し、一致する場合はURLが正しく設定されていると認識されます。
この検証プロセスにより、Slackはイベントデータを送信する先が正しいサーバーであることを確認します。
URL検証は、Request URLを初めて設定する際、またはRequest URLを変更した際にのみ行われるので、一度検証が成功すれば、その後は同じURLに対して再度検証を行う必要はありません。
※ 詳細は公式サイトのURL verification handshakeを参照
コードの実装例
URL検証に対応したコードの実装例です。Goで書くとこんな感じになると思います。
1.Slackから受け取ったパラメーターをそのまま返す処理
func SlackURLVerification(w http.ResponseWriter, r *http.Request) {
// Slackからのリクエストを格納する構造体
var reqBody struct {
Token string `json:"token"`
Challenge string `json:"challenge"`
Type string `json:"type"`
}
// HTTPリクエストからボディを読み込む
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "could not read request body", http.StatusBadRequest)
return
}
// リクエストボディを構造体に変換
if err := json.Unmarshal(body, &reqBody); err != nil {
http.Error(w, "could not decode request body", http.StatusBadRequest)
return
}
// リクエストのタイプがURL検証(url_verification)の場合は、チャレンジ(Challenge)を返す
if reqBody.Type == "url_verification" {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(reqBody.Challenge))
return
}
}
2.上の処理をサーバーのエンドポイントに設定する
package main
func main() {
port := 4000
// SlackEventAPIのエンドポイントの設定
http.HandleFunc("/slack/events", func(w http.ResponseWriter, r *http.Request) {
SlackURLVerification(w, r)
})
// CORSの設定
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowCredentials: true,
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
})
httpHandler := c.Handler(http.DefaultServeMux)
// サーバーの起動
err = http.ListenAndServe(":"+strconv.Itoa(port), httpHandler)
if err != nil {
log.Fatalf("failed to start HTTP server: %v", err)
}
}
⑤ URL検証に対する準備ができたら、再度URLを設定します。
正しくレスポンスを返すようにコードを書いていれば、認証が通り「Verified」が表示されます。
⑥ 「Subscribe to bot events」の登録
画面を下にスクロールして「Subscribe to bot events」セクションで、「Add Bot User Event」ボタンをクリックします。
⑦ 上で登録したRequest URL(エンドポイント)に対してHTTPリクエストを送信するトリガーとなるイベントを登録します。
例えば、メッセージがチャンネルに投稿されたときをトリガーとして処理を実行させたい場合は、message.channels
イベントを追加します。
※ 公式サイトのEvent typesからイベント一覧を確認できるので、必要なイベントを追加しましょう
この画面の「Required Scope」が、「2.権限の設定」で設定したScopeに含まれている必要があります。
もしも設定が足りない場合、再度「2.権限の設定」に戻り設定を追加してください。
⑧ 設定が完了したら、「Save Changes」ボタンをクリックして設定を保存します。
ここまでで、Slackサイト上での設定は完了です!
5.Slackのチャンネルにアプリを追加する
① チャンネルの詳細から作成したSlack Appをチャンネルに追加します。
② これで、特定のイベントに基づいて(今回の例だと「チャンネルにメッセージが投稿されるたび」)に、登録したエンドポイントの処理が実行されるようになります。
6.おわりに
今回の記事では、あくまでもEvents APIの導入の仕方までにとどめ、Slack Web APIの使い方については別にしたいと思います。
なお余談ですが、サーバーエラー時などのSlack Events APIのリクエスト再送の仕様などについては、下記記事を参考にしていただくと良さそうです。
最後まで当記事をご覧いただきありがとうございました