目次
- 1 はじめに:何を作るか、を最初に言い切る
- 2 全体像:5部品が一列に並ぶだけ
- 3 まずは「サンプル本文で動作確認」のフェーズ
- 4 手順1:新しいワークフローを作って「手動で実行」を置く
- 5 手順2:処理するサンプル本文を1つ用意する(Edit Fields)
- 6 手順3:AIに項目を抜き出させる(Information Extractor)
- 7 手順4:AI(Gemini)を接続して、APIキーを入れる
- 8 手順5:実行してみる → 動いた、けど中身が全部嘘だった
- 9 手順6:説明を盛る → 直らない。モデルをProに変える → やっぱり直らない
- 10 手順7:Logsを開いたら、AIに本文が一文字も届いていなかった
- 11 手順8:サンプル投入を Gmail Trigger に差し替える
- 12 手順9:出口を Google Sheets と Slack に繋ぐ
- 13 手順10:「人検証」は弱点ではなく、設計に組み込む標準装備
- 14 本番デプロイ前のチェックリスト
- 15 つまずき早見表
- 16 まとめ:30分で手転記をゼロに、AI出力は人検証で受け止める
はじめに:何を作るか、を最初に言い切る
お問い合わせメールが届くたびに、本文から「名前」「連絡先」「要件」を手で拾って Excel やスプレッドシートに書き写す。地味だけど毎回発生する作業です。月に20件、30件と来るようになると、確認と転記だけで毎週1〜2時間が溶けます。
この記事で作るのは、それを丸ごと自動化する仕組みです。完成形はこうです。
- 専用のお問い合わせメアドにメールが届く
- AI(Google の Gemini)がメール本文を読んで「名前・連絡先・要件」を抜き出す
- Googleスプレッドシートに1行ずつ追加される
- Slack に「📩 新規問い合わせ:田中/カフェのHP作成」と通知が来る
これを n8n というノーコードの自動化ツールで組みます。コードは一行も書きません。 手順全部を画面のフォームに入力していくだけです。
ただし、この記事の本当のキモは、設定中に必ず一度ハマる「AIが本文を読まずに、それっぽいダミー値で全部埋めて返してくる」現象の正体と直し方です。私もこれで1時間迷子になりました。プロンプトを盛っても、モデルを上位に変えても、温度を下げても直りませんでした。原因はもっと手前にあって、ある一箇所の設定モードを切り替えるだけで一発で直ります。本番運用に乗せる前に必ず潰しておくべき罠なので、後半でじっくり書きます。
想定する入力は「メール本文(テキスト)」
最初に1つだけ前提を共有させてください。今回扱う「問い合わせ文」は、メール本文(テキスト)を想定しています。Gmailのお問い合わせ専用メアド宛のテキストメールが典型例です。
Webフォームから来るものでも、フォーム側が裏でメールに飛ばしている設計なら同じ扱いです。Slack や Chatwork のメッセージを入口にする場合は、入口のノードを Gmail Trigger から Slack Trigger に差し替えるだけで、それ以降の流れは同じです。
逆に、PDFや画像のお問い合わせ書類を読ませたい場合は、今回の仕組みの手前に OCR(PDF→テキスト変換)の工程が一本入ります。これは別記事のスコープとして、ここでは「文字データになった本文がある状態」からスタートします。
全体像:5部品が一列に並ぶだけ
完成すると、こういう流れになります。
[Gmail Trigger] → [Information Extractor] → [Google Sheets] → [Slack]
↑
[Google Gemini Chat Model]
それぞれが何をする部品か、先に1行ずつ説明しておきます。
- Gmail Trigger:n8n が定期的に Gmail をチェックし、新着メールがあれば後段に流す入口の部品。ここを差し替えれば Webフォーム や Slack 起点にもできる
- Information Extractor:「この文章からこれとこれを抜き出して」と項目名と説明を渡すと、AIに項目抽出させてくれる専用ノード。今回の主役
- Google Gemini Chat Model:Information Extractor の中で実際に推論を担当するAI。Googleの Gemini を選ぶための部品
- Google Sheets:抽出結果を1行として追記する出口。お馴染みのスプレッドシートに新規行が積まれていく
- Slack:「新規問い合わせ来た」と担当者にメンション通知する仕上げの部品
部品はたった5つ、線で繋ぐだけです。それでは作り方を順に見ていきます。
まずは「サンプル本文で動作確認」のフェーズ
本番のメール接続にいきなり繋ぐと、AIの挙動がおかしいときに本物の問い合わせメールが暴れます。なので最初は、サンプル文を1つ手で置いて動作だけ確かめるフェーズから始めます。これがノーコード自動化の基本のお作法です。
手順1〜4 でサンプル投入版を作り、手順5〜7 でその挙動と最大のハマりどころを潰します。本番接続(Gmail/Sheets/Slack)は手順8以降です。
手順1:新しいワークフローを作って「手動で実行」を置く

n8nを開いたら、新しいワークフローを作ります。まっさらな画面の真ん中に「Add first step…」と書かれた四角があるので、そこをクリックします。
すると「このワークフローは何で始まりますか?」と聞かれるので、一番上の Trigger manually(手動で実行) を選びます。これは「ボタンを押したら動く」という、いちばん分かりやすいスタートです。本番では Gmail Trigger に差し替えますが、まずは手動で動かして AI の挙動だけ見るのが安全です。
これで「When clicking ‘Execute workflow’」という最初のノードが置かれました。
手順2:処理するサンプル本文を1つ用意する(Edit Fields)

次に、AIに読ませる「問い合わせ文」を1つ用意します。本来はメールやフォームから入ってくるデータですが、まずは動作確認のためにサンプルの文章を手で置きます。
最初のノードの右にある「+」を押し、ノード検索に「Edit Fields」と打って Edit Fields (Set) を選びます。これは「データの項目を作る・書き換える」ためのノードです。
開いたら「Add Field」を押して、項目を1つ作ります。
- 名前(Name):
本文 - 値(Value):サンプルの問い合わせ文を貼り付け
今回はこういう、いかにも実際に来そうな雑な文章を入れました。
お世話になります。田中と申します。小さなカフェのホームページを作りたいです。予算は控えめですが、メニューと地図が載ればOKです。今月いっぱい(5/31)までに公開したいです。連絡は tanaka.cafe@example.com にお願いします。
名前・連絡先・要件・期日が、文章の中にバラバラに埋まっています。これをAIに整理させるのが狙いです。入力できたら左上の「Back to canvas」でキャンバスに戻ります。これで「手動で実行 → Edit Fields」がつながりました。
手順3:AIに項目を抜き出させる(Information Extractor)

ここからが本番です。Edit Fieldsの「+」から、ノード検索で 「Information Extractor」 を選びます。これは 文章から決めた項目を抜き出す専用のAIノードで、まさに今回やりたいことそのものです。
開くと設定フォームが出ます。やることは2つだけです。
(1) Text(どの文章を読むか)
「Text」の欄に、前のノードで作った本文を指定します。{{ $json.本文 }} と書くと、「Edit Fieldsで作った本文を読んでね」という意味になります。打つだけで、コードではありません。
——ただし、ここで後で大爆発する小さな選択を一個踏みます。詳しくは手順7で書きますが、ひとまずこの欄に {{ $json.本文 }} と素直にタイプして次へ進みました。
(2) Attributes(何を抜き出すか)
「Add Attribute」を押して、抜き出したい項目を作っていきます。今回は3つにしました。それぞれ「名前(項目名)」と「Description(その項目の説明)」を入れます。
| 項目名 | Description(最初に入れた説明) |
|---|---|
| 名前 | 問い合わせ者の氏名 |
| 連絡先 | メールアドレスまたは電話番号 |
| 要件 | 依頼したい内容 |
ここまでで「文章を読んで、この3項目を抜き出して」という指示が、画面のフォームだけで完成しました。
手順4:AI(Gemini)を接続して、APIキーを入れる
Information Extractorは「どのAIを使うか」を指定しないと動きません。フォームの下のほうにある「Model」の「+」を押すと、AIの一覧が出ます。今回は Google Gemini Chat Model を選びました。
選ぶと「Credential(接続情報)」を求められます。これは、自分のGemini APIキーを登録する画面です。
- 「Create new credential」を押す
- 「API Key」の欄に、自分のGemini APIキーを貼り付ける(Host欄はそのまま触りません)
- 「Save」を押す
APIキーは、Googleの「Google AI Studio」で無料で発行できます。コードに書くのではなく、n8nの専用フォームに入れるだけなので、初心者でも迷いません。保存すると「Connection tested successfully(接続成功)」と緑で出ます。出ればOKです。最後にモデルとして gemini-2.5-flash を選びました。速くて安いモデルです。
なお、気になる料金ですが、gemini-2.5-flash は非常に安いモデルで、今回のように1件の短い文章を数回処理するくらいなら、かかる費用は数円にもなりません。テストで何十回実行しても誤差レベルなので、初心者が「課金が怖くて試せない」と身構える必要はありません。まずは気軽に何度も実行して、AIの挙動を体で覚えるほうが先です。
これで「手動で実行 → Edit Fields → Information Extractor(+Gemini)」という、サンプル動作確認版の完成です。
手順5:実行してみる → 動いた、けど中身が全部嘘だった

キャンバス下の「Execute workflow」を押します。数秒待つと、全部のノードに緑のチェックが付いて「Workflow executed successfully」と出ました。動いたこと自体は成功です。
問題は中身でした。Information Extractorの出力を見ると、こうなっていました。
- 名前:山田太郎
- 連絡先:yamada.taro@example.com
- 要件:新規プロジェクトの件で相談したい。一度打ち合わせの機会を希望。
本文に書いたのは「田中/tanaka.cafe@example.com/カフェのホームページ作成」のはずです。それなのにAIは本文と一切関係ない、いかにも”サンプル文っぽい”値を3つとも返してきました。全部、AIの作文です。 「動いた、完成!」と判断して本番接続していたら、本物の問い合わせがどれもこんな値で記録されるところでした。

手順6:説明を盛る → 直らない。モデルをProに変える → やっぱり直らない
最初に疑ったのは「項目の説明(Description)が短すぎて、AIに何を抜くか伝わっていない」という線でした。そこで説明を、より丁寧で長い指示文に書き換えました。
- 連絡先:「本文に記載のメールアドレスまたは電話番号を原文のまま正確に」
- 要件:「本文で依頼・相談している具体的な内容を、本文の言葉で簡潔に。本文に無い内容は作らない」
人間に出す指示としては親切なはずです。これで再実行——変わりません。山田太郎、yamada.taro、汎用的な打ち合わせ希望文、3つとも同じです。
次に疑ったのはモデルの性能。gemini-2.5-flash は速いぶん軽量です。上位の gemini-2.5-pro に切り替えて再実行しました。今度は本気で読んでくれるはず——変わりません。一字一句、同じ山田太郎が返ってきました。
ここで一旦手が止まりました。説明を変えても直らない、モデルを上げても直らない、Sampling Temperature を 0 にしても直らない。AIは何を読んでこの値を返しているのか、本当に本文を見ているのか、それすら確信が持てなくなってきました。
手順7:Logsを開いたら、AIに本文が一文字も届いていなかった
ここで初めて、Information Extractor の右側パネルにある 「Logs」タブを開きました。ここには、ぶら下げた Google Gemini Chat Model が実際に Gemini API に送ったプロンプトの全文が出ます。一番下までスクロールして、本文がどう渡っているかを見ます。そこに書かれていたのは、これでした。
Human: {{ $json.本文 }}
——Geminiに届いていたのは、本文ではなく 「{{ $json.本文 }}」という文字列そのものでした。波カッコも $ もそのまま。Geminiから見たら「人間が {{ $json.本文 }} という呪文を送ってきた、何これ?」状態です。本文どころか問い合わせの「問」の字も届いていない。それで何か返せと言われたから、Geminiは「いかにもそれっぽいダミー」を組み立てて返していた。山田太郎・yamada.taro・新規プロジェクトの件で相談——典型的なAIの「分からないから無難な例で埋める」挙動です。

原因はモデルでも説明文でも温度でもなく、n8n の入力モードの罠でした。Text フィールドはデフォルトで「Fixed(固定文字列)」モードになっており、そこに {{ $json.本文 }} と書いても、ただの12文字の文字列として扱われます。変数として展開させたいなら、フィールドを「Expression」モードに切り替える必要があるんです。
切替方法は簡単で、Text フィールドの右上に出る「Fixed / Expression」のトグルから Expression を選ぶだけです。値の頭に「fx」マークが付き、すぐ下にプレビューが現れて、{{ $json.本文 }} が実際の本文(「お世話になります。田中と申します…」)に展開されている様子が確認できます。ここで本文が見えていなかったら、まだ届いていません。 プレビューが本文の冒頭を表示する、これがチェックの肝です。

この状態で Execute step を押すと、Gemini から返ってきた出力はこれでした。
- 名前:田中
- 連絡先:tanaka.cafe@example.com
- 要件:小さなカフェのホームページ作成。予算は控えめだが、メニューと地図の掲載は必須。5/31までに公開希望。
全部、本文どおりです。期日まで拾ってきました。直りました。原因はモデルでも説明文でもなく、そもそも AI に本文を渡せていなかっただけだったのです。

ここまでで、サンプル本文でAIがちゃんと動くことが確認できました。ここから先がいよいよ本番接続です。
手順8:サンプル投入を Gmail Trigger に差し替える
動作確認のために置いた Edit Fields は、本番では Gmail Trigger に置き換えます。「お問い合わせ専用メアドにメールが届いたら、自動で後段が動く」入口にするためです。
Edit Fields ノードを右クリックして削除し、代わりに「+」から Gmail Trigger を追加します。設定はこのくらいです。
- Credential(接続情報):Gmail OAuth。これは Google AI Studio の API キーとは別物で、Google Cloud Console で OAuth クライアントID を発行 → n8n の Gmail Trigger ノードのCredential画面に貼って認可ボタン、というGUI完結の手順です。コードは書きません
- Trigger On:
Message Received(新しいメッセージが届いたとき) - Filters:どのメールを拾うか。一番ラクなのは「ラベル」で絞る方法。Gmail側で問い合わせメアドに自動で
inquiryのラベルが付くフィルタを作っておき、n8n側ではlabel: inquiryを指定する - Poll Interval:何分おきにGmailをチェックするか。1分でも数分でもお好みで
これで「inquiry ラベルが付いたメールが届いたら自動起動」する入口の完成です。
ここで 手順7と同じ罠を必ず再発させないために、もう一度 Text フィールドを確認します。入力ソースが Edit Fields から Gmail Trigger に変わったので、参照する変数名も変わります。Gmail Trigger は本文を text や snippet というフィールドで返すので、Information Extractor の Text 欄を {{ $json.text }} などに書き換えます(実際の名前は Gmail Trigger の Output パネルで確認)。
そして必ず、Text フィールドが Expression モード(fx印)になっていて、プレビューに本物のメール本文が展開されていることを目視で確認してください。ここを見落とすと、本番で全件「山田太郎」が記録される事故が起きます。
手順9:出口を Google Sheets と Slack に繋ぐ
抽出結果の出口を作ります。
Google Sheets(行追加)
Information Extractor の右の「+」から Google Sheets ノードを追加し、Operation は Append Row(行追加) を選びます。
- Credential:Google Sheets OAuth(GoogleアカウントでログインしてOKを押すだけ)
- Document:あらかじめ作っておいたスプレッドシートを選ぶ。例:「お問い合わせ管理」
- Sheet:タブを選択。例:「2026年受付」
- Column Mapping:n8n が自動で属性(名前/連絡先/要件)を検出するので、スプシ側の列名(例:「お名前」「連絡先」「ご依頼内容」「受付日時」「確認ステータス」)と1対1で対応付ける
- 「確認ステータス」列のデフォルト値:
未確認を入れておく。これは後段の人検証で効きます
Slack(メンション付き通知)
Google Sheets の右の「+」から Slack ノードを追加し、Resource は Message、Operation は Send を選びます。
- Credential:Slack の OAuth、または Webhook URL(チャンネル単位の簡易方式)
- Channel:
#inquiriesのような専用チャンネル - Message Text:テンプレで埋める。例:
📩 新規問い合わせ:{{ $json.名前 }} 様
連絡先:{{ $json.連絡先 }}
ご依頼内容:{{ $json.要件 }}
<!subteam^担当者ID> 内容確認お願いします
ここでも各 {{ ... }} を入れる欄は Expression モードであることを必ず確認してください。Fixed のままだと、Slackに「{{ $json.名前 }} 様」という呪文が流れます(経験者は語る)。
完成した本番フローはこうなります。
[Gmail Trigger] → [Information Extractor] → [Google Sheets(Append)] → [Slack(Send)]
↑
[Google Gemini Chat Model]
これでもう、お問い合わせメールが届くたびに、スプレッドシートに1行追加され、Slackにメンション付き通知が飛びます。手作業の転記はゼロです。
手順10:「人検証」は弱点ではなく、設計に組み込む標準装備
ここで多くの初心者が引っかかるポイントがあります。「AIの抽出って間違うんでしょ?じゃあ自動化って結局信用できないじゃん」——これは半分正解で、半分外しています。
正しいのは、AIの抽出は本文がちゃんと届いていても100%にはなりません。今回直したのは「本文すら届いていなかった」という別の話で、本文が届いた後でも、たまに表記が微妙にズレたり、本文の趣旨を別の言葉で言い換えたりはします。
外しているのは、だから自動化できない、という結論です。AIの抽出精度を100点にしようとせず、95点AI + 5点の人検証 = 100点の運用、と割り切ると、自動化は十分に成立します。今回のフローで「人検証」を以下の3点として標準装備しています。
- Slack通知に担当者をメンション:通知が流れて気付かれないリスクを潰す
- スプシの「確認ステータス」列:デフォルト「未確認」を入れて、人が目視確認したら「確認済」に変える。AIが返したそのままの値が台帳に流れ込むことはあっても、人の目を通らないまま”正式な顧客データ”になることはなくなる
- 毎朝の未確認チェック:n8n をもう1本(Cron Trigger → Sheets「未確認」行抽出 → Slack 朝礼通知)組めば、確認漏れもゼロにできる。1回組めば永久に動く
この設計にしてしまえば、AIがたまにズレても運用は止まりません。「AIに任せる範囲」と「人が必ず通る一拍」を最初から分けて組む。これがノーコード自動化を本番に乗せるときの考え方の本筋です。
本番デプロイ前のチェックリスト
スプシ転記の手作業を実際に止める前に、以下を必ず確認してください。手順7の罠で1時間溶かさないために。
- [ ] Information Extractor の Text フィールドが Expression モード(fx印) になっている
- [ ] プレビューに 展開後の本文が見えている(
{{ $json.本文 }}のままになっていない) - [ ] Logs を末尾まで開いて、
Human: ...の後ろが 本物の本文文字列になっている(変数名のままなら未展開) - [ ] Google Sheets のColumn Mappingが 全項目埋まっている
- [ ] Slack のメッセージテンプレが Expression モードで書かれていて、テストチャンネルで1回ドライランしてプレビュー確認している
- [ ] 「確認ステータス」列の デフォルト値「未確認」が入っている
- [ ] 朝礼用の未確認リマインダー(任意)が組まれている
つまずき早見表
同じ所で止まったら、ここに戻ってきてください。
| 症状 | 原因 | 対処 |
|---|---|---|
| 動くが本文と無関係の典型ダミー値(山田太郎、yamada.taro等)が返る | Text フィールドが Fixed モードのままで、{{ $json.本文 }} が文字列としてAIに送られている |
Text フィールドを Expression モードに切替。プレビューに展開後の本文が表示されることを確認 |
| プロンプトを丁寧にしても、モデルを上位に変えても出力が改善しない | そもそも本文がAIに届いていない可能性が高い | Logs タブで Gemini への実リクエストを末尾まで読み、本文が文字列として展開されているか確認 |
| 本文は届いているが、たまにそれっぽい値で埋めてくる | AIは「分からない時、もっともらしい値で埋める」性質がある | Slack通知+スプシ「確認ステータス」列で人検証を組み込む |
| Gmail Trigger が起動しない | ラベル/フィルタ/Polling間隔の設定漏れ | Gmail 側で inquiry ラベルが本物メールに付くフィルタが動いているか、Polling間隔が短すぎないか確認 |
| Google Sheets で列マッピングが空になる | Information Extractor の属性名と Sheets 列名が違う | 属性名(名前/連絡先/要件)と列名を一致させる、または Column Mapping を手動で再設定 |
Slack通知に {{ $json.名前 }} の呪文がそのまま流れた |
Slack ノードの Message Text フィールドが Fixed モード | Expression モードに切替(手順7と同じ罠の再発) |
| 接続エラーで動かない | APIキー/OAuth未登録または失効 | Credential画面で再認証「Connection tested successfully」を確認 |
まとめ:30分で手転記をゼロに、AI出力は人検証で受け止める
n8n と Gemini で、お問い合わせメールから「名前・連絡先・要件」を自動でスプレッドシートに転記し、Slack に通知するところまでを通しで作った記録でした。要点です。
- 完成形は 5部品(Gmail Trigger / Information Extractor / Google Gemini Chat Model / Google Sheets / Slack) の直列。コードは一行も書かない
- 設定中に必ず一度ハマるのが「AIが本文を読まずに山田太郎を返す」現象。プロンプトを盛ってもモデルを上げても直らない
- 真犯人は Text フィールドが Fixed モードのまま
{{ $json.本文 }}を文字列として AI に送っていたこと。Expression モードに切替えるだけで一発解決 - 本番デプロイ前には Logs を末尾まで開いて、変数が本文に展開されているか目視確認する。これを毎回やる
- 本文が届いた後でも、AIは”ありそうな値”で埋める癖を完全には捨てない。Slack通知+スプシ「確認ステータス」列で人検証を運用に組み込む
- 「AIの精度を100点にする」ではなく、95点AI + 5点の人 = 100点の運用として設計する
ノーコードでAIに作業させると、画面上は緑のチェックが並んでいて成功しているように見えても、裏でAIには空の呪文しか届いていない、という事故が起きます。そして上のレイヤー(プロンプト・モデル・温度)をいくらいじっても直りません。出力がどうにもおかしい時は、思い切って Logs を開いて「AIに何が届いているか」を生で見るクセを付けると、迷走時間を1時間単位で削れます。さらに、本番では「Slack通知+確認列」で人検証を最初から組み込んでおくと、AIがたまにズレても運用が止まりません。同じ所でつまずいている方の遠回りが、この記録で少し減れば幸いです。