2026年6月23日
Bolt/Socket ModeでSlack Botをサーバーレス実装する — バイブコーディング実践ガイド
Slack Botを「動かし続ける」ためのアーキテクチャ選択
Slack Bot・APIで何ができるのかで示したように、Slack Botには大きく分けてノーコード(ワークフロービルダー)と自作(API/Bolt)の2路線があります。自作の道に進んだ場合、次に直面するのが「どこで動かすか」の問題です。
Bolt(Bolt for JavaScript/Python/Java)はSlack公式のBotフレームワークで、2つの実行モードを持っています。
| モード | 仕組み | 向く場面 |
|---|---|---|
| Socket Mode | SlackからWSで接続を受ける | 開発環境、社内限定Bot、ファイアウォール内 |
| HTTPエンドポイント | パブリックURLでSlackからPOSTを受ける | ステートレス構成・サーバーレスデプロイ |
この記事では両モードの実装パターンと、バイブコーディングでの作り方を解説します。
Boltが解決する3つの手間
Boltを使わずにSlack APIを直接叩く場合、以下を自分で実装する必要があります。
- 署名検証:SlackからのリクエストがSlack本体からのものかを検証する(HMAC-SHA256)
- イベントルーティング:
event_type・コマンド名・ボタンのactionごとに処理を振り分ける - OAuth認証フロー:アプリをワークスペースにインストールする処理
Boltはこれらをフレームワークが担うため、実装者は「何をどう返すか」のロジックに集中できます。
実装例①:Socket Mode(開発・社内用)
Socket ModeはパブリックなURLが不要なため、ローカル開発や社内のVPC内での実行に適しています。
import { App } from '@slack/bolt';
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN, // Socket Mode用のapp-levelトークン
});
// スラッシュコマンド /hello への応答
app.command('/hello', async ({ command, ack, respond }) => {
await ack(); // Slackへの受信確認(3秒以内に必須)
await respond({
text: `こんにちは、${command.user_name} さん!`,
response_type: 'in_channel',
});
});
// メッセージへのリアクション監視
app.message('ありがとう', async ({ message, say }) => {
await say('どういたしまして!');
});
(async () => {
await app.start();
console.log('Bot is running in Socket Mode');
})();
.envファイルの設定:
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
SLACK_APP_TOKEN=xapp-...
実装例②:HTTPエンドポイント方式(本番・サーバーレス)
ステートレスに動かしたい場合(Vercel・Cloudflare WorkersなどのサーバーレスHTTP実行)には、HTTPエンドポイント方式を使います。パブリックなURLが必要ですが、リクエストごとに実行・終了するサーバーレス構成にできます。なお、CloudflareやVercelはWebSocketも利用可能ですが、ステートレスなHTTPエンドポイント方式を選ぶことでコストと運用負荷を下げられます。
import { App, ExpressReceiver } from '@slack/bolt';
import express from 'express';
const receiver = new ExpressReceiver({
signingSecret: process.env.SLACK_SIGNING_SECRET!,
});
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver,
});
// スラッシュコマンド
app.command('/summary', async ({ ack, respond }) => {
await ack();
await respond({
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: '*今日の運営サマリー* :bar_chart:',
},
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: '*投稿数*\n42件' },
{ type: 'mrkdwn', text: '*参加者*\n18名' },
],
},
],
});
});
// Vercelへのエクスポート
export default receiver.app;
vercel.json:
{
"functions": {
"src/index.ts": {
"memory": 256,
"maxDuration": 10
}
},
"routes": [
{ "src": "/slack/events", "dest": "src/index.ts" }
]
}
SlackのApp設定「Event Subscriptions」・「Slash Commands」のRequest URLに https://<your-vercel-url>/slack/events を設定すれば動きます。
バイブコーディングでの実装手順
専業エンジニアでなくても、AIコーディング(Claude等)を使えばBoltのBotを実装できます。以下のプロンプトテンプレートが出発点になります。
Slack BoltのTypeScript版でHTTP(ExpressReceiver)方式のBotを作りたいです。
要件:
- スラッシュコマンド /ask に対して、引数のテキストをそのままBlockメッセージで返す
- Vercel(サーバーレス)にデプロイする
- package.json・vercel.json・.env.example・src/index.ts を一式
- デプロイ後にSlackアプリの設定で何をどこに貼ればいいかも教えてください
必要なOAuthスコープ(権限)も一覧で教えてください。
AIからコードを受け取ったら、以下を確認します。
- スコープ(OAuth権限)の確認:必要以上の権限を付けないようにする
- 署名検証の存在確認:
signingSecretが使われているか - エラーハンドリング:
ack()が必ず呼ばれているか(これがないとSlackがタイムアウトで再送し続ける)
ユースケース別:Boltで作ると便利なBotの例
| ユースケース | コマンド/トリガー | 処理 |
|---|---|---|
| 議事録要約 | app.event('message') で会議チャンネルを監視 | LLMで要約してスレッドに投稿 |
| 申請フロー | /apply コマンド | モーダルでフォーム表示、承認者にDM通知 |
| FAQ自動応答 | app.message(キーワード) | パターンマッチ or LLMで回答 |
| 日次レポート | cron + chat.postMessage | 前日の指標をSlackに自動投稿 |
| 外部DB照会 | /lookup {ID} | CRM/DBからデータ取得してBlockで表示 |
LLMとの連携(FAQ・要約・モデレーション補助)の詳細は今後の記事で扱います。AI前提でコンテンツ制作を回すもあわせて参照ください。
Boltを使わない場合との比較
| 観点 | 生のSlack API | Bolt |
|---|---|---|
| 署名検証 | 自前実装必要 | 自動 |
| イベントルーティング | 自前実装 | app.command() / app.event() で簡潔 |
| OAuth処理 | 自前実装 | Boltの InstallationStore が担う |
| 学習コスト | API仕様を直接読む必要あり | Boltのドキュメントに集約 |
| バイブコーディングのしやすさ | AIへの説明が複雑になりがち | Boltと伝えれば例が出やすい |
シンプルな通知流し込みだけならIncoming Webhookで十分です。スラッシュコマンドやモーダルが必要になったらBoltの出番です。
まとめ
- BoltはSlack公式フレームワークで、署名検証・ルーティング・OAuth処理を担ってくれます
- 開発・社内ツールはSocket Mode(パブリックURL不要)、ステートレスに動かしたい場合はHTTPエンドポイント方式を選びます
- バイブコーディングでは「Bolt + TypeScript + HTTPエンドポイント + Vercel」と具体的に指定すると精度が上がります
ack()の呼び忘れとOAuthスコープの過剰付与が典型的な落とし穴です
Slack Botの設計・実装伴走や、コミュニティ全体の自動化設計に関心があれば、六瀬のコミュニティ開発サービスもご覧ください。
関連記事
Contact · 六瀬合同会社
コミュニティの話を、続けませんか。
読みながら「自分のところはどうなんだろう」と思った瞬間があれば、その問いをそのまま送ってください。整理されていなくても、相談の入口を一緒に言葉にしていきます。
よくある質問
- Q. Slack BoltとSlack Web APIは何が違いますか?
- A. Slack Web APIはSlackが提供するREST APIの総称で、メッセージ送信・チャンネル管理・ユーザー情報取得などの操作を直接HTTPで行います。Bolt(Bolt for JavaScript/Python等)はそのAPIを扱いやすくラップしたフレームワークで、イベントのルーティング・署名検証・OAuth処理などをほぼ自動で処理してくれます。Boltを使うと「どのコマンドに何を返すか」の処理ロジックだけを書けばよくなります。
- Q. Socket ModeとHTTPエンドポイント方式はどちらを使えばいいですか?
- A. 開発中・社内ツール・ファイアウォール内での運用はSocket Mode、ステートレスなリクエスト処理(Vercel・Cloudflare WorkersなどのサーバーレスHTTP実行)にはHTTPエンドポイント(Events API)が適しています。Socket ModeはSlackからの接続を自分から張るためパブリックURLが不要ですが、常時接続のプロセスが必要です。HTTPエンドポイント方式はステートレスなサーバーレス構成に向いており、コストと運用負荷を下げられます。なお、CloudflareやVercelはWebSocketも利用可能ですが、HTTPエンドポイント方式のほうがよりシンプルです。
- Q. バイブコーディングでSlack Botを作るとき、何をAIに渡せばいいですか?
- A. 「Slack BoltのTypeScript版でHTTPエンドポイント方式のBotを作りたい。スラッシュコマンド /daily-summary に反応して、Slackのチャンネルの当日メッセージ数をメッセージで返す。Vercelにデプロイする前提で、vercel.json・package.json・src/index.ts を一式で教えてください」のように、フレームワーク・言語・コマンド名・処理内容・デプロイ先を具体的に伝えてください。受け取ったコードのAPIスコープ(必要な権限)もセットで確認します。