Slack
ボットトークンモードは Slack Web API のすべての機能(ストリーミング、ファイル、リアクション、エフェメラル、スケジュール送信)を利用可能にします。Webhook モードは1つの URL だけで動作するフォールバックで、プレーンテキスト・Block Kit ブロック・スレッド返信に対応しています。
🟢 実行時即時利用可能 : 設定されている環境変数に応じて、2つのモードが自動で選択されます。ボットトークンモードは、簡単な用途以外にはすべて推奨です。Webhook モードは1つの URL だけで動作するフォールバックとして位置づけられており、テキスト・Block Kit ブロック・スレッド返信には対応していますが、ストリーミング、添付ファイル、リアクション、エフェメラル送信、スケジュール送信、
metadataフィールドには対応していません。
モードの選択
| モード | 環境変数 | ストリーミング | 添付ファイル | スレッド | リアクション | ブロック(Block Kit) | エフェメラル/スケジュール/Metadata | 受信 | 推奨用途 |
|---|---|---|---|---|---|---|---|---|---|
| ボットトークン(推奨) | SLACK_BOT_TOKEN + SLACK_CHANNEL_ID | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | フル機能の統合、マルチチャンネルルーティング、受信リスナー |
| Webhook(Slack アプリ不要のフォールバック) | SLACK_WEBHOOK_URL | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | プレーンテキスト・Block Kit・スレッド返信(Slack アプリの承認不要) |
Webhook モードでできること、できないこと: Slack の
Incoming Webhooks ドキュメントによると、Webhook URL は JSON ボディとして text、blocks、thread_ts、mrkdwn、unfurl_links、unfurl_media を受け付けます。一方、編集エンドポイント(ストリーミング不可)、files.upload(添付ファイル不可)、reactions.add、chat.postEphemeral、chat.scheduleMessage、metadata には対応していません。これらはボットトークン専用の Slack Web API メソッドです。Minara の制限ではなく、どの Slack SDK でも回避することはできません。
両方の環境変数が設定されている場合の優先順位: Minara はボットモード(SLACK_BOT_TOKEN + SLACK_CHANNEL_ID)を優先します。Webhook が使われるのは、ボット認証情報が存在しないか不完全な場合のみです。ボット用の環境変数をどちらか削除すると、Webhook モードにフォールバックします。
セットアップ(ボットトークンモード、推奨)
1. ボットの作成
- api.slack.com/apps を開き、Create New App → From scratch → 名前を "Minara" に設定 → ワークスペースを選択します。
- OAuth & Permissions で、以下の Bot Token Scopes を追加します。
chat:write(chat.postMessage/chat.postEphemeral/chat.scheduleMessageに必須)chat:write.public(ボットが招待されていないチャンネルへの投稿に必須)files:write(files.v2経由の添付ファイルアップロードに必須)reactions:write(add_reactionツールに必須)
- ページ上部の Install to Workspace をクリックし、Bot User OAuth Token(
xoxb-で始まる文字列)をコピーします。
2. チャンネル ID の確認
Slack クライアントでチャンネル名をクリックし、一番下までスクロールして Channel ID(例: C0123ABC)をコピーします。
3. Minara の設定
プロジェクトルートの .env ファイルから SLACK_WEBHOOK_URL を削除してください(両方設定されていてもボットモードが優先されますが、アクティブなモードが分かりやすくなるため削除を推奨します)。その後、以下を設定します。
SLACK_BOT_TOKEN=xoxb-...
SLACK_CHANNEL_ID=C0123ABC4. テスト
minara auth messaging test slackセットアップ(Webhook モード、フォールバック)
ボットトークンモードを優先してください。Webhook モードは、Slack アプリの承認が取得できない場合(個人ワークスペースや制限されたエンタープライズプランなど)や、1回限りのテキストアラートチャンネルとして最小限のセットアップで済ませたい場合にのみ使用します。
1. Incoming Webhook の作成
- api.slack.com/apps → Create New App → From scratch → 名前を "Minara" に設定 → ワークスペースを選択します。
- 左ナビゲーションで Incoming Webhooks を選択し、機能を On に切り替えます。
- Add New Webhook to Workspace → チャンネルを選択 → Allow をクリックします。
- Webhook URL(
https://hooks.slack.com/services/T00/B00/xxx)をコピーします。
2. Minara の設定
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00/B00/xxxチャンネルは URL に組み込まれているため、SLACK_CHANNEL_ID は無視されます。send_message での channel 上書きも明確なエラーとして拒否されます。Webhook モードはスレッド、Block Kit ブロック、mrkdwn、unfurl トグルに対応していますが、添付ファイル、エフェメラル送信、スケジュール送信、metadata には対応していません。
ストリーミングの動作(ボットモードのみ)
Slack の chat.update は Tier-3 のレート制限(約50回/分)が適用されます。Minara は編集を 1,200 ms ごとに制限しており、上限を余裕をもって下回りながらも十分なレスポンス感を維持しています。メッセージの最大長は 40,000 文字で、実際にはほとんど到達しません。
リッチメッセージング(Block Kit、エフェメラル、スケジュール送信、metadata、ボットモード)
ボットモード Slack の send_message は、Slack Web API の対応するフィールドやエンドポイントに直接ルーティングされる provider_options.slack オブジェクトを受け付けます。コアフィールドである text・channel・thread と provider_options.slack は同一の呼び出しで組み合わせ可能です。
attachments は例外です。 添付ファイルは Slack の Files v2 フロー(files.getUploadURLExternal → files.completeUploadExternal)を経由するため、initial_comment(text から設定)と thread_ts のみ受け付けます。attachments と同時に blocks・mrkdwn・unfurl_*・metadata・ephemeral_user・schedule_at を渡した場合、ツールの境界で拒否されます。回避策として、まずリッチメッセージを投稿して messageId を取得し、その後ファイルをそのスレッドへのフォローアップとしてアップロードしてください。
Block Kit によるリッチフォーマット
Slack の Block Kit は、ヘッダー・セクション・区切り線・コンテキスト・フィールド・画像を含む標準的なリッチメッセージ形式です。blocks はブロックオブジェクトの配列で、chat.postMessage の blocks パラメータに直接渡されます。text はプレーンテキストのフォールバック(モバイル通知・スクリーンリーダー・アクセシビリティツール向け)として機能します。
send_message({
provider: "slack",
text: "BTC -5.1% on 1h", // fallback — shown when blocks can't render
provider_options: {
slack: {
blocks: [
{ type: "header", text: { type: "plain_text", text: "Price alert" } },
{ type: "section", text: { type: "mrkdwn", text: "*BTC* dropped *5.1%* in the last hour" } },
{ type: "divider" },
{
type: "context",
elements: [
{ type: "mrkdwn", text: "_Source: Minara · 1h · $68,450_" },
],
},
],
},
},
})Slack の Block Kit Builder でブロックレイアウトを試し、生成された JSON を blocks にそのまま貼り付けてください。
エフェメラルメッセージ(特定のユーザーにのみ表示)
ephemeral_user に Slack ユーザー ID(例: U012ABC)を設定すると、送信が chat.postEphemeral にルーティングされます。メッセージはそのユーザーにのみ表示され、Slack をリロードすると消えます。チャンネル内のユーザーごとの確認応答やスラッシュコマンドへの返答に便利です。
send_message({
provider: "slack",
text: "Your position is under 1% of portfolio — auto-trade skipped.",
provider_options: { slack: { ephemeral_user: "U012ABC" } },
})chat.postEphemeral がサポートする引数は chat.postMessage の厳格なサブセットです。 Slack のドキュメントに記載されている引数リストによると、エフェメラルエンドポイントは mrkdwn、unfurl_links、unfurl_media、metadata を受け付けません。受け付けるのは text・blocks・thread_ts・attachments・標準認証引数のみです。ephemeral_user と同時にこれらの非対応フィールドを渡した場合、サイレントに無視されるのではなく、具体的なエラーとしてツールの境界で拒否されます。また、エフェメラル送信は Minara の attachments(Slack の files.v2 フローにはエフェメラルフックがありません)および schedule_at(エフェメラルのスケジュール送信は不可)とも互換性がありません。
スケジュール送信
schedule_at に Unix 秒のタイムスタンプを設定すると、送信が chat.scheduleMessage にルーティングされます。Slack はスケジュール送信を最大 120 日先まで許可しており、Minara もツールの境界で同じ制限を適用しています。
send_message({
provider: "slack",
text: "Weekly review — check the dashboard before stand-up",
provider_options: {
slack: { schedule_at: Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60 },
},
})返却される message_id は Slack の scheduled_message_id です。キャンセルが必要な場合は、将来的なツールから chat.deleteScheduledMessage に渡してください。ephemeral_user とは同時に使用できません。
スケジュール送信では metadata はサポートされません。 Slack の chat.scheduleMessage ドキュメントには、metadata パラメータを含むスケジュール送信は「投稿されない」と記載されています。Minara はツールの境界でこの組み合わせを拒否するため、サイレントに送信されない scheduled_message_id を受け取る事態を防ぎます。
mrkdwn・unfurl_links・unfurl_media
メッセージごとに Slack のデフォルトのパース動作を制御します。
mrkdwn: falseを指定すると、textの Markdown 展開が無効になります(*not-bold*をそのままテキストとして送信できます)。unfurl_links: falseを指定すると、メッセージ内のリンクプレビューが非表示になります(大きなプレビューカードが表示されると煩わしい高頻度アラートに便利です)。unfurl_media: falseを指定すると、リッチメディアプレビューが非表示になります。
metadata(機械可読なコンテキスト)
構造化された JSON ペイロードをメッセージに付与します(Slack の上限は 8KB)。UI には表示されませんが、受信ハンドラーがレンダリング済みテキストではなく LLM が推論に使った生データを必要とする場合に便利です。
send_message({
provider: "slack",
text: "BTC dropped 5%",
provider_options: {
slack: {
metadata: {
event_type: "price_alert",
event_payload: { symbol: "BTC", pct: -5.1, ts: Date.now() },
},
},
},
})チャンネルの上書き(ボットモードのみ)
send_message({
provider: "slack",
channel: "C9876XYZ",
text: "Critical: position liquidation imminent",
})ボットが上書き先のチャンネルのメンバーであるか、chat:write.public スコープを持っている必要があります。
トラブルシューティング
"Webhook URL is disabled"
- アプリがワークスペースから削除されたか、アプリ設定で Webhook が手動で無効化されたことで、Slack が Webhook を無効にしています。
- Webhook を再作成し、
SLACK_WEBHOOK_URLを更新してください。
"channel_not_found"(ボットモード)
- ボットがチャンネルのメンバーではありません。対象チャンネルで
/invite @your-botを実行するか、chat:write.publicスコープを追加してください。
"not_authed" / "invalid_auth"
SLACK_BOT_TOKENが未設定または誤っています。ボットトークンはxoxb-で始まります。ユーザートークン(xoxp-)は使用できません。Slack API がchat.postMessageに対して拒否します。
"Streaming not working"
- おそらく Webhook モードになっています。
SLACK_BOT_TOKENとSLACK_CHANNEL_IDの両方が設定されているか確認してください。
"invalid_blocks" / "missing_scope"(Block Kit 使用時)
- Slack の API は Block Kit を独自の JSON スキーマに対して検証します。Minara はそのスキーマチェックを複製しません。Block Kit Builder で問題のあるブロックを特定してください。
missing_scopeは通常、files:write(添付ファイル用)またはreactions:write(add_reaction用)が不足していることを意味します。スコープを追加した後、アプリを再インストールしてください。
リファレンス
- 環境変数:
SLACK_WEBHOOK_URL,SLACK_BOT_TOKEN,SLACK_CHANNEL_ID - ソース:
apps/agent/src/messaging/slack.ts - Slack Web API インデックス: api.slack.com/methods
- Block Kit リファレンス: api.slack.com/block-kit
- Incoming Webhooks: api.slack.com/messaging/webhooks