LoginSignup
5
3

More than 1 year has passed since last update.

Slack Platform(Next-Gen)ハンズオン

Last updated at Posted at 2022-12-10

はじめに

Slack Platform(Next-Gen) v1.15.0を試してみた記事です。最新のバージョンと挙動が異なる場合があるのであらかじめご了承ください。

クイックスタート(環境構築)

https://api.slack.com/future/quickstart

Step1: Automated Installerでやったらエラーになった(ログ取るの忘れた&どんなエラーか憶えてないです、すみません🙏)ので、Manual Installatonでやったら上手くいきました!

Step2,3と順当に進み、

Step4で

$ slack trigger create --trigger-def "triggers/greeting_trigger.ts"

を実行したら、slack CLIのバージョンアップ(v1.15.0→v1.16.4)が促され、Yを押したら

🚫  Error: This Slack API method does not exist or you do not have permissions to access it. (unknown_method)

Error Details:

1: This method does not exist. Please reach out to the admin to approve hosting custom TOS (unknown_method)

Suggestion:

An admin or owner on your workspace needs to have accepted the Slack Platform Beta Terms of Service here: https://slack.com/admin/settings#hermes_permissions

と出て失敗。(使っているslackワークスペースのadmin権限持ってる人に許可してもらわないといけなかった)

無視して、もう一度コマンドを実行したらアプデがスキップされ成功しました。
(ここで表示されるShortcut URLをメモ)

Step5でslack runしてローカルでサーバ立ち上げ、Step4でメモったURLをslack上に書き込むと
%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2022-11-23_10.51.42.png

ワークフローを実行するためのボタンが表示され、Botが動きました🙌
slack uninstallで”hello_world” Appは消しておきました

Slack Platformの概要

ハンズオンしてみて私がイメージした、Slack Botの基本的な概念はこんな感じです↓

  • Triggers
    • https://api.slack.com/future/triggers
    • その名の通り、Botが起動する最初のきっかけを定義する。
    • チャンネルに起動ボタンをつけてそれを押す(Link Triggers)とか、定期実行(Scheduled Triggers)などなど。
  • Workflows
    • https://api.slack.com/future/workflows
    • Triggersから呼ばれる、Bot処理の流れを定義するもの。
    • (例)トリガー発火→フォームを表示→データ処理→slackのチャンネルにメッセージ表示
  • Functions
    • https://api.slack.com/future/functions/custom
    • Workflowから呼ばれる、特定の処理をまとめて分割したもの。関数。Workflowからinputとして値をもらって、何らかの処理をしてoutputとしてWorkflowに返す。(input, outputは無くてもいい)
    • slackでよく使われる機能はBuilt-in functionとして予め定義されているのでそれを使うとベンリ:https://api.slack.com/future/functions

他にもこんなものも使います:

実装例: シャッフルランチBot

会社で使えるBotを一つ作ってみたのでそれをご紹介しつつ、詰まったところも書いておきます〜

全コードはこちら:
https://github.com/hirorocky/slack-future-hands-on

背景

  • 会社の人を3~4人にグループ分けして、ランチに行く文化がある。(シャッフルランチ)
  • slackには全社員所属している。グループ分けをslack上で実施&発表したい。
    • ※slack上にはシャッフルランチの選出から外したい社員もいるので、その辺は柔軟に設定できるようにしたい。

仕様

slack上のユーザーを登録して、登録されたユーザーをランダムにグループ分けするBot

  • ランチメンバーを指定して、登録できる
  • すでに登録されているランチメンバーを削除できる
  • すでに登録されているランチメンバーを一覧表示できる
  • すでに登録されているランチメンバーからランダムにグループを作れる
    • グループあたりの人数は3~4名
    • グループを作るときに3人グループと4人グループの数を指定できる
      • 計算でグループの数は分かるけど、あえて指定可能にすることで柔軟性を出したい

実装

Triggers

  • member_addition_shortcut
    • 「メンバー追加」ボタン
  • member_removal_shortcut
    • 「メンバー削除」ボタン
  • member_list_shortcut
    • 「メンバー一覧」ボタン
  • member_grouping_shortcut
    • 「メンバー分け」ボタン

Workflows

  • member_addition_workflow
    • ランチメンバーを追加するフロー
      • ユーザーを複数入力できるフォームを表示

        const inputForm = MemberAdditionWorkflow.addStep(
          Schema.slack.functions.OpenForm,
          {
            title: "追加するメンバー",
            interactivity: MemberAdditionWorkflow.inputs.interactivity,
            submit_label: "追加",
            fields: {
              elements: [{
                name: "members",
                title: "メンバー",
                type: Schema.types.array,
                items: { type: Schema.slack.types.user_id },
              }],
              required: ["members"],
            },
          },
        );
        
      • member_addition_functionを、フォームで入力されたユーザーをinputにして呼ぶ

      • member_addition_functionのoutputをメッセージとして表示(実行したユーザーにだけ見えるメッセージ)

        • Schema.slack.functions.SendEphemeralMessageを使えば、みんなから見えないメッセージを送れます
  • member_removal_workflow
    • ランチメンバーを削除するフロー
      • ユーザーを複数入力できるフォームを表示
      • member_removal_functionを、フォームで入力されたユーザーをinputにして呼ぶ
      • member_removal_functionのoutputをメッセージとして表示(実行したユーザーにだけ見えるメッセージ)
  • member_list_workflow
    • 現在登録されているランチメンバーを一覧するフロー
      • member_list_functionをinput無しで呼ぶ
      • member_list_functionのoutputをメッセージとして表示(実行したユーザーにだけ見えるメッセージ)
  • member_grouping_workflow
    • ランチメンバーをグループ分けするフロー
      • 3人グループと4人グループの数を入力できるフォームを表示
      • member_grouping_functionを、フォームで入力された数をinputにして呼ぶ
      • member_grouping_functionのoutputをメッセージとして表示

Functions

  • member_addition_function
    • ランチメンバーを追加する
  • member_removal_function
    • ランチメンバーを削除する
  • member_list_function
    • 現在登録されているランチメンバーを一覧する
  • member_grouping_function
    • ランチメンバーをグループ分けする

Datastores

  • ランチメンバー LunchMenbers
    • シャッフルランチの候補となるメンバー
    • attribute
      • user_id: slack.user_id(user_idはslackワークスペースでユニークなので自然キーとして使える)
const MemberDatastore = DefineDatastore({
  name: DATASTORE_NAME,
  primary_key: "user_id",
  attributes: {
    user_id: {
      type: Schema.slack.types.user_id,
    },
  },
});

しかし、上記実装だと上手くいかなかったです、(idが自動的に主キーになる?)
v1.17.0で修正されたかもです

仕方なくattributeにidをいれて、user_idが重複しないようにFunctionで登録前に確認するようにしました。

const MemberDatastore = DefineDatastore({
  name: DATASTORE_NAME,
  primary_key: "id",
  attributes: {
    id: {
      type: Schema.types.string,
    },
    user_id: {
      type: Schema.slack.types.user_id,
    },
  },
});

デバッグ用にDatastoresにアクセスできるCLIコマンドが用意されています!

slack datastore query '{"datastore": "members"}'     

詳しくはslack datastore helpなどで...

おわりに

datastoreの挙動に謎が残りましたが、全体的には快適に開発を進められました。ローカルに開発環境を構築してデプロイの前にいろいろ試行錯誤できたり、Typescriptの強力な型推論があったりとDXは高いと思いました。

GASやLambdaなどの外部サービスに頼ること無く、Slackだけで完結できるので、(従来のslack botの実装方法と比べて)シンプルになっていてGoodだと思います👍

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3