【Slack API】Home Tabの表示
はじめに
こんにちは!大ちゃんの駆け出し技術ブログです。
今回は前回の記事に引き続きEvent Subscriptionsについて書きたいと思います。
前回は「ユーザがメッセージタブでテキトーなメッセージを送信したイベント」を検知し、それをアプリ側にリクエストを送信、そしてアプリ側がレスポンスをメッセージタブに送信するというものでした。
・ユーザがメッセージタブでテキトーなメッセージを送信(イベント) ↓ ・Slackからリクエストを送信 ↓ ・アプリがレスポンス ↓ ・メッセージタブにメッセージが送信される
前回の記事はこちら!
今回の記事では「Home Tabを開いたイベント」を検知し、それをアプリ側にリクエストを送信、そしてアプリ側がレスポンスし、Home Tabにメッセージを表示する方法を紹介します!
・ユーザがHome Tabを開くイベント) ↓ ・Slackからリクエストを送信 ↓ ・アプリがレスポンス ↓ ・Home Tabにメッセージが表示される
対象読者
Home Tabとは
Home Tabとは、Slackのアプリ画面でSlackアプリを開いたときに最初に表示されるアプリの用途や使用説明、機能の一部などを表示したタブのことです。下記の例では「Slack Developer Tools」というSlackアプリのHome Tabです。
補足ですが、このHome Tabは開発する際任意につけられるもので、Home Tabが表示されていないSlack アプリもあります。例えば、有名なアプリ「Google Drive」は表示がされていませんでした。
実装に必要なAPI各種
app_home_opened
まずHome Tabを開いたというイベントを検知するためのEvent Subscriptionsです。Home Tabを開いたときのイベントを検知するためにはapp_home_openedをEvent Subscriptionsに設定します。
views.publish
Home Tabにメッセージを表示させたいときに使用する専用のメソッドとして、views.publishメソッドを使用します。
このメソッドを使うために必要なscopeはありません。
トークン以外の必要なArgumentsとして、user_idとviewが必要になります。
このviewですが、今まで投稿機能の時に使用していたBlock Kitとほとんど変わりません。異なる点として、今まではblocksの中身の配列を指定していましたが、type":"home"
を含めたJSONオブジェクトを指定する必要があります。Home Tabのオブジェクトであると区別するためですかね。
{ "type":"home", "blocks":[ { "type":"section", "text":{ "type":"mrkdwn", "text":"A simple stack of blocks for the simple sample Block Kit Home tab." } }, { "type":"actions", "elements":[ { "type":"button", "text":{ "type":"plain_text", "text":"Action A", "emoji":true } }, { "type":"button", "text":{ "type":"plain_text", "text":"Action B", "emoji":true } } ] } ] }
実装手順
それでは実装していきましょう!
※前回の記事で既にEvent Subscriptionsの設定を行いました。今回は同様のリクエストURLに送信するので、まだ行っていない人はこちらの記事を参照してください。
app_home_openedの設定
まずSlack アプリ開発画面からEvent Subscriptionsを設定します。
Subscribe to bot eventsのタブを開きます。
「Add Bot User Event」のボタンをクリックして、app_home_openedを検索。追加したら設定を保存するために「Save Changes」をクリックしてください。
これでアプリのHome Tabを開いたときにイベントが発生し、リクエストURLにリクエストが送信されます。
views.publish
あとはviews.publishを使用してHome Tabに表示させたいメッセージを表示します。
ただここで少しだけ注意が必要です。Event SubscriptionsのリクエストURLは一つしか設定できません。つまり、前回実装したテキトーなメッセージを送信するイベントのリクエストURLがアプリのURL/slack/events
だったのですが、今回のHome Tabを開いた時のリクエストURLも同様にアプリのURL/slack/events
となります。よって、同一のURLの中で条件分岐をする必要があります。
条件分岐をさせる方法として、Slackから送信されるパラメーターを使用します。今回の実装でHome Tabを開いた場合、下記のようなパラーメーターが送信されます。
{ "type": "app_home_opened", "user": "U061F7AUR", "channel": "D0LAN2Q65", "event_ts": "1515449522000016", "tab": "home", "view": { "id": "VPASKP233", "team_id": "T21312902", "type": "home", "blocks": [ ... ], "private_metadata": "", "callback_id": "", "state":{ ... }, "hash":"1231232323.12321312", "clear_on_close": false, "notify_on_close": false, "root_view_id": "VPASKP233", "app_id": "A21SDS90", "external_id": "", "app_installed_team_id": "T21312902", "bot_id": "BSDKSAO2" } }
"type": "app_home_opened"
とあるように、Home Tabが開いたイベントであることがわかります。
逆に、メッセージを送信したというイベントのパラメーターが下記になります。
{ "token": "one-long-verification-token", "team_id": "T061EG9R6", "api_app_id": "A0PNCHHK2", "event": { "type": "message", "channel": "D024BE91L", "user": "U2147483697", "text": "Hello hello can you hear me?", "ts": "1355517523.000005", "event_ts": "1355517523.000005", "channel_type": "im" }, "type": "event_callback", "authed_teams": [ "T061EG9R6" ], "event_id": "Ev0PV52K21", "event_time": 1355517523 }
"type": "message"
で、"text"
のパラメーターがあれば、それはテキトーに送信したメッセージであることがわかりそうですね。
よって条件分岐をすると下記のようになります。views_publish
メソッドにはもちろんHome Tabを表示させるメソッドを後述します。
def respond if params[:event][:type] == 'app_home_opened' views_publish elsif params[:event][:type] == 'message' && params[:event][:text].present? send_help_msg end end
条件分岐が完了したところで、いよいよAPIメソッドを使用してメッセージを表示させます。
先にコードを見せておきます。
def views_publish team = Team.find_by(workspace_id: params[:team_id]) user = User.find_by(uid: params[:event][:user]) return if team.nil? || user.nil? || team.workspace_id != user.team.workspace_id access_token = set_access_token(user.authentication.access_token) publish_to_home_tab(team, user, access_token) end def publish_to_home_tab(team, user, access_token) encoded_msg = encoded_home_tab_block_msg(team) access_token.post("api/views.publish?user_id=#{user.uid}&view=#{encoded_msg}&pretty=1").parsed end def encoded_home_tab_block_msg(team) channel_id = team.share_channel_id channel_name = team.share_channel_name msg = "{~~~~~~~~~~~~~}" encoded_msg = ERB::Util.url_encode(msg) encoded_msg end
まず、Slackアプリにユーザとチームが存在し、ユーザがチームに属しているはずですので、そうでない場合はreturnで処理を強制終了させます。
team = Team.find_by(workspace_id: params[:team_id]) user = User.find_by(uid: params[:event][:user]) return if team.nil? || user.nil? || team.workspace_id != user.team.workspace_id
その後access_tokenを取り出すメソッドを使用します。
access_token = set_access_token(user.authentication.access_token)
上述しましたviewですが、msgの箇所は長すぎたので割愛します。自分はかなり複雑なviewを設定しましたが、作り方は簡単です。block-kit-builderを使用して、タブにApp Home Previewを指定すると、Home Tabに表示したいJSONオブジェクトを簡単に作れます。
あとはAPIメソッドを使用してHome Tabにメッセージを表示させます。
access_token.post("api/views.publish?user_id=#{user.uid}&view=#{encoded_msg}&pretty=1").parsed
これで実装は終了です。実際にアプリのHome Tabを開いてみましょう。
実際に表示することができました!