🤖

【手順を解説】Slack CLIを使用して、担当者通知するSlackアプリを作成してみた

に公開

背景

あるとき、「平日のみ役割と担当者をローテーションして、結果をSlackで通知したい」という話になりました。
自動的に行う方法をAIに質問したところ、Slack + AWS(Lambda,EventBridge)が一次回答として得られましたが、AWSを用いることで、料金の面やプラットフォームの分散が気になりました。

Slackのみで完結できる方法に限定してAIに再度質問した結果、Slack CLIを使用してSlack App(アプリ)を作成するという方法があることを知り、採用することにしました。
実際に作成してみて、得た知見を共有したいと思います。

こんな人にオススメ

  • Slackのワークフローのみでは実現できない複雑な内容を自動化したい人
  • Slackのみで自動化を実現したい人
  • CLIの操作が好きな(得意な)人

作成したSlackアプリ

作成したSlackアプリの機能は以下です。

  • 平日の朝7:00(JST)に動作する。(定期実行)
  • 役割リストと担当者リストを参照し、紐付けを行う。
  • 役割に対し、必ず1人の担当者が紐付けされる。(担当者は2つ以上の役割を担当することもある。)
  • 実行されるごとに、紐付けが1つずつスライドする。
  • 結果は特定のSlackチャンネルに通知する。
    ※今回作成したSlackアプリは、正確にはSlack Workflow Appsに該当します。

作成したSlackアプリのGitHubリポジトリ
https://github.com/From-NULLHorizon/slack-assign-app

環境

Slackアプリを作成した環境について、簡単に記します。

  • 端末:MacBook Air
  • OS:macOS Sequoia 15.3.2
  • メモリ:16GB
  • Slack CLI:3.8.1
  • Deno Slack SDK
    • Deno:2.4.3 (stable, release, aarch64-apple-darwin)
    • JavaScriptエンジン:v8 13.7.152.14-rusty
    • TypeScript:5.8.3

Slack CLIとは

Slack CLIは、コマンドラインからSlackアプリを作成 / 管理するためのものです。
Deno Slack SDK / Bolt for JavaScript / Bolt for Python のいずれかと組み合わせて使用​​する必要があります。
https://docs.slack.dev/tools/slack-cli/

Denoとは

Deno(ディーノ)は、JavaScript / TypeScript / WebAssembly で書かれたコードを実行できるランタイムです。
ランタイム(正確にはランタイム環境)とは、プログラムを実行するために必要なソフトウェアやライブラリなどを備えた環境を指します。
つまり、Denoを用いることで、OSといった違いに関係なく、JavaScript / TypeScript / WebAssembly のコードを実行することができます。
https://deno.com/

Deno Slack SDKとは、Slackアプリ開発用のDeno SDK(Software Development Kit)のことです。
https://docs.slack.dev/tools/deno-slack-sdk/

前提条件

以下のプランや権限となっている必要があります。

  • Slack有料プラン:カスタム関数の利用や高度なスケジュール実行を行うために必要
  • ワークフローの作成 / 編集権限:Slackアプリの作成に必要
  • カスタム関数の作成 / デプロイ権限:Slack CLIを使用したSlackアプリの作成に必要

セットアップ

Slack CLIのインストール

Slack公式のCLIドキュメントを参考にインストールを行います。
ターミナル(またはコマンドプロンプト)を開き、以下のコマンドを実行します。

curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash

Denoのインストール

Slack公式のDenoドキュメントを参考にインストールを行います。
以下のコマンドを実行します。

curl -fsSL https://deno.land/x/install/install.sh | sh

Homebrewといった他のコマンドからでもインストール可能です。

インストールの確認

以下のコマンドを実行します。

slack --version
deno --version

ワークスペースへのログイン

  1. 以下のコマンドを実行します。
slack login
  1. 対話形式が始まり、/slackauthticket "認証コード"というような内容が出力されます。
  2. /slackauthticket "認証コード"をSlackアプリを導入したいSlackワークスペースの任意チャンネルまたはDMに入力します。
    (入力内容がチャンネルの他のメンバーに通知されることはないので安心です。)
    ワークフローの実行
    入力後のポップアップ表示
  3. 生成されたチャレンジコードを、Enter challenge code部分に入力します。
  4. ワークスペースへのログインが完了します。
  5. 確認のため、以下のコマンドを実行します。
    ※ワークスペース名やTEAM IDが確認できたらOK
slack auth list

プロジェクトの作成

任意の場所で以下のコマンドを実行して、Slackアプリのプロジェクトを作成します。

slack create assign-app -t https://github.com/slack-samples/deno-starter-template

作成されたプロジェクトディレクトリに移動します。

cd assign-app

作成直後の構成は以下のようになっています。

.
├── .devcontainer
│   ├── Dockerfile
│   ├── README.md
│   └── devcontainer.json
├── .gitignore
├── .slack
│   ├── .gitignore
│   ├── config.json
│   └── hooks.json
├── .vscode
│   └── settings.json
├── LICENSE
├── README.md
├── assets
│   └── default_new_app_icon.png
├── datastores
│   └── sample_datastore.ts
├── deno.jsonc
├── functions
│   ├── sample_function.ts
│   └── sample_function_test.ts
├── manifest.ts
├── triggers
│   └── sample_trigger.ts
└── workflows
    └── sample_workflow.ts

Slackアプリの作成

ここからは、作成 / 編集 したファイルの概要について説明します。
詳細な内容については公式ドキュメントを、詳細なソースコードについてはGitHubリポジトリを、それぞれ参照してください。

【再掲】Deno Slack SDK
https://docs.slack.dev/tools/deno-slack-sdk/

【再掲】作成したSlackアプリのGitHubリポジトリ
https://github.com/From-NULLHorizon/slack-assign-app

環境変数

プロジェクトディレクトリ直下に、環境変数ファイル(.env)を、以下の.env.exampleの内容を参考に作成します。

.env.example
# Slack Channel Configuration
# Slackチャンネルの設定
CHANNEL_ID=C0123456789

# Team Member Configuration
# チームメンバー(担当者)の設定
MEMBERS=A,B,C,D,E

# Role Configuration
# 役割の設定
ROLES=桃太郎,きび団子,いぬ,さる,きじ,赤鬼,青鬼

# Debug Configuration
# デバッグの設定
SLACK_DEBUG=false

# Environment Configuration(Slack CLIが自動設定)
# 環境設定(Slack CLIが自動で設定)
# SLACK_ENV=local
# SLACK_WORKSPACE=your-workspace-name

データストア

datastoresディレクトリ内に、slide_counter_datastore.tsというデータストアファイルを作成します。
データストアとは、Slackアプリ用のデータをSlackが管理するDynamoDBにホスティングさせる方法です。
データストアを用いることで、Slackアプリに関連するデータをSlack側で永続的に保持することができます。
slide_counter_datastore.tsで一例を挙げると、役割と担当者の紐付けを実行ごとに1スライドするために、前回実行時のスライド状態を保持するように設定しています。

カスタム関数

functionsディレクトリ内に、assign_function.tsというカスタム関数ファイルを作成します。
関数とは、Slackアプリの動作を定義するものです。
関数にはカスタム関数をはじめ、3種類が存在します。

種別 特徴
Slack関数 Slack固有の動作 チャンネルの作成やメッセージの送信など
コネクタ関数 Slack外のサービス固有の動作 GoogleスプレッドシートやMicrosoft Excelなどとの連携
カスタム関数 開発者固有の動作 任意の入力を渡し、コードで実装可能なあらゆる動作を実行し、出力を渡す

assign_function.tsでは、役割と担当者の紐付けや実行結果メッセージの整形などを行っています。

ワークフロー

workflowsディレクトリ内に、assign_workflow.tsというワークフローファイルを作成します。
ワークフローとは、順番に実行される関数の組み合わせのことです。
assign_workflow.tsは、まずassign_function.tsで定義したカスタム関数を実行し、次にSlack関数(SendMessage)を実行するという設定になっています。

assign_workflow.ts(抜粋)
// ステップ1:役割担当者割り当て関数を実行
const assignmentStep = AssignWorkflow.addStep(AssignFunction, {});

// ステップ2:結果をチャンネルに通知
AssignWorkflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: AssignWorkflow.inputs.channel_id,
  message: assignmentStep.outputs.result_text,
});

トリガー

triggersディレクトリ内に、assign_manual_trigger.tsassign_scheduled_trigger.tsという2つのトリガーファイルを作成します。
トリガーとは、ワークフローを実行するタイミングについて定義するものです。
それぞれのトリガーファイルの概要は以下です。

  • assign_manual_trigger.ts:ローカル環境用の手動トリガーファイル
  • assign_scheduled_trigger.ts:本番環境用の自動トリガーファイル

この先の手順では、Slackアプリをローカル環境で動作テストし、本番環境にデプロイします。
それぞれの動作環境に合わせたトリガーを用意するために、2つ作成しています。

マニフェスト

プロジェクトディレクトリ直下にある、manifest.tsというマニフェストファイルを編集します。
マニフェストとは、Slackアプリの名前やスコープ、使用する関数などを定義するものです。
これまでに作成した、データストア / カスタム関数 / ワークフロー を使用することを宣言し、スコープを設定します。
スコープが適切に設定されていないとSlackアプリの動作に必要な権限が足りず、ソースコードに問題がなかったとしても意図した動作にならないため、注意が必要です。

動作テスト

以下のコマンド実行して、動作テストを開始します。

slack run
  1. 対話形式が始まり、ローカル環境用のSlackアプリを選択するよう促されます。
  2. Create a new appを選択し、新規Slackアプリを作成します。(初回のみ)
  3. Choose a teamでは、slack loginで認証したワークスペースを選択します。(初回のみ)
  4. 新規Slackアプリに設定するトリガーについて聞かれるため、assign_manual_trigger.tsを選択します。(初回のみ)
  5. 問題なければ、URLが出力されます。
  6. URLを任意のSlackチャンネルに入力して、立ち上がったワークフローを実行します。
    ワークフローの実行
    Slackチャンネルでのワークフローの例
  7. 意図した動作であれば、(定期実行以外の確認が)OK
    1回目の実行結果
    1回目の実行結果
    2回目の実行結果
    2回目の実行結果
コラム:動作テストの補足情報
  • slack runコマンドは、”Ctrl+C”で終了します。
  • slack runコマンド実行中にカスタム関数やワークフローといったファイルの内容を編集したら、(再実行する必要なく)Slackアプリが自動更新されます。
  • slack runコマンドの良いところは、実行ログがターミナル上に出力されることです。
    → ログがあると、デバッグやエラー原因の特定がしやすい!
  • エラーが発生した場合、slack doctorコマンドでも原因を調査できます。

ワークスペースへのデプロイ

  1. 本番環境用のSlackアプリの作成
slack deploy

コマンドを実行すると、対話形式が始まります。
Choose a teamでは、slack loginで認証したワークスペースを選択します。
Create a new appDo not create a triggerを選択してください。
(環境変数の定義よりも先にトリガーを作成すると、エラーになるらしい。)

  1. Slackアプリの作成を確認
slack app list
コラム:Slackアプリ情報の確認ポイント

Slackアプリに対して紐付けるような認識で、環境変数やトリガーを設定します。
間違えてローカル環境用のSlackアプリに設定を行わないように、本番環境用のSlackアプリのApp IDを把握しておきましょう。

  1. 環境変数の定義
slack env add

コマンドを実行すると、対話形式が始まります。
Variable nameVariable valueに設定を行ってください。
(ローカルでの動作確認済みであれば、環境変数ファイルの変数名と値をコピペするだけです。)
環境変数の数だけ実行が必要です。

  1. 環境変数の設定を確認
slack env list
コラム:環境変数の確認ポイント

環境変数の値は、" *(アスタリスク)"でマスキングされた表示となるため、変数名の間違いや抜け漏れがないかを確認するようにしましょう。

  1. トリガーの設定
slack trigger create --trigger-def <trigger-file.ts>

<trigger-file.ts>部分は、設定したいトリガーファイル名を指定してください。
今回だと、assign_scheduled_trigger.tsです。
コマンドを実行すると、対話形式が始まります。
本番環境用のSlackアプリを選択し、トリガーを設定してください。

  1. トリガーの設定を確認
slack trigger list

コマンドを実行すると、対話形式が始まります。
本番環境用のSlackアプリを選択し、トリガーの設定を確認してください。

  1. Slackアプリの設定内容を更新
slack deploy

コマンドを実行すると、対話形式が始まります。
本番環境用のSlackアプリを選択してください。

  1. 動作の確認

トリガーで指定したタイミングまで待ち、意図した動作が行われるか、確認しましょう。
今回は、平日の朝7:00(JST)に動作する設定のため、以下のような動作結果になります。
1日目の実行結果
1日目の実行結果
2日目の実行結果
2日目の実行結果

更新作業

Slackアプリ作成後(初回実行後)、環境変数やトリガーを変更する場合の更新作業の手順について説明します。

ローカル環境用のSlackアプリ

  1. トリガーの削除:slack trigger delete
    ※トリガーの設定時に環境変数が読み込まれるため、環境変数を更新する度に(トリガー削除→トリガー設定を)行う必要があります。
  2. トリガーの設定:slack trigger create --trigger-def <trigger-file.ts>
  3. トリガーの設定を確認:slack trigger list
  4. 動作テストの実行:slack run

本番環境用のSlackアプリ

  1. トリガーの削除:slack trigger delete
  2. 変更する環境変数を除外:slack env remove
  3. 環境変数の除外を確認:slack env list
  4. 最新の情報で環境変数を再定義:slack env add
    ※変更がない環境変数については、再定義する必要はありません。
  5. 環境変数の設定を確認:slack env list
  6. トリガーの設定:slack trigger create --trigger-def <trigger-file.ts>
  7. トリガーの設定を確認:slack trigger list
  8. ワークスペースへのデプロイ(更新):slack deploy

まとめ

今回は、Slack CLIを使用してSlackアプリを作成し、更新管理するまでの一連の手順について説明しました。
functionstriggersといったコンポーネントに分離されているため、コンポーネントごとにカスタマイズすることで、また違ったSlackアプリが作成できそうです。(管理もしやすい☺️)
ワークフローのみでは実現できない複雑な内容を自動化したい際に、参考にしてみてください。

参考文献

Discussion