大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【Slack API】Home Tabの表示

はじめに

こんにちは!大ちゃんの駆け出し技術ブログです。

今回は前回の記事に引き続きEvent Subscriptionsについて書きたいと思います。

前回は「ユーザがメッセージタブでテキトーなメッセージを送信したイベント」を検知し、それをアプリ側にリクエストを送信、そしてアプリ側がレスポンスをメッセージタブに送信するというものでした。

・ユーザがメッセージタブでテキトーなメッセージを送信(イベント)
↓
・Slackからリクエストを送信
↓
・アプリがレスポンス
↓
・メッセージタブにメッセージが送信される

前回の記事はこちら!

sakitadaiki.hatenablog.com

今回の記事では「Home Tabを開いたイベント」を検知し、それをアプリ側にリクエストを送信、そしてアプリ側がレスポンスし、Home Tabにメッセージを表示する方法を紹介します!

・ユーザがHome Tabを開くイベント)
↓
・Slackからリクエストを送信
↓
・アプリがレスポンス
↓
・Home Tabにメッセージが表示される

対象読者

  • SlackアプリをRailsで開発している人
  • Slack APIをある程度理解している人(scopeやEvent Subscriptionsの説明が必要ない人)

Home Tabとは

Home Tabとは、Slackのアプリ画面でSlackアプリを開いたときに最初に表示されるアプリの用途や使用説明、機能の一部などを表示したタブのことです。下記の例では「Slack Developer Tools」というSlackアプリのHome Tabです。

https://i.gyazo.com/c99c3e09ecc8cee9a04e9d505c00de77.png

補足ですが、このHome Tabは開発する際任意につけられるもので、Home Tabが表示されていないSlack アプリもあります。例えば、有名なアプリ「Google Drive」は表示がされていませんでした。

https://i.gyazo.com/380b4872bf03cc724418aab17dadac59.png

実装に必要なAPI各種

app_home_opened

まずHome Tabを開いたというイベントを検知するためのEvent Subscriptionsです。Home Tabを開いたときのイベントを検知するためにはapp_home_openedをEvent Subscriptionsに設定します。

api.slack.com

views.publish

Home Tabにメッセージを表示させたいときに使用する専用のメソッドとして、views.publishメソッドを使用します。

api.slack.com

このメソッドを使うために必要なscopeはありません。

https://i.gyazo.com/3334d8ae9d7ff43418ea800d112297cb.png

トークン以外の必要なArgumentsとして、user_idとviewが必要になります。

https://i.gyazo.com/41fa08a160ba40a795fb8ba14210af05.png

この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
               }
            }
         ]
      }
   ]
}

api.slack.com

実装手順

それでは実装していきましょう!

※前回の記事で既にEvent Subscriptionsの設定を行いました。今回は同様のリクエストURLに送信するので、まだ行っていない人はこちらの記事を参照してください。

sakitadaiki.hatenablog.com

app_home_openedの設定

まずSlack アプリ開発画面からEvent Subscriptionsを設定します。

https://i.gyazo.com/7e474b42237ad3731d4f104d373616e7.png

Subscribe to bot eventsのタブを開きます。

https://i.gyazo.com/f55b17bd2d03c0beaaeae7c5bd088e09.png

「Add Bot User Event」のボタンをクリックして、app_home_openedを検索。追加したら設定を保存するために「Save Changes」をクリックしてください。

https://i.gyazo.com/7b427baea0ecda8b76609254701126e9.gif

これでアプリの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オブジェクトを簡単に作れます。

app.slack.com

https://i.gyazo.com/7b4f93a857d9c8ba4a2b70612cc253d8.png

あとはAPIメソッドを使用してHome Tabにメッセージを表示させます。

access_token.post("api/views.publish?user_id=#{user.uid}&view=#{encoded_msg}&pretty=1").parsed

これで実装は終了です。実際にアプリのHome Tabを開いてみましょう。

https://i.gyazo.com/958e1cad50cfd165c2c059e1fc871d44.png

実際に表示することができました!