実装サンプル的記事は後日書きたい気がしますが、タイトル通り
Slack Appからボタン付きのメッセージを送信し、クリックイベントをサーバーで受信する
のに必要だった用語・知識などをまとめます。
Interaction受信URLの設定方法
ボタンやセレクトボックス等への操作(Interaction)に対する処理は、操作によって起こるHTTPリクエストをこちらが用意したサーバーで待ち受けることになります。
- App設定画面 > Interactivity & Shortcuts
- Interactivityの右上のOffをOnに
- Request URLに自分のサーバーのURLを入れる
- プレースホルダがhttpsになっていますがhttpでも大丈夫です
Interactionリクエストへのレスポンス
ステータス200を返さないとメッセージ側に⚠マークが出てしまうので200を返しましょう。
Blocksとは
メッセージ構造を定義するためのJSONです。
単純な文章はメッセージ送信時のtextプロパティだけで済みますが、ボタン等を使った複雑なメッセージを構築するにはJSONで表現し、blocksプロパティに入れて送信する必要があります。
公式のBlocks作成補助ツールBlock Kit Builderを見るとどういう意味かなんとなくわかると思います。
大雑把に言うとHTMLみたいなものだと思えば良いです。(JSONだけど)
tsとは
timestampの略で、チャンネルに対してユニークな所謂ID的存在です。
APIの各所で使われます。
例えば、chat.update APIでメッセージを編集するにはchannelとtsで対象を指定します。
ts is the unique (per-channel) timestamp.
最初リファレンスを読んでいて「ID的なものはどれなんだ」と迷ったのでtsがそれだと知っておくと話が早いです。
Incoming WebhookとpostMessage API
Incoming WebhooksとWeb APIのchat.postMessageはどちらもメッセージを送信する手段ですが、以下に示すような違いがあります。
- Incoming Webhook
- URLがわかればOAuthトークンが無くても送信できる
- 1つのURLがチャンネルと紐付いている
- (作ると自動でAppがチャンネルに参加する)
- レスポンスボディが「ok」だけで後でtsなどをメタデータを全く返さない
- chat.postMessage API
- リクエストにOAuthトークンを含める必要がある
- Appをチャンネルに参加させる必要がる
- レスポンスボディにtsなどのメタデータが入ったJSONが含まれる
Incoming Webhookでは送信したメッセージのtsが返ってこないため、
- Appのロジックからボタン付きメッセージを送信
- ユーザーがボタンをクリックしてサーバーがリクエストを受信
- (これにはtsが含まれる)
としたときに、1が複数ある場合どれの反応なのか突き合わせが難しいです。(補足後述)
2で送られてきたメッセージを更新するだけならクリックのペイロードに response_url
というものがありそこにPOSTすることでメッセージを更新できます。
しかしApp側でメッセージに対応するステートを管理したいような場合はtsを取れるchat.postMessageのほうが便利かと思います。
block_idとaction_id
[YES] [NO]のような複数のボタンを横に並べて1ブロックを作った場合
- block_idはblock全体1つ
- action_idはボタン1個に1つ
割り振られる要素となります。
そのblockの中でどのボタンが押されたかを識別するにはaction_idを使います。
action_idとvalue
プログラム側でどのボタンが押されたか確認するのに使えそうなプロパティとしてaction_idとvalueがあります。
Buttonのリファレンスと挙動調査によると以下のような違いがあります。
- action_id
- 必須?:Yes
- 最大255文字
- 省略してメッセージ送信するとランダムな値が割り振られる。
- value
- 必須?:No
- 最大2000文字
- 省略すると存在しなくなる。
action_idはリファレンスでは
Should be unique among all other action_ids used elsewhere by your app.
とありますが、試した所
- 同一ブロック内で同じaction_idを作ると送信エラー
- 同一メッセージ内別ブロックで同じaction_idを作るのはエラーにならない
という挙動でした。
なのでメッセージ内でユニークじゃなくてもblock_idとaction_idの組み合わせでボタンを特定できます。
必須である、最大文字数が少ないなどのことからボタンの特定はaction_idでやるように作られている気がしますが、valueでやっても別に問題なさそうに見えます。
でも公式のBlocks作成ツールBlock Kit Builderはaction_idでなくvalueを入れていて謎です。
補足:Incoming Webhookで突き合わせする方法
blocksのblock_idには任意の値を入れられ、かつクリック時のpayloadにそれが乗って返ってくるので、メッセージ送信時のblock_idに独自に採番した一意のIDを入れれば突き合わせることはできます。
操作のあるblockが1個だけのメッセージならそのblock_idを対象にすれば実質的にメッセージにIDをふっているのと同じような感じになります。
コメント