【Dify×GAS】検索から営業メール作成・スプシ転記までを完全自動化するツールの作り方

blog

新規開拓のリストアップと1件ずつのメール作成、本当に骨が折れる作業ですよね。

今回は、AI開発プラットフォーム「Dify」を活用して、「キーワードから対象企業を検索 → 課題を分析 → 提案の営業メールを作成 → スプレッドシートに自動転記」という一連の流れを完全自動化するツールの作り方をご紹介します。

Web制作の営業ツールとして構築しましたが、プロンプトを変えるだけでSaaS営業やDX支援、コンサルティングなど、あらゆるアウトバウンド営業に転用可能です。

実際に運用する中でつまずいたエラー(テキストの途切れ、GASの連携ミスなど)の解決策もすべてまとめているので、ぜひ参考にしてみてください!

今回作成するツールの全体像

Difyのワークフローを使って、以下の構成でツールを作成します。

【Difyのフロー構成】

スタートTavily(検索)LLM(メール作成)コード(データ分割)HTTPリクエスト(スプシへ送信)

最終的に、Googleスプレッドシートに「日付」「URL」「先方のメールアドレス」「抽出した課題」「営業メール本文」が綺麗に整理されて自動で蓄積されていく仕組みを作ります。


ステップ0:TavilyのAPIキーを取得・設定する

今回のフローで「Web検索」の役割を担うのが、LLM向けに最適化された検索エンジン「Tavily(タビリー)」です。まずはDifyでTavilyを使えるようにする準備を行います。

  1. APIキーの取得: Tavilyの公式サイトにアクセスし、アカウントを作成します。ダッシュボードから「API Key」を生成してコピーしてください(※無料プランでも月に1,000回まで検索が可能です)。
  2. Difyへの設定: Difyのトップ画面上部にある「ツール」メニューを開き、プロバイダー一覧から「Tavily」を探して「承認する」をクリックします。そこに先ほどコピーしたAPIキーを貼り付けて保存します。

これで、Difyのワークフロー内でTavilyノードが自由に使えるようになります。


ステップ1:LLMのプロンプトで出力をコントロールする

Tavilyで検索した企業の情報をLLMに渡し、営業メールを作成させます。

スプレッドシートに転記しやすくするため、出力フォーマットを4つの項目にガチガチに固定するのがポイントです。

業種に合わせて、以下のプロンプト例を参考にカスタマイズしてみてください。

パターンA:Web制作・リニューアル営業の場合(プロンプト)

提供される対象Webサイトの解析データ(ソースコードや検索結果)を読み込み、以下の4つの項目を必ず出力してください。

1. 【対象のWEBサイトURL】
2. 【先方のメールアドレス】
※見当たらない場合は「不明(要手動確認)」と記載
3. 【抽出した課題】
※スマホ未対応、古いテーブルレイアウト、非SSLなど、サイトが「古い」と判定できる要素を具体的に箇条書きで抽出
4. 【営業メールドラフト】
※抽出した課題を指摘しつつ、最新のモダンなサイトへのリニューアルを提案する文面を作成。末尾に必ず固定署名を付与すること。

パターンB:DX支援・SaaS営業などの場合(プロンプト)

提供される対象企業のWebサイトデータや検索結果を読み込み、以下の4つの項目を必ず出力してください。

1. 【対象のWEBサイトURL】
2. 【先方のメールアドレス】
※見当たらない場合は「不明(要手動確認)」と記載
3. 【抽出した課題】
※企業の事業内容や採用ページの情報から、「アナログな業務管理」「属人的なシフト作成」「DX化の遅れ」など、業務効率化の余地がある課題を推測して箇条書きで抽出
4. 【営業メールドラフト】
※推測した課題に寄り添い、弊社のDX支援・業務効率化ツールを導入することでコスト削減や業務改善ができることを提案する文面を作成。末尾に必ず固定署名を付与すること。


ステップ2:コードノードでデータを4つに分割する(超重要!)

ここが一番のキモです。

LLMが出力した長いテキストをそのままスプレッドシートに送ろうとすると、文章内の記号(「”」や改行など)が原因でデータが途切れてしまうエラーが発生します。

これを防ぐため、LLMとHTTPリクエストの間に「コード(Python)」ノードを挟み、テキストを4つのパーツに綺麗に切り分けます。

【コードノードの設定】

  • 入力変数: llm_output (LLMの出力を指定)
  • 出力変数: url, email, challenges, draft (すべてString型)
  • コード(Python3):

Python

import re def main(llm_output: str) -> dict: url_match = re.search(r’【対象のWEBサイトURL】\s*(.*?)(?=2\.|【先方のメールアドレス】|$)’, llm_output, re.S) email_match = re.search(r’【先方のメールアドレス】\s*(.*?)(?=3\.|【抽出した課題】|$)’, llm_output, re.S) challenges_match = re.search(r’【抽出した課題】\s*(.*?)(?=4\.|【営業メールドラフト】|$)’, llm_output, re.S) draft_match = re.search(r’【営業メールドラフト】\s*(.*)’, llm_output, re.S) return { “url”: url_match.group(1).strip() if url_match else “不明”, “email”: email_match.group(1).strip() if email_match else “不明”, “challenges”: challenges_match.group(1).strip() if challenges_match else “課題なし”, “draft”: draft_match.group(1).strip() if draft_match else “本文なし” }

(※LLMのプロンプトで指定した見出しと、このPythonコード内の検索キーワードが完全に一致している必要があります)


ステップ3:GAS(Google Apps Script)で受け皿を作る

次に、スプレッドシート側の設定です。

「拡張機能」>「Apps Script」を開き、以下のコードを貼り付けます。

JavaScript

function doPost(e) { try { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName(‘シート1’) || spreadsheet.getSheets()[0]; // Difyから送られてくる4つのデータを受け取る var url = e.parameter.url || “不明”; var email = e.parameter.email || “不明”; var challenges = e.parameter.challenges || “課題なし”; var draft = e.parameter.draft || “本文なし”; // スプレッドシートの列に合わせて書き込み sheet.appendRow([ new Date(), // A列: 日付 “”, // B列: 企業名(今回は空欄) url, // C列: URL email, // D列: 先方メアド challenges, // E列: 課題 draft // F列: メール本文 ]); return ContentService.createTextOutput(“success”); } catch (err) { return ContentService.createTextOutput(“error: ” + err.message); } }

💡 注意点:コードを保存したら、必ず「デプロイ」>「新しいデプロイ」で「ウェブアプリ」として公開し、発行されたURL(末尾が /exec のもの)をコピーしてください。


ステップ4:DifyのHTTPリクエストでスプシに送信

最後にDifyに戻り、HTTPリクエストノードを設定します。

ここでJSON形式を選ぶと文章の途切れエラーが起きやすいため、必ずフォームデータ形式を使用します。

  • メソッド: POST
  • URL: GASで発行したURL(末尾が /exec
  • Bodyタイプ: x-www-form-urlencoded
  • Key-Valueの設定:
    • url : コードノードの url
    • email : コードノードの email
    • challenges : コードノードの challenges
    • draft : コードノードの draft
    • ※値は必ず {x} ボタンから変数を選択してください。

運用時のよくある「つまずきポイント」

今回、実際にツールを構築する上でハマったポイントと解決策を共有します。

1. スプシに書き込まれた文章が途中で切れる!

【原因】 DifyからJSON形式でデータを送ると、文章内にダブルクォーテーション(”)や改行が含まれていた場合にデータが破損してしまいます。

【解決策】 HTTPリクエストのBodyタイプを x-www-form-urlencoded に変更し、GAS側も e.parameter で受け取るように修正することで完全に解決します。

2. Difyで「ステータスコード400」のエラーが出る

【原因】 GASのURLが間違っているか、Difyの変数設定が手打ちになっている可能性があります。

【解決策】 GASのURL末尾が /edit ではなく /exec になっているか確認。また、Difyの変数は手打ちせず、必ず {x} ボタンからプルダウンで選択してください。

3. スプシの行がズレて書き込まれてしまう

【原因】 appendRow という命令は「データが入っている一番下の行の、次の行」に書き込みます。まだDifyからデータが来ていない先の行(G列など)に、手動でメモなどを先書きしてしまうと、そこを基準にズレてしまいます。

【解決策】 手動での追記やステータス管理は、必ず「Difyが書き込みを完了した行」に対してのみ行うようにしてください。


まとめ

DifyとGASを組み合わせることで、手作業で行っていた営業リスト作成とメール起案の時間を劇的に削減できます。

「Tavilyの検索結果から欲しい部分だけをPythonで抽出し、フォームデータとしてGASに投げる」というこの構成は、Web制作だけでなく、あらゆるアウトバウンド営業に応用が利く強力なパターンです。

ぜひ、日々のビジネスの効率化に役立ててみてください!

↓ワークフローで営業リストを自動生成しているイメージ