メールから来る問い合わせをn8nでHuman in the loopしつつ自動化する方法
こんにちは、酒井です!
株式会社 EGGHEAD(エッグヘッド)という「製造業で生成 AI を活用したシステム開発」をしている会社の代表をしております。
1. はじめに
生成AIノーコードツールとして人気なのはDifyですが、メール受信をトリガーとしたワークフロー実行やHuman-in-the-loop機能には制約があります。メール受信のトリガーはGASと連携すれば実現可能ですが、二重管理が必要になってしまいます。
本記事では、これらの課題を一元的に解決できるワークフロー自動化ツール「n8n」をご紹介します。n8nを使えば、メール受信から処理の自動化と人間の判断を組み込んだフローを直感的に構築できます。
n8nを使うと以下のようなことができます。
- メールを受信する
- そのメールから必要な情報を抽出
- Slackに通知を送信する
- Slackの内容を承認/却下する
- 承認された場合のみGoogle Sheetsにデータを追加
今回はGoogle Sheetsに追加にしましたが、これはNotionやSalesforceなどAPIが公開されているサービスであれば置き換えることが可能です。
では、実際にn8nでワークフローを構築していきます。
2. 前提条件と環境準備
n8nのインストール
n8nは以下の方法で利用開始できます。
- クラウド版(n8n.cloud): 最も手軽に始められる方法です。n8n.cloudからアカウントを作成するだけで利用できます。
- セルフホスト: 自社サーバーやクラウドサービス(AWS、GCP、Azureなど)に自分でインストールする方法です。
今回はローカル環境で動かしていきます。その場合、以下のコマンドでインストールできます。
$ npm install n8n -g
$ n8n start
インストール後、ブラウザで http://localhost:5678
にアクセスすると、n8nのUIが表示されます。
必要なアカウントと連携設定
このワークフローには以下のサービスが必要です。
- Gmail: メールの受信をトリガーにします
- Slack: Human in the loopをするために使います
- Google Sheets: 最終的なデータの保存先です
各サービスの連携設定を行っていきます。
Gmailの連携設定
- Google Cloud Consoleでプロジェクトを作成
- Google Gmail APIを有効化
- APIとサービスの「認証情報」から「認証情報を作成」をクリックして、OAuthクライアントIDを作成します。
3.1. アプリケーションの種類を「ウェブアプリケーション」を選択
3.2. 承認済みリダイレクトURIにn8nのコールバックURL(http://localhost:5678/rest/oauth2-credential/callback
)を追加 - クライアントIDとクライアントシークレットを取得
Slackの連携設定
- Slack APIでアプリを作成
- 「OAuth & Permissions」から「Scopes」から権限を追加(
chat:write
,im:write
など)します - Bot User OAuth Tokenを取得
- アプリをSlackのワークスペースにインストール
Google Sheetsの連携設定
- Google Cloud ConsoleでGoogle Sheets APIを有効化
- OAuth 2.0クライアントIDを使用(Gmail連携と共用可能)
これらの認証情報は、n8nでノードを設定する際に使用します。
3. ワークフロー構築:全体像
今回構築するワークフローは以下の流れになります。
- 特定の条件に一致するGmailメールを受信
- メールから必要な情報を抽出
- Slackに通知を送信し、承認/却下ボタンを表示
- ユーザーがSlackで承認した場合のみ、Google Sheetsにデータを追加
- 処理結果をSlackに通知
n8nのUIでは、このフローを「ノード」と呼ばれるコンポーネントを繋げることで視覚的に構築していきます。
4. Gmail連携の設定
まず、Gmailからメールを取得するトリガーノードを設定します。
Gmailトリガーノードの追加
- n8nのワークフローエディタを開き、「+」ボタンをクリック
- 「Gmail」を検索して「On message received」を選択
- 「Create new credential」から先ほど取得したGoogleの認証情報を入力
- 「Authentication」ボタンをクリックしてn8nとGoogleアカウントを連携
以下が取得される情報です。
[
{
"id": "195a8e6a9a5bebae",
"threadId": "195a8e6a9a5bebae",
"snippet": "株式会社EGGHEAD 営業担当者様 いつもお世話になっております。 株式会社山田製作所の田中と申します。 「型番:AB123」の製品につきまして、発注を検討しております。 以下の内容で対応可能かどうか、ご確認いただけますでしょうか。 希望納期:2025年3月10日数量:100個 また、見積もり書をいただけると助かります。 お忙しいところ恐縮ですが、ご返信いただけますようお願い申し上げます。 株式",
"payload": {
"mimeType": "multipart/alternative"
},
"sizeEstimate": 7698,
"historyId": "195173",
"internalDate": "1742295431000",
"labels": [
{
"id": "INBOX",
"name": "INBOX"
},
{
"id": "IMPORTANT",
"name": "IMPORTANT"
},
{
"id": "CATEGORY_PERSONAL",
"name": "CATEGORY_PERSONAL"
}
],
"From": "shun sakai <ss211.sabcabc12312395.18@gmail.com>",
"Subject": "製品発注についての問い合わせ",
"To": "sakai.shun@egghead.co.jp"
}
]
メールフィルタリング条件の設定
Filtersでは、送信者や件名など様々な条件でメールをフィルタリングすることができます。あらゆる条件でフィルタリングできるのでやりたいことはほとんどできると考えていいです。
メール本文からの情報抽出
Gmailの「On message received」から取得した情報にはメール本文が含まれません。そのため、メール本文を取得するためのノードを追加します。
- 「Gmail」を検索して「Get a message」を選択
- 以下のような設定を行い、メール本文から情報を抽出
2.1. Credential to connect with:先ほど設定したアカウントを選択
2.2. Resource:Message
2.3. Operation:Get
2.4. Message ID:{{ $json.id }}
2.5. Simplify:オフ
これにより、取得できるデータは以下です。
[
{
"id": "195a8e6a9a5bebae",
"threadId": "195a8e6a9a5bebae",
"labelIds": [
"IMPORTANT",
"CATEGORY_PERSONAL",
"INBOX"
],
"sizeEstimate": 7698,
"headers": {
"delivered-to": "Delivered-To: sakai.shun@egghead.co.jp",
"received": "Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41])\r\n by mx.google.com with SMTPS id a640c23a62f3a-ac314809be3sor479355866b.3.2025.03.18.03.57.23\r\n for <sakai.shun@egghead.co.jp>\r\n (Google Transport Security);\r\n Tue, 18 Mar 2025 03:57:23 -0700 (PDT)",
"x-received": "X-Received: by 2002:a17:907:cd04:b0:abf:6d1c:8f4a with SMTP id\r\n a640c23a62f3a-ac38ff8e98cmr297350766b.18.1742295442795; Tue, 18 Mar 2025\r\n 03:57:22 -0700 (PDT)",
"arc-seal": "ARC-Seal: i=1; a=rsa-sha256; t=1742295443; cv=none;\r\n d=google.com; s=arc-20240605;\r\n b=QLk+iunkgZ/jIV/LSClIWFbyJWjaurKA9H98K0iYrptLqTYQMuW8t23+RLvkf7Ph4x\r\n FamfbRkr6V6abyv+CJTOI/kfF3rJrRpJcXth/4+NMVd1P9R02KhccO2v5YwLuCie0B33\r\n TiAKzZ8n01wbt38UhAu6taOOMWPyEJkNOKwlY9H1GlLYCN9xnkizw7xCymIZm3hKSYAy\r\n j4Nk0dDXKOf44xruLCzGSYrv3GKmIPW1ni2mnxxpCberXUzPEFUBYHWLLMtbcyCSSoO4\r\n WyeJZsHFyplaoE8hTznmJLdBjQYz/dzPv5v8nlZdDdtYXUHEUIGAyDJBgHr48tZIMdlQ\r\n hrMg==",
"arc-message-signature": "ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605;\r\n h=to:subject:message-id:date:from:mime-version:dkim-signature;\r\n bh=pULAjCOyS35rlCvwIn0AYwmTC+dTJLrIqlq1oDBp+9Q=;\r\n fh=M5NiiYFDfgh9JphlTlklptZlfBNx6r5VP9QHao54rHM=;\r\n b=K0lQ7AagePkWj8MWmDWYUzHdCWfBCf2JtpMV/U0DuldUuyN1EcFNClztW7omRsDghw\r\n 3AnJPD1AKDIDt8mHVv8Cw984XXBkSDSHNjEKro/ZvhCFsdv3oF/IqDhe26pOISdgBhz4\r\n RlpLlGRNEVDEjj+Cum/t2FnDu2rP1likICE+QMxwNSZxgo7qF73Du6Y5lBKp2qruE3lE\r\n wQZcyAno8rQfa1JhQmD8jZvoPNZKV/ONBVjbBC/ujtpPDBGKTzhGlvQrmQvLimvDVzzx\r\n a0OfWrzxco4BUG+HAYrk1Yy2zCsTv4sYHe7RkHfRVq0qY9vzoD6DpBInM81kqyWovWuG\r\n YFsw==;\r\n dara=google.com",
"arc-authentication-results": "ARC-Authentication-Results: i=1; mx.google.com;\r\n dkim=pass header.i=@gmail.com header.s=20230601 header.b=UFDb6MT8;\r\n spf=pass (google.com: domain of ss211.sabcabc12312395.18@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=ss211.sabcabc12312395.18@gmail.com;\r\n dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com;\r\n dara=neutral header.i=@egghead.co.jp",
"return-path": "Return-Path: <ss211.sabcabc12312395.18@gmail.com>",
"received-spf": "Received-SPF: pass (google.com: domain of ss211.sabcabc12312395.18@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41;",
"authentication-results": "Authentication-Results: mx.google.com;\r\n dkim=pass header.i=@gmail.com header.s=20230601 header.b=UFDb6MT8;\r\n spf=pass (google.com: domain of ss211.sabcabc12312395.18@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=ss211.sabcabc12312395.18@gmail.com;\r\n dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com;\r\n dara=neutral header.i=@egghead.co.jp",
"dkim-signature": "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r\n d=gmail.com; s=20230601; t=1742295443; x=1742900243; darn=egghead.co.jp;\r\n h=to:subject:message-id:date:from:mime-version:from:to:cc:subject\r\n :date:message-id:reply-to;\r\n bh=pULAjCOyS35rlCvwIn0AYwmTC+dTJLrIqlq1oDBp+9Q=;\r\n b=UFDb6MT8wYLPkK6kiRTqee8X3Sdi3uJlIxGRWEn7PmAI3jmFDIvQN5YHf6mWVPoNye\r\n zm/PP8bYV+Qpf4vU2souUv6HW6Pxa20ArDzx/9bO3pSg1fw1idtAVivIRhB8/pO9tSXy\r\n HzvaDuPkA+6iEIeYnGjn2xOuSu+lBf3ZaDsGMJcJ/fI9RZu29EgJzJWbcrBPu/PL1RTE\r\n TvOVxfDxbNnxDYEbpkJO8MRWrMPyAURxxzzMYMb9CY2enM+f/Z9i0AqrWyEf5S35cfIJ\r\n N1Jh5rZxlHPWUDTMTQ82yBo4rWojYHr/9MRNDRXEY5T1Q2YF0caSGwMzf9sEYEvmipvr\r\n EtDw==",
"x-google-dkim-signature": "X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r\n d=1e100.net; s=20230601; t=1742295443; x=1742900243;\r\n h=to:subject:message-id:date:from:mime-version:x-gm-message-state\r\n :from:to:cc:subject:date:message-id:reply-to;\r\n bh=pULAjCOyS35rlCvwIn0AYwmTC+dTJLrIqlq1oDBp+9Q=;\r\n b=woVm6Of3yCcFaBJ1jzR8+vS0yBrzDRaJtbiuw3/L1MvhY2TShOWhO2c3xBxosSsO8H\r\n IedNrs0Y9KlyKLDcPWyCCBM5b5ULyP1WJAI5xeffcicTDi9GMGo/jlcjBbcjtdSJyj4k\r\n UoGm0pVsz6ovyE9eUfcq48HgtvCaxNX02Gcmtn3PDv+sogIHhpTRlTDhe4V310g09TZW\r\n 9hf96Q8RmWlqo+64Dzwrlk6zSZaG4bWEDt7L8oe8UqksfNUeAaE6A9hrJ7apW3uDoH17\r\n mw0qeoshooWh/SIwyWGF7xsjnspMq7WcbPVfIUkj/ULnAorLvxnTKmkkawTYQGpoWx12\r\n M8Qg==",
"x-gm-message-state": "X-Gm-Message-State: AOJu0YymE7jH/pn66d7CbnOoVAlnWKrPO4jeferr9speIK4x/PgrIb0z\r\n\tkRRkv3J+32KMv5UtAyx8ikgGsVavm9plTQ9Fm+sgrliitJ/+DfMCeMJGyEKbhewtwfa412BuA8q\r\n\tqkLAN5Qn+lvo5hSNJ1bttk+jgr/WrR+3FcLc=",
"x-gm-gg": "X-Gm-Gg: ASbGncs5qDEEG6bA37pCCX3n1lmWin1eCMyOZw+Yo9jrROjzDae9hgpc/caxM1uRMA5\r\n\tXb8PwfrQglfE4UICDfb78tVPZ1J/fWWuzcVpUvTrhsyTpnh9WkiKvRQsDuuwUSW3+UK59sigiJn\r\n\t70tLX5em1h+SjPvXEPZkptAtNySN56",
"x-google-smtp-source": "X-Google-Smtp-Source: AGHT+IGAoyIVqSBFRoydlLITqbPzBrEaGFlrYUsasJd9DXQOU9MtfhPG3bDrghYZkUSyKcldi+/6H56NNNHPK2mdih4=",
"mime-version": "MIME-Version: 1.0",
"from": "From: shun sakai <ss211.sabcabc12312395.18@gmail.com>",
"date": "Date: Tue, 18 Mar 2025 19:57:11 +0900",
"x-gm-features": "X-Gm-Features: AQ5f1JoZbOxfUiKR47XSTx-LjxanKPiChgX6Hy9o1XaG9JDUVtyMAPyz8lpZdDI",
"message-id": "Message-ID: <CABgrK5rYZ7LORGDcghQsP5CaDh=Y_F3cLpFYurimk9aHTN6OsA@mail.gmail.com>",
"subject": "Subject: =?UTF-8?B?6KO95ZOB55m65rOo44Gr44Gk44GE44Gm44Gu5ZWP44GE5ZCI44KP44Gb?=",
"to": "To: sakai.shun@egghead.co.jp",
"content-type": "Content-Type: multipart/alternative; boundary=\"000000000000f636d106309bc463\""
},
"html": "<div dir=\"ltr\">株式会社EGGHEAD<br>営業担当者様<br><br>いつもお世話になっております。<br>株式会社山田製作所の田中と申します。<br><br>「型番:AB123」の製品につきまして、発注を検討しております。<br>以下の内容で対応可能かどうか、ご確認いただけますでしょうか。<br><br>希望納期:2025年3月10日<br>数量:100個<br><br>また、見積もり書をいただけると助かります。<br><br>お忙しいところ恐縮ですが、ご返信いただけますようお願い申し上げます。<br><br>株式会社山田製作所<br>製造部 田中一郎<br>電話:03-1234-5678<br>メール:<a href=\"mailto:tanaka@example.co.jp\" target=\"_blank\">tanaka@example.co.jp</a></div>\n",
"text": "株式会社EGGHEAD\n営業担当者様\n\nいつもお世話になっております。\n株式会社山田製作所の田中と申します。\n\n「型番:AB123」の製品につきまして、発注を検討しております。\n以下の内容で対応可能かどうか、ご確認いただけますでしょうか。\n\n希望納期:2025年3月10日\n数量:100個\n\nまた、見積もり書をいただけると助かります。\n\nお忙しいところ恐縮ですが、ご返信いただけますようお願い申し上げます。\n\n株式会社山田製作所\n製造部 田中一郎\n電話:03-1234-5678\nメール:tanaka@example.co.jp\n",
"textAsHtml": "<p>株式会社EGGHEAD<br/>営業担当者様</p><p>いつもお世話になっております。<br/>株式会社山田製作所の田中と申します。</p><p>「型番:AB123」の製品につきまして、発注を検討しております。<br/>以下の内容で対応可能かどうか、ご確認いただけますでしょうか。</p><p>希望納期:2025年3月10日<br/>数量:100個</p><p>また、見積もり書をいただけると助かります。</p><p>お忙しいところ恐縮ですが、ご返信いただけますようお願い申し上げます。</p><p>株式会社山田製作所<br/>製造部 田中一郎<br/>電話:03-1234-5678<br/>メール:tanaka@example.co.jp</p>",
"subject": "製品発注についての問い合わせ",
"date": "2025-03-18T10:57:11.000Z",
"to": {
"value": [
{
"address": "sakai.shun@egghead.co.jp",
"name": ""
}
],
"html": "<span class=\"mp_address_group\"><a href=\"mailto:sakai.shun@egghead.co.jp\" class=\"mp_address_email\">sakai.shun@egghead.co.jp</a></span>",
"text": "sakai.shun@egghead.co.jp"
},
"from": {
"value": [
{
"address": "ss211.sabcabc12312395.18@gmail.com",
"name": "shun sakai"
}
],
"html": "<span class=\"mp_address_group\"><span class=\"mp_address_name\">shun sakai</span> <<a href=\"mailto:ss211.sabcabc12312395.18@gmail.com\" class=\"mp_address_email\">ss211.sabcabc12312395.18@gmail.com</a>></span>",
"text": "\"shun sakai\" <ss211.sabcabc12312395.18@gmail.com>"
},
"messageId": "<CABgrK5rYZ7LORGDcghQsP5CaDh=Y_F3cLpFYurimk9aHTN6OsA@mail.gmail.com>"
}
]
4. OpenAIノードによる情報抽出
メールから重要な情報を抽出するために、OpenAIのAPIを活用します。
OpenAIノードの設定
- ワークフローに「OpenAI」ノードを追加
- 「Create new credential」からOpenAIのAPIキーを入力
- 以下のような設定を行う
3.1. Resource:Text
3.2. Operation:Message a Model
3.3. Model:使うモデルを選択
3.4. Prompt:「中小製造業に対する問い合わせメールが来ています。メールの内容を要約してください。メールの内容が以下です。{{ $json.text }}」
3.5. Role:User
このような情報が取れます。
[
{
"index": 0,
"message": {
"role": "assistant",
"content": "中小製造業の製品に関心があり、価格や納期、最低発注数量などについて情報を提供してほしいという内容です。サンプルを送付することや工場見学を希望していることも記載されています。",
"refusal": null,
"annotations": []
},
"logprobs": null,
"finish_reason": "stop"
}
]
5. Slack連携によるHuman-in-the-loop実装
次に、抽出した情報をSlackに送信し、人間の判断を仰ぐフローを構築します。
Slackノードの設定
- 「OpenAI」ノードの後に「Human in the loop」から「Slack」ノードを追加
- 「Create new credential」から先ほど取得したSlackの認証情報を入力
- 以下のような設定を行う
3.1. Resource:Message
3.2. Operation:Send and Wait for Response
3.3. Send Message To:Channel
3.4. Channel:By ID として、チャンネルIDを入力
送信したいSlackチャンネルのリンクをコピーして、チャンネルIDを取得します。例えば、「https://eggheadai.slack.com/archives/123456789a」だとしたら「123456789a」がチャンネルIDです。
3.5. Message:「以下のメールの内容をスプレットシートに追加しますか? ## メール内容 {{ $json.message.content }}」
3.6. Response Type:Approval
設定したチャンネルに以下のようなメッセージが届きます。「Approve」ボタンを押すと続きのフローが実行されます。
6. Google Sheets連携
ユーザーがSlackで「承認」ボタンをクリックした場合に、データをGoogle Sheetsに登録するフローを設定します。
Google Sheetsノードの設定
- ワークフローに「Google Sheets」ノードを追加
- 「Create new credential」から先ほど取得したSlackの認証情報を入力
- 以下のような設定を行う
3.1. Resource:Sheet Within Document
3.2. Operation:Append Row
3.3. Document:「From list」から追加するスプレットシートを選択
3.4. Sheet:「From list」から追加するシートを選択
3.5. Mapping Column Mode:Map Each Column Manually
3.6. Values to Send:列が取得されるので、登録する値を入力
9. まとめ
n8nはオープンソースのワークフロー自動化ツールであり、自社サーバー上に構築できるため、セキュリティ要件の厳しい企業でもデータを完全に自社環境内で管理しながら運用できます。Difyでは実現困難なHuman in the loopの機能を備え、400種類以上のアプリケーションとの連携が可能な点が大きな強みです。
特にメール受信をトリガーとしたワークフロー実行は、業務自動化において非常に有用です。私が現在取り組んでいる中小製造業の業務効率化でもn8nを活用してメール受信をトリガーに、受注管理システムへの登録を検討しています。
(支援先の製造業で使っているソフトではAPIを公開していないので、工夫は必要ですが)
ノーコードで直感的に操作できるn8nを皆さんの業務効率化にも取り入れてみてください!
Discussion