~Webhook設計・イベント分岐・Codeノード・異常検知まで~
Slack連携は、n8nで最も活用範囲が広く、同時に「構造の理解力」が問われる分野です。単なるWebhook接続だけでなく、本番環境でも壊れない自動化構造を作るには、イベントの処理構造、Codeノードでの安全な分岐、そして異常系の設計までを押さえる必要があります。
この記事では、2025年現在の最新仕様(n8n v1.70〜 / Slack Event API対応)に基づいて、「止まらないSlackワークフロー」の作り方をゼロから解説します。
Chapter 1:Slack連携とWebhook設計の基礎
1-1. Slack連携の流れ(2025年版)
Slack Event API を使って n8n と連携する際の全体フローは、2025年時点で次のステップが基本です:
- Slack App を作成し、「Event Subscriptions」を有効化
- 「Event Subscriptions」をONにし、受信したいイベント(message / app_mention / reaction_added など)を選択します。
- Webhook URL(例:https://hooks.n8n.cloud/…)を登録
- n8n 側で作成した Webhook ノードの URL を Slack に登録します(Test URL ではなく本番用 URL を使用)。
- Slack から初回の「URL検証リクエスト」が送られる
- 最初の1回だけ、Slack は type = “url_verification” のイベントを送信し、Webhook の有効性を確認します。
- n8n が challenge を返却すれば連携完了
- Slack 側でレスポンスを受け取ると、Webhook が「有効」と判定されます。
- 以降はイベントが自動で n8n に送信される
- 例:message(通常メッセージ)、app_mention(Bot宛メンション)、reaction_added(リアクション追加)など
1-2. n8nの基本構成(最新版のベストパターン)
[Webhook (Slack)]
↓
[If: type == "url_verification"]
├ True → [Respond to Webhook: challenge返却]
└ False ↓
↓
[Code: event.type → route分類]
↓
[Switch: routeごとに処理]
├ message → Slack返信 or OpenAI処理
├ reaction → ログ記録
├ mention → GPT応答
└ other → 監視チャンネルへ通知
- URL検証は Respond to Webhook ノードで返却(Codeノード単体での返却は非推奨)
- イベント判定は body.event.type を必ず参照(type は常に “event_callback” 固定なので注意)
- 想定外イベントは「監視通知」に逃がす(処理が止まらず、異常を検知できる)
1-3. URL検証対応(最新推奨パターン)
Slack が最初に送信してくる type = “url_verification” リクエストは、Webhook の有効性を確認するためのものです。ここで最も重要なのは 「3秒以内に challenge をそのまま返す」 ことです。
[Webhook (Slack)]
↓
[If: $json.type == "url_verification"]
├ True → [Respond to Webhook: challenge返却]
└ False → [通常イベント処理へ]
Respond to Webhook ノードの設定:
- Respond With: JSON
- Response Body:
{
"challenge": "={{ $json.challenge }}"
}
✅ この構成を使えば Slack 側で「Invalid response」になることはなく、Webhook が非アクティブ化されるリスクも防げます。
また、n8n が自動的に 200 OK と適切な Content-Type を返すため、将来的な API 変更にも耐性があります。
Chapter 2:イベント分岐と Code / Switch ノードの使い方
2-1. Slackイベントの構造(2025年時点)
Slack のイベント JSON は必ず body.event の中に入って届きます。
{
"type": "event_callback",
"event": {
"type": "app_mention",
"user": "U12345",
"text": "Hello bot!"
}
}
このため、条件分岐では item.json.body.event.type を使うことが重要です。
2-2. Codeノードで route を割り当てる(実践構成)
まずはイベントタイプを Codeノードで分類します。
const eventType = item.json.body?.event?.type;
switch (eventType) {
case "message":
item.json.route = "message";
break;
case "reaction_added":
item.json.route = "reaction";
break;
case "app_mention":
item.json.route = "mention";
break;
default:
item.json.route = "other";
}
return [item];
✅ route を後続で使うと処理が整理され、SwitchノードやIFノードが読みやすくなります。
2-3. Switchノードでの分岐(最新おすすめ)
n8n v1.60 以降では、Switchノードが強化されました。Codeを使わずに次のような分岐も可能です。
[Switch: $.body.event.type]
├ message → [Slack返信]
├ app_mention → [OpenAI]
├ reaction_added→ [ログ保存]
└ default → [監視通知]
✅ Switchは読みやすく高速。複雑な条件が不要ならこちらを推奨します。
Chapter 3:異常検知とエラー通知の設計
3-1. 想定外イベントの通知ルート
イベントの仕様変更や新機能に備えて、route == “other” のパスは必ず用意しましょう。
[If: route == "other"]
↓
[Slackノード]
- チャンネル: #監視用
- メッセージ: “⚠️未対応イベントを受信: {{$json.body.event.type}}”
これで「沈黙クラッシュ(処理が止まって気づかない)」を防げます。
3-2. よく届く「想定外イベント」の例
| イベント名 | 内容 | 対応策 |
| message_changed | メッセージ編集 | 処理対象から除外 or 無視通知 |
| reaction_removed | リアクション削除 | ログ記録 or 無視 |
| file_shared | ファイル共有 | 別ルートで対応 or 無視 |
✅ 「other」ルートに丸投げでも構いませんが、必要に応じて除外ロジックを Code 内に入れてもOKです。
Chapter 4:「止まらない」構造設計と例外処理
4-1. よくある「壊れる」パターン
| 原因 | 内容 | 対策 |
| undefined.toLowerCase() | 存在しない値へのアクセス | ?. で安全参照 |
| Slack challenge 失敗 | JSON形式が不正 | Codeノードで正しい返却 |
| 想定外イベント未対応 | event.typeが未定義 | route == “other” ルート |
4-2. Codeノードでの try/catch 構造
try {
const text = item.json.body?.event?.text?.toLowerCase();
item.json.cleanedText = text || "";
return [item];
} catch (error) {
return [{
json: {
error: true,
message: error.message,
route: "error"
}
}];
}
✅ route: “error” を監視チャンネルに飛ばせば、エラーもクラッシュせず通知可能になります。
4-3. 「壊れない設計」の4原則
- 例外ルートを必ず用意する(other, error)
- 値がない前提でコーディング(?. や || “” を徹底)
- Webhookには確実に200を返す
- 「Always Output Data」 を全ノードでONにする
Chapter 5:n8nで使う実用的なJavaScript構文
| 構文・メソッド | 目的 | 使用例 |
| if / else | 条件分岐 | if (type === “message”) { … } |
| ?. | null安全アクセス | item.json.body?.event?.text |
| includes() | 含有判定 | “text”.includes(“AI”) |
| map() | 全件処理 | items.map(…) |
| toLowerCase() | 小文字化 | text.toLowerCase() |
| trim() | 空白除去 | text.trim() |
ネガティブワード検知の例
const badWords = ["クレーム", "不具合", "故障", "請求"];
const content = item.json.body?.event?.text || "";
item.json.alert = badWords.some(word => content.includes(word));
return [item];
✅ この判定結果を元に、Slack通知やCRMアラートを自動化できます。
まとめ|「構造 × 防御 × 通知」で本番運用へ
- ✅ Slackのイベント構造(body.event.type)を正しく扱う
- ✅ Codeノードでのルーティング & Switch での分岐が鉄板パターン
- ✅ 異常時は route == “other” で通知する「逃がし道」を必ず用意
- ✅ ?.・||・try/catch など防御的なコードで止まらない構造にする
- ✅ 「Always Output Data」は全ノードでON にしておくと安心
この設計パターンを押さえておけば、Slack連携はもちろん、LINE・Notion・Typeformなど他のWebhook自動化にも横展開が可能です。
