Home タブ
App Home は、Slack の中でもユーザーにとってプライベートな、アプリと 1 対 1 で共有しているスペースです。各アプリの App Home は複数のタブを持つことができ、アプリのボットユーザーとの会話の履歴である Messages タブ、アプリによってユーザーひとりひとりにそれぞれ個別にカスタマイズされている Home タブがあります。
Slack アプリの設定
Home タブを有効にするには Slack アプリ管理画面にアクセスし、開発中のアプリを選択、左ペインの Features > App Home へ遷移します。画面を少し下スクロールすると見つかる Home Tab を有効化します。
イベント API を有効にするには、左ペインの Features > Event Subscriptions へ遷移します。この画面でいくつかやることがあります。
- Enable Events を Off から On にする
https://{あなたのドメイン}/slack/events
を Request URL に設定 (ソケットモードの場合、この手順は不要です)- Bot User Event を設定
- Subscribe to bot events をクリック
- Add Bot User Event ボタンをクリック
- app_home_opened を選択
- 最下部にある Save Changes ボタンをクリック
Bolt アプリがやること
Bolt アプリが Home タブの提供のためにやらなければならないことは以下の通りです。
- ユーザごとに Home タブを更新するために views.publish API メソッドを呼び出す
- Home タブ上で発生したユーザーインタラクション (
"block_actions"
,"block_suggestion"
) をハンドリング
よくある手法としては "app_home_opened"
のイベントを使って views.publish API メソッドを呼び出すきっかけに使うという実装があります。特に初回更新にはこのイベントの利用が必要です。しかし、それ以外のタイミング・手段で Home タブを更新することも全く問題ありません。
コード例
注: もし Bolt を使った Slack アプリ開発にまだ慣れていない方は、まず「Bolt 入門」を読んでください。
以下のコードは、ユーザーが App Home にアクセスして "app_home_opened"
イベントが発火したときに views.publish API メソッドによって Home タブを更新しています。views.publish の呼び出しが成功すれば、即座に Home タブの変更が反映されます。
import com.slack.api.methods.response.views.ViewsPublishResponse;
import com.slack.api.model.event.AppHomeOpenedEvent;
import com.slack.api.model.view.View;
import java.time.ZonedDateTime;
import static com.slack.api.model.block.Blocks.*;
import static com.slack.api.model.block.composition.BlockCompositions.*;
import static com.slack.api.model.view.Views.*;
// https://api.slack.com/events/app_home_opened
app.event(AppHomeOpenedEvent.class, (payload, ctx) -> {
// Home タブの view を構成
ZonedDateTime now = ZonedDateTime.now();
View appHomeView = view(view -> view
.type("home")
.blocks(asBlocks(
section(section -> section.text(markdownText(mt -> mt.text(":wave: ようこそ! (最終更新日時: " + now + ")")))),
image(img -> img.imageUrl("https://www.example.com/foo.png").altText("alt text for image"))
))
);
// Home タブをこのユーザーのために更新
if (payload.getEvent().getView() == null) {
ViewsPublishResponse res = ctx.client().viewsPublish(r -> r
.userId(payload.getEvent().getUser())
.view(appHomeView)
);
} else {
ViewsPublishResponse res = ctx.client().viewsPublish(r -> r
.userId(payload.getEvent().getUser())
.hash(payload.getEvent().getView().getHash()) // To safeguard against potential race conditions
.view(appHomeView)
);
}
return ctx.ack();
});
Kotlin で書いた同じコードは以下のようになります(参考:「Bolt 入門 > Kotlin での設定」)。
// static imports
import com.slack.api.model.block.Blocks.*
import com.slack.api.model.block.composition.BlockCompositions.*
import com.slack.api.model.view.Views.*
import com.slack.api.model.event.AppHomeOpenedEvent
import java.time.ZonedDateTime
// https://api.slack.com/events/app_home_opened
app.event(AppHomeOpenedEvent::class.java) { event, ctx ->
// Home タブの view を構成
val now = ZonedDateTime.now()
val appHomeView = view {
it.type("home")
.blocks(asBlocks(
section { section -> section.text(markdownText { mt -> mt.text(":wave: ようこそ! (最終更新日時: ${now})") }) },
image { img -> img.imageUrl("https://www.example.com/foo.png").altText("alt text for image") }
))
}
// Home タブをこのユーザーのために更新
val res = ctx.client().viewsPublish {
it.userId(event.event.user)
.hash(event.event.view?.hash) // レースコンディション防止のため
.view(appHomeView)
}
ctx.ack()
}
また、 Kotlin で開発しているなら、上記の例を Block Kit Kotlin DSL を使って以下のように実装することもできます。
// これらの import が必要です
import com.slack.api.model.kotlin_extension.view.blocks
import com.slack.api.model.view.Views.view
val appHomeView = view { it
.type("home")
.blocks {
section {
markdownText(":wave: Hello, App Home! (Last updated: ${now}")
}
image {
imageUrl("https://www.example.com/foo.png")
}
}
}
Bolt がやっていること
「イベント API」の同項目を参照してください。