コネヒト開発者ブログ

コネヒト開発者ブログ

Slack Block Kitを使って既存ツールをカッコよくしてみた

こんにちは、 BLUE GIANT SUPREME (7) (ビッグコミックススペシャル)を読みました。金城(@o0h_)です。
読後、へーしゃで称賛が発生していました。

f:id:o0h:20190303130444p:plain
こちら、社長と私です

そんな感じで色々にSlackを利用している身のものですが、先月「新しい機能をリリースしたよ!」という発表がありました。
「Block Kit」です。

Block Kitは、「Slack投稿の表現力を上げる」「ユーザーと、より気の利いたインタラクションをつなぐことを支援する」ための新UI(のためのAPI)です。
これを利用すると、いつものSlackの投稿がとても高機能になります。

実際に触ってみたので、使い方やハマったポイントなどを共有していきます。

https://cdn-mamari.imgix.net/authorized/5c7ccc81-7170-439c-8949-0034ac110003.jpg

Hello! Block Kit

例えば、実際にBlock Kitでできること = 「いち投稿上でやり得ること」は、次のようなイメージになります

f:id:o0h:20190303135424p:plain
サムネイル画像を埋め込んだり、2列組ブロックを使ったり、ButtonやContext Menu等の操作用UIをくっつけたり・・

f:id:o0h:20190303135156p:plain
コンテンツのグルーピングのための区切り線を使ったり、「本文」と「副文」を別々に扱ったり、プライマリな操作UIをつけたり

今までより、かなり出来ることが増えたな!というのが伝わってくるのではないでしょうか。

私は、この新リリースをSlack Platform BlogのRSSフィードが流れてきたので知る事になりました。
未読でしたら、一度ぜひ目を通してみていただく事をお勧めします。

medium.com

リリース後、Slackチームは積極的にBlock Kitの宣伝をしている印象を受けます。
「Block party」を皮切りに、ちょっと観点を変えながらこの歓迎すべき新機能についての説明エントリーをあげていますね。
実際に読んでみて個人的に感じたのは、

というような、少しずつステップアップしているような内容になっているのかなーということです。

具体的に、何なんですか?

機能概要みたいなところは、2月のPHP勉強会東京でも個人的にLTをさせていただいたところです。
よろしければ、発表資料もご覧ください。
発表に使った資料@Speaker Deck

Block Kitは、一言で言えば 「layout block」と「block element」の集合として、投稿を定義していくAPI と言えると思います。
Elementは、Blockに梱包するサブ要素です。
そして、これらの要素にいろいろな「Type」があるため、すご〜い!いろんな事ができるんだね!!という結果が導かれるわけです。
Blockは、投稿系のAPI(例えば chat.postMessage)に拡張されたフィールド blocks に配列として注入することでハンドリングされます。

イメージを具体化してみましょう。
Slackが Block Party に合わせてBlock KitのUIビルダー「Block Kit Builder」を提供しています。
いくつかテンプレートがあり、そのうちの1つが「Search Results」です。
実際に組み立てられたUIは、以下のようになります。

f:id:o0h:20190303140051p:plain
Example message for seeing top search results and browsing additional info.

これらが、「Block」&それに属する「Element」で構成されているわけです。
このようなアウトラインとなります。

[
    { "type": "section", "accessory": {"type": "overflow"} },
    { "type": "divider" },
    { "type": "section", "accessory": {"type": "image"} },
    { "type": "context", "elements": [ {"type": "image"}, {"type": "plain_text"} ] },
    { "type": "divider" },
    { "type": "section", "accessory": {"type": "image"} },
    { "type": "context", "elements": [ {"type": "image"}, {"type": "plain_text"} ] },
    { "type": "divider" },
    { "type": "section", "accessory": {"type": "image"} },
    { "type": "context", "elements": [ {"type": "image"}, {"type": "plain_text"} ] },
    { "type": "divider" },
    { "type": "actions", "elements": [ {"type": "button"} ] }
]

section image button といった「要素」があることが、何となく見て取れるでしょう。

実画面との対応について、一部を示します。 *1

f:id:o0h:20190303142952p:plain

こうしてみると、「いかにリッチな表現ができるようになったのか」がわかりやすいのではないでしょうか。

使ってみた

折角こんなに面白そうなので、実際に試してみることにしました。
当ブログでも何度か紹介している社内ツールをいじってみます。

tech.connehito.com tech.connehito.com

  • ツールの概要
    • ナレッジやユビキタスその他を、Slack上から簡単に出し入れできる機能を提供するツール
  • 今回やること
    • 「検索」系の機能の改修
    • Before
      • 該当したアイテムが、セレクトメニュー(Attaching interactive message menus | Slack)に一覧表示される
      • ユーザーが任意のアイテムを選択
      • メッセージ本体の更新による結果表示
    • After
      • 該当したアイテムが、sectionブロックとdividerブロックによりサブジェクト+スニペット形式で表示される
      • show moreボタンの設置と、呼応して該当アイテムのコンテンツを追加投稿する

動作例

これが、以前の実装です

https://user-images.githubusercontent.com/907122/53692227-90e59380-3dcf-11e9-8bca-f94633d9ba68.gif

Block Kitを使って、ちょっとかっこよくしてみました

サーバーの処理遅延で、二重応答しているのはご愛嬌・・・💁

「表示する」ボタンを押す前に、一覧で表示される内容はスニペットです。先頭200文字程度で削っています。
コネヒトでの実際の利用動向を見ると、多くのものは「何かのURL」や「1文、もしくは2,3文程度の説明」であるものが多いので、実は文字数制限を加えた上での表示でも十分に事足ります。
今回の改修により、「わざわざユーザーの操作をせずに、一瞥して情報確認終わり!」という体験を得られやすくなりました。
また、section.accessoryによって「このブロックに対する操作」を明示したインタラクションが可能になったので、この「省略しつつ一覧表示」に踏み込めました。

総論として、Blocksの登場で、これまでよりも格段に「複数の情報の集合を適切に表示する」というのが容易になります。
確かに、今回の例に上げた程度の機能なら「今までのAPIでもほぼ同じことができたのでは」とも思います。それは実際に作ってみてから感じました。
ですが、Slack側から示された道によってインスピレーションが湧いた!!!というのは大きいです。
そういった背景も含めて「やりやすさ」が支援されたのではないでしょうか。

実装について

投稿メッセージにBlockを組み込むことに関しては、Block Builderを利用しながら感覚を掴むのが良いと感じます。
インタラクションに関する実装に関して、いくつか気づいたことやハマった点をまとめてみます。

  1. リクエストの受信
  2. 「なんの操作をしたか」は action_idにセットする
  3. blocksフィールドがあるとtextフィールドが無視される
  4. blocksのエラー内容が凄く親切
  5. リンク切れ画像を指定すると送信エラーとなる
  6. URLを含む投稿でも情報が自動展開されない
リクエストの受信

Interactive Componentsの例に漏れず、Slack App側で設定したエンドポイントに対してリクエストが送信されてきます。
その内容が、 type:block_actionsになっています。

実は、送信されてくるPayloadについてもBlock Kit Builderから知ることができます。
プレビューに表示されたボタンやメニューを操作してみてください。
すると、 Show Payloadボタンが現れます。

Buttonの操作時のPayloadを表示している様子

「なんの操作をしたか」は action_idにセットする

ユーザーインタラクションを求めるElementは、 action_id というフィールドを持っています。

api.slack.com

これは、「なんの操作をしたか」の識別子です。例えばHTMLのフォームで言えばname属性に当たります。
先ほど紹介した社内ツールの例では、「表示する」ボタンのaction_idは view-document としました。
同じくelement(Buttonや、Select Menuなら option objectのそれぞれ)にvalueをもたせられますので、これらを組み合わせて「document:211に対するview-documentをリクエストされた」といった判断ができるわけです。

blocksフィールドがあるとtextフィールドが無視される

これまで、 attachmentstextは共存可能でしたが、もしblocksが存在していると「本文」が表示されなくなるようです。*2
デスクトップアプリのNotificationにはtextのコンテンツが表示されるので、少し不思議な感じもするのですが。

例えば、Testツールから試してみた内容と実際に受信した内容が次のとおりです。 f:id:o0h:20190303154530p:plain f:id:o0h:20190303153839p:plain

blocksのエラー内容が凄く親切

コンテンツのバリデーションまでしっかり行った上で、「どこがおかしいか」を返してくれます。 f:id:o0h:20190303153946p:plain

リンク切れ画像を指定すると送信エラーとなる

Image Block、Image elementのいずれでも同様です。
Block(image)の場合、downloading image failed という内容でエラーとなります。
ただし、section.accessoryにimageを含めて取得失敗が生じた場合、Slackの返すエラー内容が少しあやふやなものになるので、注意が必要です。

f:id:o0h:20190303154128p:plain

今回、「ヒットしたアイテムに画像が含まれていたら表示する」という実装をしていたためにこの挙動は悩まされました。
最終的に、「投稿失敗時にエラーの内容を解釈し、該当するBlockを除去して再投稿」というリトライ機構を入れています。

URLを含む投稿でも情報が自動展開されない

これまでは、例えばchat.postMessagetextにURLを含めていた場合、画像や動画といったメディアであればそのコンテンツが表示されたらり、WebサイトであればOGPから情報が表示されていました。
Block Kitを利用すると、これらの情報が展開されないようです。
場面によってはしんどいかも知れません。

Block Kitの歩き方

実装において参考にしたリソースを列挙します。

  • Messaging for Slack apps | Slack
    • このタイミングで「メッセージ」全般に関して取り扱うセクションが登場しています。
    • 前提として、「今までのattachmentsやinteractive messagesで扱っていた領域を刷新しようとしている」点を抑えておくべきです。
    • すなわち、セクション自体は「New」なのですが、言及されているコンテンツが「すべて新しいこと」ではないということです。私は、「今まで○○で出来たとと何が違うの?」という発想で読もうとしてしまったため、無用に混乱していました。
    • 参考 : 以前のドキュメント An outmoded introduction to messages | Slack
  • Introducing Block Kit | Slack
    • api.slack.com 上にある、「Block Kitのトップページ」とでも言うべきページです。各種リソースへのリンクがまとまっています
    • なお、個人的には、とっかかりとして読むならこちらの記事よりも先述のBlock party – Slack Platform Blog – Mediumをオススメします。少しイメージを沸かせてからが良いのかな、と。
  • Block Kit Builder
    • Block Kitに実際に触ってみれるプレイグラウンドとして、非常にありがたいものです
    • Block Kit Builderは、ゼロから始めるタイミングでも実際になにか作ってみよう!というタイミングでも、最大の武器になると思います
  • Reference: Message layout blocks | Slack / Reference: Block elements | Slack及び Reference: Message composition objects | Slack
    • 実際に「Block KitのAPIリファレンス」として情報を求めるなら、これらのページになります
    • 「Block」と「Element」のリファレンスです
    • と、オマケ的にはなりますが「Object」も併記してみました。
      • Text ObjectやOption Object(セレクトメニューの中のオプション)はどうすればいいのか?はこちらを参照してください

「Block Party」のエントリーをまず読んで、その後にBuilderでUIやリクエスト内容を確認し、Block/Elementの詳細を確認しながら実際に投稿APIを叩いてみる・・・・みたいな流れが、最速でBlock Kitデビューを飾るための道かな?というのが所感です。

おわりに

基本的に「Slackで出来ることが増えると日常業務の革新につながる可能性がある」と思っているので、Slackは、私にとって大好きなおもちゃ箱でもあります!
今回言及したツールとは別に、個人的に作ってみているアプリケーションもあるので、Block Kitと仲良くなっていきたいな!と思っています。

*1:テキストデータについては、「blockのためのelement」ではなく、より横断的なレイヤーにある Message composition objectsにその定義が属しています

*2:探しているのですが、API Reference上での言及を見つけられていません。。。情報をお持ちでしたら、ぜひ聞かせてください!