SlackApp/APIの整理とメモ
当記事は、3ヶ月以上前に投稿されたものです。そのため、古い技術や情報をもとに書かれている可能性があります。参照する際は十分に注意していただければです。
はじめに
ここ最近、実務でSlackチャンネルへの通知要件がありSlack App/APIを触っていたのですが、よくよく考えると何となく雰囲気で使っていたと反省する一面が多く、今一度SlackApp/API周りの理解を深めようと思い、当記事ではいまいち分かってなかった部分を再整理して自身の理解をメモしています。
言及していないこと
以下は公式ドキュメントや他解説記事がいっぱいあるため言及しません。
- Slack Appの作り方
- Slack App/APIの細かいスコープ設定
メモ一覧
自身の疑問点を順に潰したため、繋がりなく項目を羅列しています
- 通知方法のベストは?
- 3つのSlack APIの違いは?
- 3つのトークンの違いは?
- Slack Appのセキュリティ対策
- Boltフレームワークとは?既存のNode SDKとの違いは?
通知方法のベストは?
Slack通知周りの初見殺しは結構罪深いと思っています。
Slack App ディレクトリにあるIncoming Webhooksで通知
Slack App ディレクトリにある公式から提供されたIncoming Webhooksがあります。 ただし、同Appは既に非推奨、将来的には削除される可能性もあるため、今後はまず使わないはずです。ところが、昔からある手法のため、まだ現役で動いているものもあるかと思いますが、はやめに移行することを勧めます。
自身のSlack AppでIncoming Webhooksを有効化して通知
上述のIncoming Webhooksは公式から提供されるAppを自身のワークスペースに連携する方法ですが、自身のAppを作成してそのApp上でIncoming Webhooksを設定することもできます。また、同方法は公式が推奨しています。
管理画面でIncoming Webhooksを各チャンネルごとに連携設定することで、そのチャンネルに対して通知ができるようになります。具体的には、各チャンネルごとにWebhooks URLが払い出されて、そのURLを各Saasもしくはアプリケーションに設定して通知を実現します。 さらに詳しい内容は、公式ドキュメントを参照ください。
自身のSlack Appで通知スコープを設定、対象のチャンネルにAppユーザーを連携して通知する
Slack Appを作成して通知用のchat:write
スコープを設定、対象のワークスペースに連携します。そして、個人的にはここが肝だと思っているのですが、通知したいチャンネルごとAppを連携追加します。これで、そのチャンネルにApp(Bot)から通知が送れるようになります。
channels:read
スコープを設定すれば、Appがパプブリックチャンネルにアクセスできるようになるため、上記の個別にAppをチャンネルに追加する設定はいらなくなるのですが、不必要なチャンネルにまでBotが通知できる状態は気分が良くないため、チャンネルごとに連携できるようにしています。
さらに詳しくは、公式ドキュメントを参照ください。
どの通知方法が良いの?
あくまでも私的見解ですが、3番目のSlack Appで通知スコープを設定、各チャンネルごとにAppを連携してあげる方法が良いと考えています。Incoming Webhooksの場合、飛ばしたいチャンネルごとにWebhooks URLが増えるて管理コストが高くなると考えていますが、上述の方法であれば、払い出されたトークンだけを管理すれば良いだけなので楽だと考えています。
ただし、他Saasと連携する場合は、Incoming Webhookを払い出して設定するだけで済む場合もあり(アプリケーションを書かなくて済む)、結局、目的に応じて柔軟に通知方法を選択できるかが鍵になるとも考えています
3つのSlack APIの違いは?
長らくSlackAPIを触っていてWeb API、Events API、RTM APIの違い、責務がよくわかっていませんでした。ひとまず、チャンネルに通知をしたいだけならWeb APIを使えばいいのだろう程度の理解でした。 公式の解説はコチラを参照ください。
Web API
Web API は、Slack 上でリッチなインタラクティブ・メッセージを送信する主な手段です。
要するにメッセージを送信するためのAPIです。
Events API
Events API は、イベント情報のサブスクリプションを使用して JSON ペイロードをサーバーに送信します。
何のこと?ということで、使用例を覗くと、「ユーザーがメッセージの投稿、チャンネルの作成や変更、ファイルの追加や変更を行った場合にイベントを受信する」とあり、つまりユーザーの何らかの動作によって、ここではイベントが発生したとしてJSONリクエストを受け取れるようにするためのAPIのようです。
RTM API
RTM (リアルタイムメッセージング) API は WebSocket を使用し、イベントを受信して Slack に簡単なメッセージを送信できます。
WebSocketを使うことでリアルタイムな通信を実現、Slackイベントを受信することができ、さらにメッセージ送信を行うこともできるようです。イベント受信ができるのはEvents APIと被っていますし、メッセージ送信はWeb APIの責務と被っているように見えます。
どうも、公式だと、RTMではWebSocket通信のせいで大量に不要な情報まで送信してしまうことがあり、Events APIを使うことを勧めています。
3つのAPIよりどう使うの?
RTMでは大量の情報を連続的に提供してしまい、普段のユーザアプリに組み込むのにはオーバースペック気味だったため、必要十分なリクエストだけを送るためのEvents APIが新しく作られたようです。詳しくはSlack公式記事を参照ください。
よって、メッセージ送信をしたいのであればWeb APIを、ユーザーイベントを受信して何らかの次のアクションを起こしたいのであればEvents APIを、RTM APIは手に余るので似たようなことをしたいのなら、Web/Events APIを組み合わせるのが良さそうです。
3つのトークンの違いは?
Slack AppではOAuthをもとに認可を行っており、Appに対してどのように振る舞わせたいかで幾つかのトークンが払い出されています。詳しい解説はコチラも合わせて参照ください。
Bot Tokens
まさにBot向けのためのトークンで、後述のユーザートークンとの違いは、そのAppをワークスペースにインストールしたユーザーのIDと紐付けがされないため、たとえそのユーザーがdeactivated
されてもBot Appとして生き残り続けられることです。
User Tokens
ワークスペースにAppをインストールしたユーザーのIDと結びつくため、そのユーザーが実行したかのように振る舞うためのトークンです。
App-level tokens
使用した機会はないですが、所属するOrganization全てのワークスペース、そしてそれに属する全てのユーザーに影響するトークンのようです。
結局どれ使うの?
基本的には、Bot Tokensを使って永続的にワークスペースで稼働するのを担保して、どうしても自身のユーザーとして振る舞わせたい時だけUser Tokensを使えば良いのかなと考えます。
Slack Appのセキュリティ対策
誰でもAppを簡単に作れるためセキュリティ周りは大丈夫なのかなと思いますが、そこにも対策が打たれているようです。
Slack Appのスコープ設定
これは基本中の基本ですが、Appが呼び出せるWeb APIやEvents APIのスコープを現在は必要に応じて設定することができます。以前はさまざまな権限と機能を扱えたボットトークン(スコープ)が提供されていましたが、その強強スコープを付与されたアプリをユーザーがリスクと捉えて使わなかったため、スコープを絞れるようにしたようです。設定できるスコープ一覧。
トークンにIPアドレス制限を設ける
CIDR表記でIP制限をかけることで、特定のIPからのみWeb APIリクエストを受け付けられるようです。最大で10個のIP範囲まで制限できるようです。詳しくは公式ドキュメントを参照してください。
リクエスト署名
リクエストが本当に意図したサーバから送信されたものかを確かめるのに、リクエスト署名検証がよく用いられますが、Slackでもサポートされています。詳しくは公式ドキュメントを参照ください。
Boltフレームワークとは?既存のNode SDKとの違いは?
少し複雑なAppを作ろうとすると、もちろんアプリケーションを書く場面が発生するのですが、その時に既存のSDKに対して、Boltがいることに違和感を感じるかもしれません。私は感じました
既存のNode SDK
SDKの役目そのままに、前述の3つのAPIを中心に、Python・JsvaScriptでプログラマブルにAPIを叩けるようにしたものです。実装の側面によると、モノレポ構成なため、叩きたいAPIに応じてどのpackageをインストールするかが決まります。Web APIなら@slack/web
、Events APIなら@slack/events-api
です。
Bolt
Boltは上述のAPI/SDKを更に使いやすくするためのフレームワークのようです。
ユーザーイベントを拾ってそれに応じたインタラクティブなアクションを起こすAppを作るのに、既存のSDKでは@slack/web
と@slack/events-api
をそれぞれインストール、更にドキュメントを詳細に追いかけて組み合わせる必要がありました。
ところが、BoltではそれぞれのAPI/SDKをうまくラップして、ややこしい設定やドキュメントを詳細に読まずとも簡単にAppが組めるようです。
ただし、Events APIは、イベントリクエストを受け取るために、常時サーバーとして稼働させておく必要があります。Slackへ一方的にアクションを起こすpush型のイベントでは、Events APIは必要ではなく、Web APIで事足りたりします。
そして、Boltはイベントを受け取るために常時httpサーバーを立てる前提なため、簡単な通知だけしたい時は@slack/web
で十分で、注意が必要だなと考えています。
おわりに
うーん、ややこしい
また、余談ですが、この手のSaas周りはユーザのAppを作成・公開できるようにプラットフォーム化するのが多くて、Appで実現できる幅と費用対効果が大きくなるにつれて、ゆくゆくはsalesforceエンジニアのようにslackappエンジニア的なのが現実味を帯びるのかなと思ったり思わなかったりでした。