RELATIONS Developers Blog

RELATIONS株式会社の開発ブログです。

SlackのHome tabがBeta版で使えるようになっていたのでSlack BoltでTODOアプリを作ってみました

f:id:yoshhiide:20191111193224p:plain

こんにちは。最近RELATIONSにジョインしました鍋山です。
RELATIONSではSlackを連絡手段として使っていて、エンジニアや大多数を占める非エンジニア全員で活発にやりとりしてます。
さて、僕自身がSlackに入門して1ヶ月ほど経ちましたので、どんなことができるのかを試してみる目的でとりあえずTODOアプリを作ってみました。

今回使用した機能はHome tabというBeta版(2019/11/11時点)でリリースされた、Slack上で表示できるWEBアプリライクな機能です。
実際に便利なものだと思っているのですが、Beta版なので今後どうなるかはわかりません。

Home tabとは

従来はアプリのアカウントを選択すると、DMができるようになっていました。
同じページで「ホーム」タブが追加されるようになります。
「ホーム」タブを表示するには、設定ページのFeaturesのApp Homeの設定をオンにする必要があります。(後述します)

f:id:yoshhiide:20191111182918p:plain

参考ページ:Home is where the tabs are | Slack

Block Kit Builderでも対応

Block kit BuilderでもHome tabの対応がされており、「App Home Preview」を選択することができます。 そうすると、GUIの操作でHome tab用のblockを構築していくことができます。

f:id:yoshhiide:20191111183027p:plain

参考ページ:https://api.slack.com/tools/block-kit-builder?mode=appHome
サインインしないと見られない可能性があります

Slack BoltでTODOアプリを作ってみる

今回はNode.jsでBoltというSlackのアプリを開発しやすくしたライブラリを使って開発してみました。 Boltについては公式ドキュメント(https://slack.dev/bolt/ja-jp/tutorial/getting-started)を参考にしています。

完成したアプリの動作はこちらのようになりました。 home-tab-todo

完成後のコードはこちらになります。

github.com

今回はmacOSで開発しています。

Home tabを使う為の設定

Boltを使用する為なのか、botのscopeが必要となりますが、今回のTODOアプリでは対話は発生しません。
今回の最低限の設定はこちらのようになりました。

f:id:yoshhiide:20191111183635p:plain

f:id:yoshhiide:20191111183647p:plain

f:id:yoshhiide:20191111183657p:plain

f:id:yoshhiide:20191111183709p:plain

f:id:yoshhiide:20191111183722p:plain

f:id:yoshhiide:20191111183732p:plain

Block Kit BuilderでHome tab用のblockを作る

Block KitというのはSlackアプリのUIフレームワークとのことです。
blockはSlackアプリを構築する際に機能する再利用可能なコンポーネントです。

Block Kit BuilderでHome tabで表示するUIを作ると、実際のコードに埋め込む為のオブジェクトが生成されていますのでコピーして使用することができます。

参考ページ:https://api.slack.com/tools/block-kit-builder?mode=appHome
サインインしないと見られない可能性があります

TODOアプリでは固定された部分と、動的に変化する一覧部分がありましたので二つに切り分けて作りました。

固定されたblock部分。
f:id:yoshhiide:20191111184727p:plain

内容を仮とした動的に変化するblock部分。 f:id:yoshhiide:20191111184749p:plain

利用者が「ホーム」タブを選択した際に、Home tabのviewを表示する

ここからは具体的なコードを示しますが、より全体を見たい方はGitHubのリポジトリ(https://github.com/relationslab/slack-home-todo)をご覧ください。 本記事では要所要所のみ切り取って紹介させていただきます。

「ホーム」タブを選択した際にapp_home_tabイベントを受け取り、Home tab内容を表示します。
ここでのapp_home_tabというイベント名はHome tab用のイベントのようです。

  // ホームタブを開いた際に発生するイベントをキャッチする
  app.event('app_home_opened', async ({ event, context }) => {
    if ('home' === event.tab) {
      // HomeTabを表示する
      await app.client.views.publish({
        token: context.botToken,
        user_id: event.user,
        view: {/* home用のオブジェクトを渡す */},
      });
    }
  });

ここではHome tabを表示する際にviews.publishメソッドを使用していますが、更新する場合も同じようにviews.publishメソッドを使います。(後述します)

Block Kit Builderでモーダル用のblockを作る

Home tab用のblockを作ったように、モーダル用のblockを作ります。
先ほどとは違い、左上のプルダウンメニューから「Modal Preview」に切り替えるようにする必要があります。
f:id:yoshhiide:20191111184822p:plain

利用者が「TODOを作る」ボタンをクリックした際に、モーダルを表示する

Home tabから「TODOを作る」ボタンをクリックした際に、そのアクションを受け取り、モーダルを表示させます。 ここでは、Home tabのblockのaction_idにアクションIDを埋め込んでいます。 「TODOを作る」のblockにはhome_todo_addというアクションIDを埋め込みましたので、そのアクションをキャッチする必要があります。

  // HomeTabから「TODOを作る」を選択した場合、モーダルを表示させる
  app.action('home_todo_add', async ({ body, ack, context }) => {
    ack();
    // モーダルを表示させる
    await app.client.views.open({
      token: context.botToken,
      trigger_id: body.trigger_id,
      view: {/* モーダル用のオブジェクトを渡す */},
    });
  });

利用者が「この内容で作成する」ボタンをクリックした際に、入力内容を取得してHome tabのviewを更新する

モーダルからTODOの内容を記入後、確定させる為に「この内容で作成する」をクリックした際に、そのイベントを受け取り、Home tabのTODO一覧を更新します。 モーダルの場合は、モーダルのblockに埋め込んだcallback_idをイベント名としてキャッチする必要があります。 新規TODOの作成のモーダルにはmodal_todo_add_doneというcallback_idを埋め込みましたので、そのイベントをキャッチします。

  // 新規TODOの作成モーダルで「この内容で作成する」を選択した場合
  app.view('modal_todo_add_done', async ({ ack, body, context, view }) => {
    ack();

    // モーダル入力値取得
    const val = _.get(view.state.values, ['todo_input', 'input_value', 'value']);

    // HomeTabを更新する
    await app.client.views.publish({
      token: context.botToken,
      user_id: body.user.id,
      view: {/* Home tab用のオブジェクトを渡す */},
    });
  });

利用者がTODO一覧から「完了」ボタンをクリックした際に、対象に斜線を付けてHome tabのviewを更新する

Home tabの動的内容となるTODO一覧から「完了」ボタンをクリックした際に、Home tabeからのアクションを受け取り、対象に斜線を付けてHome tabのTODO一覧を更新します。 Home tabの「完了」のアクションIDにはhome_todo_completeを埋め込んでいますので、それをキャッチします。

  // HomeTabのTODO一覧からタスクの「完了」を選択した場合
  app.action('home_todo_complete', async ({ ack, body, context }) => {
    ack();

    // HomeTabを更新する
    await app.client.views.publish({
      token: context.botToken,
      user_id: body.user.id,
      view: {/* Home tab用のオブジェクトを渡す */},
    });
  });

完成!

ワークスペース単位で管理するTODOアプリが完成しました! home-tab-todo

完成後のコードはこちらになります。

github.com

本記事に載せていないコードもありますので、実際に試してみたい方はGitHubのリポジトリを見てみてください。

試してみた感想

だいぶエンドユーザーに寄り添った機能だと思いました。
社内用のボットを作ろうとしていたのですが、最初にエンドユーザーがアプリ/ボットを操作する際のトリガーをどうしようかと悩んでいたところにHome tab機能が出てきました。
ちょっとこれはすごいかも!試してみよう!と思ったことが今回のTODOアプリを作ったきっかけでした。
Beta版としてのリリースということからかモバイルアプリでは使用できない機能ですが、まだ機能拡張があるのではないかと今後の様子を注視したいと思いました。