mcpField
D
deploy-slack-app

deploy-slack-app

github.com/slackapiクラウド・DevOps161114 回インストール2 日前に更新
リポジトリ

deploy-slack-app について

deploy-slack-appは、ローカルで動作確認済みのSlackアプリを、別のアプリとしてRailwayまたはHerokuに配置するためのスキルです。Slack CLIのデプロイフックでアプリトークンを渡し、ローカル開発用アプリも維持します。

主な機能

  1. 01Slack CLIのデプロイフックでスクリプトを実行
  2. 02RailwayとHerokuへのデプロイに対応
  3. 03Socket Modeと実行環境の前提条件を確認
  4. 04ローカル版とデプロイ版のSlackアプリを分離
  5. 05デプロイ後の稼働状況とSlackでの動作を確認

活用シーン

  1. 01ローカルで検証したSlackアプリを常時稼働するサービスとして配置
  2. 02Socket Modeアプリ向けにRailwayまたはHerokuを設定
  3. 03デプロイ後にSlack上で応答することを確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/slackapi/slack-skills-plugin --skill deploy-slack-app

インストール後、Claude Code で/deploy-slack-appを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
deploy-heroku.sh
deploy-railway.sh
heroku.md
railway.md

詳細

Slack アプリのデプロイ

ローカルで正常に動作する Slack アプリを、独自のアプリ ID を持つ別の Slack アプリとしてホスティングプロバイダーにデプロイし、開発者のマシンがなくても実行し続けられるようにします。ローカル開発用アプリには変更を加えません。2 つのアプリの共存方法については、Step 5: Deploy で説明します。slack:test-slack-app スキルでアプリが応答することを確認した後に行うステップです。

この仕組みでは、Slack CLI の deploy フックを使います。プロジェクトの .slack/hooks.json に deploy キーを追加すると、Slack 独自のホスト型デプロイが任意のスクリプトに置き換わり、CLI はデプロイ済みアプリを作成してインストールした_後に_そのスクリプトを実行します。この順序こそが、この方法を使う最大の理由です。スクリプトが実行される時点で、アプリのボットトークンとアプリレベルトークンはすでにスクリプトの環境変数として渡されているため、ここでシークレットの入力を求めたり、保存したりする必要はありません。

サポート対象のプロバイダーは 2 つです。どちらもアプリを長時間稼働するワーカープロセスとして実行します。

プロバイダープロセスタイプデプロイ元シークレット現在の料金
Railwayポートのバインド不要のサービス作業ディレクトリ標準入力で渡すhttps://railway.com/pricing
Herokuworker dynoコミット済みコードの git push引数として渡すhttps://www.heroku.com/pricing

デフォルトとしては Railway が適しています。その理由は Step 2a: Choose a Provider で説明します。


Step 1: 前提条件の確認

1a. Slack CLI の検出

slack:slack-cli スキル(Step 1: Detect the Slack CLI)を使って、公開 Slack CLI がインストールされているか確認し、コマンド名を特定します。フィンガープリントの確認、エイリアスへのフォールバック、インストール手順はすべてそちらに記載されています。内容を重複させないでください。以降は、特定したコマンドを SLACK_CMD として参照します。

これは見た目以上に重要です。マシンによっては、無関係な社内ツールが slack という名前でパスに登録されています。それを実行すると、デプロイがかなり進んでから分かりにくいエラーが発生します。

1b. アプリが Socket Mode を使用していることの確認

質問するのではなく、アプリのマニフェストを確認してください。 プロジェクトには使用するモードがすでに宣言されているため、ここで質問するのは不要です。manifest.json の settings.socket_mode_enabled を確認します。.slack/config.json でマニフェストのソースが remote に設定されている場合はローカルファイルがないため、代わりに SLACK_CMD manifest info で読み取ります。

  • Socket Mode が有効: 続行します。アプリは Slack への送信 WebSocket を開くため、パブリック URL は不要で、HTTP ポートもバインドしません。
  • Socket Mode が無効、またはアプリが Request URL を使用: ここで中止してください。 このスキルはまだ Request URL アプリには対応していません。ホストされた Request URL アプリでは、デプロイ後に取得したパブリックアドレスをアプリのマニフェストに書き戻す必要があるためです。これが未対応の点であり、現時点でサポートされている方法はアプリを Socket Mode に変換することだと、開発者にはっきり伝えてください。新しいバージョンの Slack Skills Plugin でサポートされている可能性があるため、開発者にプラグインを更新して再度試すよう依頼してください。すでに最新バージョンを使っている場合は、https://github.com/slackapi/slack-skills-plugin/issues/172 を案内し、リアクションを追加するかコメントを投稿してもらってください。

マニフェストから判断できない場合は、アプリのエントリーポイントを確認します。socketMode: true と appToken を指定して構築された Bolt for JavaScript アプリや、SocketModeHandler 経由で起動される Bolt for Python アプリは Socket Mode アプリです。

1c. ランタイムがサポート対象であることの確認

このフローは macOS と Linux で動作確認済みです。デプロイフックはシェルスクリプトのため、Windows の開発者には、まだ存在しない PowerShell 用の同等スクリプトが必要です。Windows の場合は、デプロイが途中で失敗する前にそのことを伝えてください。当面は WSL を利用できます。新しいバージョンの Slack Skills Plugin でサポートされている可能性があるため、開発者にプラグインを更新して再度試すよう依頼してください。すでに最新バージョンを使っている場合は、https://github.com/slackapi/slack-skills-plugin/issues/171 を案内し、リアクションを追加するかコメントを投稿してもらってください。


ステップ 2:プロバイダーとチームを選ぶ

プロジェクトからは分からないことを開発者に 2 つ尋ねます。デプロイ先のプロバイダーと、デプロイ先の Slack チームです。

2a. プロバイダーを選ぶ

費用は開発者がプロジェクトから推測できないため、どのプロバイダーを使うか尋ねます。現在の条件を確認できるよう、上の表にある両方の料金リンクを開発者に提示します。ページを取得したり、料金、プラン名、トライアル条件を引用したりしないでください。 プロバイダーは頻繁に内容を変更します。また、このスキルは作成からかなり時間が経ってからインストールされる可能性があります。

料金表が変わっても変わらず、伝えておく価値のあることは次のとおりです。

  • Railway をデフォルトで推奨します。標準入力からシークレットを受け取るため、トークンがプロセスの引数に現れません。作業ディレクトリをデプロイするため、再デプロイ時にコミットは不要で、Procfile も必要ありません。
  • Heroku は、開発者がすでにアカウントを持っている場合や、チームの標準でデプロイ先が指定されている場合に適しています。git からビルドするため、コミット済みのコードだけがデプロイされます。エンタープライズ管理のアカウントなど、一部のアカウントでは個人用アプリを所有できず、Heroku チームを作成する必要があります。個人用アプリとチームアプリではプランや請求が異なる場合があるため、こちらで決めずに、どのチームを使うか尋ねてください。共有チームの予算は共有されます。

どちらのプロバイダーもアプリを継続的に実行することを明確に伝えてください。これは Socket Mode アプリに必要です。常時稼働のホスティングは最終的に有料サービスとなるため、トライアル期間が終了すると費用が発生すると考えてください。

開発者がプロバイダーを選んだら、そのプロバイダーのリファレンスファイルを読み、記載に従います。references/railway.md または references/heroku.md を参照してください。各ファイルには、インストールと認証のコマンド、プロジェクトに対するプロバイダー固有の要件、デプロイスクリプトが読み取る環境変数が記載されています。ステップ 4:デプロイフックを設定するで、これらの手順を進めます。

2b. チームを選ぶ

SLACK_CMD auth list を実行します。チームが 1 つだけ表示された場合は、それを使います。複数表示された場合は、各チームの名前と ID を開発者に示し、デプロイ先を尋ねます。

チームを自分で選んではいけません。 スタンドアロンのワークスペースや Enterprise 組織を決めつけないでください。また、.slack/apps.dev.json のチームを再利用しないでください。これは開発者のサンドボックスであることがよくあります。誤った推測をすると、開発者が意図していないチームにアプリがインストールされ、後から正しいチームにデプロイした際に、2 つ目の Slack アプリが作成されます。


ステップ 3:まずローカルで動作を確認する

動作を確認していないアプリをデプロイしてはいけません。 プロバイダーのログでは、デプロイの不具合とアプリの不具合は同じように見えます。後から両者を切り分けるのは、先に確認するよりはるかに手間がかかります。

slack:test-slack-app スキルを使って SLACK_CMD run でアプリを実行し、少なくとも 1 つの実際の機能を試してください。これにより、デプロイ後に再確認できる正常な動作が分かります。使用した機能を記録してください。ステップ 6:デプロイを検証するでも、同じ機能を確認します。


ステップ 4:デプロイフックを設定する

設定するものは 3 つあります。書き込む前に、それぞれがすでに存在するか確認してください。 アプリの再デプロイはよくあるケースであり、開発者が編集したスクリプトを上書きすると復元できません。

4a. プロバイダーを準備する

選択したプロバイダーのリファレンスファイルに記載された手順を、何かを書き込む前に進めてください。デプロイスクリプトはこれらを確認するだけで、問題があれば停止します。スクリプトで修正することはできません。

  • プロバイダーの CLI をインストールして認証します。 whoami チェックを実行します。ログインするとブラウザーが開くため、チェックに失敗した場合は、自分で実行せずに、開発者自身のターミナルでログインコマンドを実行するよう依頼してください。
  • 開発者と名前および所有者を決めます。 Heroku の場合は、他と区別できるアプリ名と、アプリをチームに所属させるかどうか(heroku teams)を決めます。Railway の場合は、アカウントに複数あるときは使用するワークスペースを決めます。これらはステップ 5:デプロイでデプロイコマンドに指定する環境変数になります。
  • プロバイダーのプロジェクト要件を満たします。 Heroku の場合は Procfile を作成してコミットします。Railway の場合は、検出される起動コマンドを確認します。
4b. デプロイスクリプトを作成する

プロバイダーのデプロイスクリプトをプロジェクトの .slack/ ディレクトリに同じ名前でコピーし、実行可能にします。

  • Railway:references/deploy-railway.sh を .slack/deploy-railway.sh にコピーします
  • Heroku:references/deploy-heroku.sh を .slack/deploy-heroku.sh にコピーします

たとえば、chmod +x .slack/deploy-railway.sh を実行します。

各スクリプトは単体で動作します。2つのトークンがどちらも渡されていることを検証し、ログ出力に使うデプロイ済みアプリ ID を .slack/apps.json から読み込み、プロバイダーの事前確認、プロビジョニング、設定、デプロイの手順を順に実行します。ほかにコピーするものはありません。CLI はプロジェクトのルートからフックを実行するため、ファイルが .slack/ にあってもスクリプトの相対パスはルートを基準に解決されます。

スクリプトがすでに存在する場合は、開発者に存在することを伝え、上書きする前に確認してください。開発者が調整を加えている可能性があります。

4c. フックを登録する

既存の hooks オブジェクトに deploy キーを追加し、プロバイダーのスクリプトを指定します。Railway の場合:

"deploy": "./.slack/deploy-railway.sh"

Heroku の場合、値は ./.slack/deploy-heroku.sh です。get-hooks のエントリーはそのまま変更しないでください。 値は Bolt for JavaScript と Bolt for Python のプロジェクトで異なるため、別の場所からコピーしないでください。

すでに deploy キーがある場合は、2つ目を追加しないでください。 キーが重複すると JSON が無効になり、CLI はデプロイせずにプロジェクトを拒否します。既存のキーが選択したプロバイダーのスクリプトをすでに指定している場合は、そのままにします。別のプロバイダーのスクリプトなど、ほかのものを指定している場合は、開発者にそのことを伝え、変更する前に確認してください。


Step 5: デプロイする

プロジェクトのルートから SLACK_CMD deploy を実行し、出力を確認します。CLI はデプロイ済みアプリを作成してインストールし、その後フックスクリプトを実行するため、出力の前半はアプリのインストール、後半はプロバイダーのビルドになります。

インタラクティブではないターミナル(ほとんどのエージェントセッションを含みます)で実行する際は、4つのフラグが重要です。CLI は4つの質問をしますが、どれか1つでも回答されないと処理は失敗します。非インタラクティブシェルでは The input device is not a TTY or does not support interactivity が表示され、何もデプロイされません。

  • --skip-update は、CLI がアップグレードを提案して一時停止するのを防ぎます。
  • --team <team ID> はワークスペースまたは組織を選択します。Step 2b: チームを選択する で開発者が選んだチームを使います。
  • --app deployed はデプロイ済みアプリ環境を選択し、初回デプロイ時にはそのアプリを作成します。これを指定しないと、CLI は既存アプリと新規アプリのどちらを選ぶか開発者に尋ねます。このフラグは最も忘れやすいものです。対応するプロンプトが表示されるのは、まだ一度もデプロイされていないプロジェクトだけだからです。
  • --org-workspace-grant all は、組織にインストールされたアプリのワークスペース権限のプロンプトに回答します。

したがって、コマンド全体は SLACK_CMD deploy --skip-update --team <team ID> --app deployed --org-workspace-grant all です。

Step 4a: プロバイダーを準備する で決めたプロバイダー変数があれば、コマンドの前に置きます。フックは CLI の環境変数を引き継ぐため、この方法でスクリプトに渡します。

HEROKU_TEAM=<team> HEROKU_APP_NAME=<name> SLACK_CMD deploy --skip-update --team <team ID> --app deployed --org-workspace-grant all

デプロイ済みアプリは、SLACK_CMD run が使用するアプリとは別のアプリです。 CLI はデプロイ済みアプリを .slack/apps.json に、ローカル開発アプリを .slack/apps.dev.json に、それぞれチームごとに記録します。どちらも独立して動作し続けます。これは意図された設計であり、修正すべき問題ではありません。

初回デプロイ後に .slack/apps.json をコミットしてください。 ここにはアプリ ID とチーム ID が含まれますが、シークレットは含まれておらず、プロジェクトの .slack/.gitignore では意図的に追跡対象のままになっています。コミットしておけば、以降のデプロイは常に同じアプリを対象にできます。Heroku では、再デプロイのたびにデプロイスクリプトが未コミットの変更について警告することもなくなります。

開発者に伝えておくべき影響が1つあります。2つのアプリは、同じワークスペースで同じスラッシュコマンドを宣言します。デプロイ済みアプリの稼働中に SLACK_CMD run を実行すると、どちらのアプリがスラッシュコマンドに応答するのか判別できなくなります。デプロイ済みアプリを確認するときはローカルプロセスを停止してください。いずれにせよ、Step 6: デプロイを検証する でそのようにします。

ステップ 6:デプロイを確認する

次の 3 点をすべて確認してください。最初の 2 点を満たしていても、Slack 上でアプリが応答しないことがあります。

6a. サービスが稼働している

プロバイダーのリファレンスファイルにあるステータス確認コマンドとログ確認コマンドを使います。アプリ自身の起動ログと、Socket Mode の WebSocket 接続を確認してください。ビルドが成功した後にプロセスが終了した場合は、ここで表示される内容が大きく異なります。ビルド結果を信頼するだけでなく、ログを確認してください。

6b. ローカルで何も実行せずに、アプリが Slack で応答する

最初にローカルプロセスを停止してください。 これが、開発者のノート PC ではなく、デプロイしたアプリが動作していることを証明できる唯一の確認方法です。ステップ 3:まずローカルで動作を確認するで確認した機能を試し、Slack に応答が表示され、対応するリクエストがプロバイダーのログに記録されていることを確認してください。

6c. 2 つのアプリが別々である

.slack/apps.json と .slack/apps.dev.json にあるアプリ ID を開発者に示し、異なることを確認してください。次に、SLACK_CMD run が引き続き開発用アプリを起動することを確認してください。


ステップ 7:再デプロイする

変更を反映するには、ステップ 5:デプロイと同じフラグを指定して、同じ SLACK_CMD deploy コマンドを実行します。ステップ 4:デプロイフックを設定するの内容はすでに完了しているため、そこは飛ばして、そのままデプロイしてください。新しいアプリではなく、同じアプリが使われるはずです。

プロバイダーごとに異なる点が 2 つあります。どちらもデプロイスクリプトで処理されます。

  • Railway は作業ディレクトリをアップロードして毎回再ビルドするため、コミットは不要です。
  • Heroku は git push からビルドするため、コミットされていない変更はデプロイされません。新しいコミットがないまま push すると、何もビルドされません。そのため、代わりに dyno が再起動され、変更したトークンが反映されます。再デプロイする前に、コードの変更をコミットしてください。

再デプロイによって Slack アプリが 2 つ作成される場合は、.slack/apps.json からデプロイ済みアプリのエントリが失われています。再度デプロイする前に、後からアプリを削除するのではなく、.slack/apps.json に --team ID のエントリがあることを確認してください。


ステップ 8:デプロイを終了する

開発者がデプロイ済みアプリを使い終えたとき、たとえばスキルを試した後に、この手順を使います。ホスト上のコピーとデプロイ済み Slack アプリを削除し、開発用アプリはそのまま残します。

削除するリソースをすべて示し、削除する前に一度だけ確認を求めてください。 削除は取り消せません。削除するプロバイダープロジェクトまたはアプリと、.slack/apps.json にある Slack アプリ ID を伝え、承認を待ってください。

  1. 最初にプロバイダー上のコピーを削除します。 これにより、無効になる予定のトークンを使って Slack との接続を維持するものが残らないようにします。コマンドは、プロバイダーのリファレンスファイルの「Tearing down」に記載されています。
  2. SLACK_CMD app delete --team <team ID> --app deployed --force を使って、デプロイ済み Slack アプリを削除します。 .slack/apps.json からチーム ID を読み取ってください。--force は確認プロンプトを省略します。確認プロンプトは、非対話型のシェルでは失敗するためです。デプロイ済みアプリがそれだけだった場合、CLI は .slack/apps.json も削除するため、その削除をコミットしてください。
  3. 開発用アプリは、開発者から依頼がない限り残します。 このアプリは SLACK_CMD run が使うアプリであり、通常は引き続き開発に使います。削除を依頼された場合は、同じコマンドに --app local を指定して削除してください。

.slack/hooks.json とデプロイスクリプトはそのまま残してください。これにより、後で SLACK_CMD deploy を実行すれば、最初からすべて設定し直せます。


注意事項

サーバーレスプロバイダーでは Socket Mode アプリをホストできません。 Socket Mode アプリは、常駐してアウトバウンド WebSocket を開いたままにするプロセスです。Vercel、AWS Lambda などのプラットフォームでは、実行時間に上限があり、常時稼働するプロセスの種類がないリクエストごとの関数が実行されるため、WebSocket を常駐させる場所がありません。開発者からこれらのプロバイダーのいずれかを求められた場合は、実現しようとするのではなく、この制約を説明してください。Slack アプリをサーバーレスプラットフォームでホストするには Request URL アプリを使用しますが、このスキルではまだ扱っていません。

その他のプロバイダー。 このスキルで扱っていないプロバイダーについて開発者から尋ねられた場合は、常時稼働するバックグラウンドワーカープロセスの種類が用意されているかどうかと、そのプロセスの料金体系を確認してください。

トークンの受け渡しは、文書化された仕様ではありません。 Slack CLI は、デプロイフックにトークンを明示的に渡しません。アプリのインストール中に Slack CLI 自身のプロセスにトークンを設定し、フックスクリプトは後から同じプロセス内で実行されるため、それらを引き継ぎます。この仕組みは機能します。また、Slack ホストの関数ランタイムを持たないアプリでのみ機能します。すべての Bolt アプリがこれに該当します。そのため、各デプロイスクリプトでは両方のトークンがあるか確認し、トークンが存在することを前提にせず、内容が分かるメッセージを表示して終了します。

フックなしで slack deploy を実行しないでください。 .slack/hooks.json に deploy キーがない場合、SLACK_CMD deploy は Slack 独自のホスト型インフラストラクチャを対象とします。これは、異なる種類のアプリ向けの別の製品です。CLI のコマンド全般については、slack:slack-cli スキルで扱っています。

まずアプリを作成してください。 まだアプリがない場合は、slack:create-slack-app スキルから始め、ローカルで実行できるようになったら、こちらに戻ってきてください。

コメント