「返信どうしよう…」を助ける!n8n×AIでSlack秘書をつくってみた
はじめに
スケジュール調整や一時的な返信って、地味に手間がかかりますよね。
少なくとも私は「誰か代わりに返事してくれないかな…」と何度も思ってきました。
そこで今回は n8n を使って、Slackでメンションがついたら自動で「返信案」を提案してくれるAI秘書Botを作ってみました。さらに、Google Calendarと連携して簡単な日程調整も考えてくれるようにしています。
さすがにいきなり相手に送るのは怖いので(笑)、まずは返信案を自分宛てにDMするようにしています。
(※精度はまだ怪しく、動かない時もあります。改善の余地ありです!)
今回作ったもの
- Slackで自分宛てのメンションが来ると、AIが返信候補を提案してくれる
- Google Calendarと連携し、予定を踏まえた返信も生成
n8nとは?
n8n は、ノーコード/ローコードでワークフローを自動化できるOSSのツールです。
Zapierのようなサービスのセルフホスト版で、自由度が高いのが特徴。
例えば今回のように Slack → AI → Google Calendar といった複数サービスを簡単につなげることができます。
作成手順
今回作成するワークフローは、次のステップで作成できます。
「細かい設定を見ている時間がない!」という方は、用意したJSONをそのまま貼り付ければすぐに枠組みを作成することができます。詳しくは こちら をご覧ください。
ステップ1:n8nアカウントの準備
まずは n8n Cloud でアカウントを作成しましょう。
ステップ2:Slackアプリの作成と設定
SlackでBotを動かすためのアプリを作ります。
-
アプリの作成Slack API — Your Apps にアクセスし、「Create New App」から「From scratch」を選びます。アプリ名は「AI秘書」など、わかりやすい名前をつけましょう。
-
権限(Scopes)の設定
左メニューの「OAuth & Permissions」を開き、「Bot Token Scopes」に必要な権限を追加します。まずは、公開チャンネルでのメンションにBotが返信するための最低限の権限を付与してください。-
app_mentions:read
:メンションを読み取る -
channels:history
:公開チャンネルのメッセージを取得する -
chat:write
:メッセージを送信する
注意: 上記の権限だけでは動かない場合もあります。より幅広い用途で使う場合は、必要に応じて権限を追加しましょう。
-
-
アプリのインストール
ページ上部の「Install to Workspace」をクリックして、アプリをワークスペースにインストールします。完了後、「Bot User OAuth Token」をコピーして控えておきます。このトークンは後でn8nに貼り付けます。 -
Events API の有効化
左メニューの「Event Subscriptions」を開き、「Enable」をONにします。
「Subscribe to bot events」にmessage.channels
を追加し、保存してください。この画面にある「Request URL」は、後ほどn8nから取得したURLを貼り付けます。
ステップ3:n8nでSlackトリガーを設定
-
ワークフローの作成
n8nで新しいワークフローを作成し、「Slack Trigger」ノードを追加します。 -
Slack認証
ノード内の「Credentials」に、先ほど控えておいた「Bot User OAuth Token」を使ってSlack認証情報を設定します。 -
Webhook URLの検証
ノード右側に表示される「Webhook URL」をコピーし、ステップ2で開いたSlackの「Event Subscriptions > Request URL」に貼り付けて検証します。 -
動作確認
SlackでBotを対象チャンネルに招待し、「こんにちは」などと投稿して、n8n側でメッセージが受信できるか確認します。
ステップ4:自分宛のメンションだけを抽出
If ノードを追加し、Bot宛のメンションだけを次のステップへ進めるように設定します。
-
左辺: メッセージ本文(
text
) -
演算子:
contains
(含む) -
右辺:
<@あなたのSlackユーザーID>
ステップ5:メッセージ情報の整理
Set ノードを追加し、以降のステップで使いやすいようにメッセージ情報を整理します。
-
original_message
:受信したメッセージ本文 -
channel_id
:チャンネルID -
user_id
:送信者ID -
timestamp
:メッセージのタイムスタンプ
ステップ6:AIエージェントの配置
AIエージェントノードを追加し、OpenAIやGoogleカレンダーと連携させます。
-
AI Agentノードの設定
ノードにoriginal_message
を入力として渡し、Botにどのような返信をさせるかプロンプトで指示します。 -
OpenAIとの連携
「Language Model」で「OpenAI」を選択し、APIキーを設定します。 -
Googleカレンダーとの連携
日程を確認したい場合は、「Tools」に「Google Calendar」を追加し、認証を済ませます。
ステップ7:Slackへの返信テスト
Slack: Send Message ノードを追加して、返信が正しく機能するかテストします。
- 送り先: 「User」を選択し、あなたのユーザーIDを指定(まずは自分へのDMで確認するのがおすすめです)。
- メッセージ本文: AIエージェントの出力結果をここに差し込みます。
JSONを使ってワークフローを簡単に作成
「自分でゼロから設定するのは大変そう…」と感じた方もご安心ください!
実はこのワークフローは、JSONを貼り付けるだけでも手軽に再現できます。
作成手順
- n8nのワークフロー作成画面を開く。
- 以下のJSONコードをコピーして、
Ctrl + V
(Windows)またはCmd + V
(Mac)で貼り付ける。 - 表示されたワークフローに必要な認証情報を設定する。
JSONコードはこちら
実際にn8nで作成したワークフローをJSON形式でエクスポートしました。ぜひご活用ください!
作成したワークフロー
{
"nodes": [
{
"parameters": {
"trigger": [
"any_event"
],
"watchWorkspace": true,
"options": {}
},
"type": "n8n-nodes-base.slackTrigger",
"typeVersion": 1,
"position": [
-432,
240
],
"id": "27ec441f-27ba-490a-8dad-9d6874454902",
"name": "Slack Trigger",
"webhookId": "{{YOUR_WEBHOOK_ID}}",
"credentials": {
"slackApi": {
"id": "{{YOUR_SLACK_CREDENTIAL_ID}}",
"name": "{{YOUR_SLACK_ACCOUNT_NAME}}"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "cc267284-b13b-4899-8584-9d7be379ad72",
"leftValue": "={{ $json.text }}",
"rightValue": "<@{{YOUR_SLACK_USER_ID}}>",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-224,
240
],
"id": "d3a905e0-945d-4373-b298-39eed3bf2caf",
"name": "If"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
80,
384
],
"id": "1d02681a-70e6-47aa-aa92-3d4e850ca551",
"name": "No Operation, do nothing"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"name": "original_message",
"value": "={{ $('Slack Trigger').item.json.text }}",
"type": "string",
"id": "b6475be5-a3c0-4e79-9d73-bd6d2fcd1f28"
},
{
"name": "channel_id",
"value": "={{ $('Slack Trigger').item.json.channel }}",
"type": "string",
"id": "a8f4aa58-7248-488c-a1a4-8cfc2cac5c37"
},
{
"name": "user_id",
"value": "={{ $('Slack Trigger').item.json.user }}",
"type": "string",
"id": "dd8b7c0f-06ee-445c-9fa1-c241efb7cdcd"
},
{
"name": "timestamp",
"value": "={{ $now }}",
"type": "string",
"id": "c6cd9f03-3c2f-4a8e-b8b1-66b34da2685e"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
80,
176
],
"id": "7b9c55fd-2782-40b3-aee0-ae52d5ce4236",
"name": "メッセージ情報抽出"
},
{
"parameters": {
"promptType": "define",
"text": "=## 秘書AI - 返信案生成プロンプト\n\nあなたは**秘書AI**です。受信メッセージに対して、**2種類の返信案**を生成してください。\n\n---\n\n### 📥 受信メッセージ\n```\n{{ $json.original_message }}\n```\n\n---\n\n### ✅ 返信案の生成ルール\n\n#### 1. 基本フォーマット\n```\nお疲れ様です。(または「お世話になっております。」)\n[本文]\nご確認の程、よろしくお願いいたします。\n```\n\n#### 2. 特徴的な表現(例)\n- **依頼時**: 「〜していただけますと幸いです」「〜していただけると助かります」\n- **時間配慮**: 「お手すきの際に」「お忙しいところ恐縮ですが」\n- **確認依頼**: 「ご確認の程」「ご対応の程」\n- **感謝**: 「ありがとうございます!」\n- **謝罪**: 「申し訳ございません」(必要最小限に)\n\n#### 3. 構成要素\n- **メンション**: @ユーザー名 で対象者を明確化\n- **箇条書き**: 複数項目は「•」で整理\n- **URL**: 関連リンクは本文の後に配置\n- **絵文字**: 適度に使用(1〜2個まで)\n\n---\n\n### 📝 出力形式\n```\n【短い返信】\n[30〜60文字程度の簡潔な返信]\n\n【標準的な返信】\n[120〜220文字程度の丁寧な返信]\n```\n\n---\n\n### 🎯 返信パターン例\n(承諾・質問回答・依頼受領・PRレビュー・作業完了報告・問題報告・会議後 など)\n\n---\n\n### 現在時刻\n{{ $now }}",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2.1,
"position": [
320,
176
],
"id": "6ea26c52-426f-4666-970d-846a14c2a75c",
"name": "AI Agent"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "gpt-4o",
"mode": "list",
"cachedResultName": "gpt-4o"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
320,
432
],
"id": "b8150d9c-c4e1-4e52-bc21-21f5afc9463d",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"id": "{{YOUR_OPENAI_CREDENTIAL_ID}}",
"name": "{{YOUR_OPENAI_ACCOUNT_NAME}}"
}
}
},
{
"parameters": {
"select": "user",
"user": {
"__rl": true,
"value": "{{YOUR_SLACK_USER_ID}}",
"mode": "id"
},
"text": "={{ $json.output }}",
"otherOptions": {}
},
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
784,
176
],
"id": "1b9b0bd5-9920-4f3a-ad38-a1131d2acd97",
"name": "Send a message",
"webhookId": "{{YOUR_WEBHOOK_ID}}",
"credentials": {
"slackApi": {
"id": "{{YOUR_SLACK_CREDENTIAL_ID}}",
"name": "{{YOUR_SLACK_ACCOUNT_NAME}}"
}
}
},
{
"parameters": {
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "{{YOUR_GOOGLE_CALENDAR_EMAIL_1}}",
"mode": "list",
"cachedResultName": "{{YOUR_GOOGLE_CALENDAR_EMAIL_1}}"
},
"limit": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Limit', ``, 'number') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}",
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
"options": {}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [
736,
432
],
"id": "d26f7d74-70a5-43cf-aca4-c5059f011426",
"name": "Get many events in Google Calendar",
"credentials": {
"googleCalendarOAuth2Api": {
"id": "{{YOUR_GOOGLE_CALENDAR_CREDENTIAL_ID_1}}",
"name": "{{YOUR_GOOGLE_CALENDAR_ACCOUNT_NAME_1}}"
}
}
},
{
"parameters": {
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "{{YOUR_GOOGLE_CALENDAR_EMAIL_2}}",
"mode": "list",
"cachedResultName": "{{YOUR_GOOGLE_CALENDAR_EMAIL_2}}"
},
"limit": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Limit', ``, 'number') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}",
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
"options": {}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [
560,
432
],
"id": "e5c5880f-88e8-413e-b76d-6c1c90720e50",
"name": "Get many events in Google Calendar1",
"credentials": {
"googleCalendarOAuth2Api": {
"id": "{{YOUR_GOOGLE_CALENDAR_CREDENTIAL_ID_2}}",
"name": "{{YOUR_GOOGLE_CALENDAR_ACCOUNT_NAME_2}}"
}
}
}
],
"connections": {
"Slack Trigger": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "メッセージ情報抽出",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"メッセージ情報抽出": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Get many events in Google Calendar": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get many events in Google Calendar1": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "masked-instance-id"
}
}
動作イメージ
実際の動作イメージを紹介します。
例として「1 on 1 の調整をお願いされた」というSlackメッセージを想定しました。
画像のように、Google Calendar の予定も踏まえて返信案を提示してくれます。
場合によっては、そのまま必要な部分をコピペしてすぐに返事できそうですね。
想定メッセージ(私宛てに届いたもの)
AI秘書が考えた返信案
まとめ
まだ動作は不安定なところもありますが、「えっ、ここまでノーコードでできちゃうの?」と正直びっくりしました。
これまでは数千〜数万行のコードを書かないと実現できなかったような連携や自動化も、n8nならGUIでサクッと構築できるんです。
しかも、n8nには公式の ワークフローテンプレート集 が用意されていて、そこから選ぶだけで便利な仕組みがすぐに試せます。今回紹介したようなワークフローも、テンプレートを使えばあっという間に完成。
私自身は今後、RAGやカスタムプロンプトを組み合わせて、さらに精度の高い「自分専用AI秘書」に育てていきたいと思っています。
業務効率化の第一歩として、ぜひ一度 n8n を触ってみてください。

京都芸術大学のテックブログです。採用情報:hrmos.co/pages/xtm/jobs 芸大など5校を擁する瓜生山学園は、通信教育で国内最大手、国内で唯一notionと戦略パートナー契約を結ぶなどDX領域でも躍進、EdTech領域でAIプロダクトを開発する子会社もあり、実は多くのエンジニアがいます。
Discussion