0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者ハマりポイント】DifyからGASへのPOSTが通らない理由と対処法_ 文字列化されたJSON配列の扱い

Last updated at Posted at 2025-05-13

以下は、あなたの内容をマークダウン形式に整えたものです。


Dify × GASで自動化!LLMで生成したペルソナをスプレッドシートに出力する方法

はじめに

「Difyのワークフローで、LLMで生成したデータをうまくGASにPSOTできずにハマっている…

この記事では、Difyのワークフローで生成された文字列化されたJSON配列をGoogle Apps Script(GAS)にPOSTする処理について、LLM(今回はGemini)が分析したペルソナ情報を自動でGoogle スプレッドシートに書き出す方法を事例に、初心者の方にも分かりやすく解説します!

今回の事例では以下のような情報をもとに、Geminiがペルソナを分析します。

  • 収集したサイトの概要
  • 想定される訪問目的

そして分析結果をスプレッドシートに整理します。

「なんだか難しそう…」と感じた方も大丈夫!
各ステップを丁寧に解説していきますので、ぜひ最後まで読んで、業務効率化の一歩を踏み出しましょう!


どんなワークフロー?全体像をざっくり解説

今回のワークフローは、以下のような流れでLLMの分析結果をスプレッドシートに書き出します。

各ステップの概要

  1. 初期データ取得ノード
    分析の元となるサイト概要と訪問目的のデータを取得。

  2. Codeノード(LLM入力整形)
    取得したデータをLLMが分析しやすい形式に整形。

  3. LLMノード(ペルソナ分析)
    Geminiが3つのペルソナ情報を分析。

  4. Codeノード(LLM出力検証・整形)
    JSON形式で出力されたデータを検証・整形。

  5. HTTPリクエストノード
    整形済みのデータをGASのWebアプリにPOST。

  6. Google Apps Script(GAS)
    POSTされたデータを受け取り、スプレッドシートに書き込む。

今回は、ステップ2〜ステップ6を詳しく解説します!


前提:Difyで生成されるデータの構造

Difyのワークフローを通じて、以下のような形式をLLMで生成したと仮定します。

{
  "result": "[{\"siteSummary\":\"サイトの概要1\",\"visitPurpose\":\"訪問目的1\"}, {\"siteSummary\":\"サイトの概要2\",\"visitPurpose\":\"訪問目的2\"}]"
}

このように、resultキーに、サイト概要と訪問目的のペアが配列形式で格納された文字列が含まれています。


各ステップの詳細と設定方法

ステップ2:Codeノード(LLM入力整形)

  • ノードタイプ:Code
  • 入力変数initialData(初期データ取得ノードの出力)
  • 出力変数llmPromptText

JavaScriptコード

function main({ initialData }) {
  if (typeof initialData !== 'object' || initialData === null || !initialData.hasOwnProperty('result')) {
    return { llmPromptText: "", error: "初期データの形式が不正です。" };
  }
  let jsonString = initialData.result;
  if (typeof jsonString !== 'string' || jsonString.trim() === '') {
    return { llmPromptText: "", error: "'result' の値が空の文字列です。" };
  }
  let dataArray;
  try {
    dataArray = JSON.parse(jsonString);
  } catch (error) {
    return { llmPromptText: "", error: "'result' のJSONパースに失敗しました: " + error.message };
  }
  if (!Array.isArray(dataArray)) {
    return { llmPromptText: "", error: "'result' の値が配列ではありません。" };
  }

  let formattedText = "以下のサイト概要と訪問目的のリストを分析し..."; // 省略(全文は元のコード参照)

  return { llmPromptText: formattedText };
}

出力形式を純粋なJSON配列に限定するように明確に指示している点が重要です。


ステップ3:LLMノード(ペルソナ分析)

  • ノードタイプ:LLM
  • AIモデル:Gemini(または任意のLLM)
  • プロンプト{{llmPromptText}}

LLM設定で「出力形式:JSON」を指定できる場合は、必ず設定しておきましょう。


ステップ4:Codeノード(LLM出力検証・整形)

  • ノードタイプ:Code
  • 入力変数llmOutputString(LLMノードの出力)
  • 出力変数finalPersonaJsonString

JavaScriptコード

function main({ llmOutputString }) {
  if (typeof llmOutputString !== 'string' || llmOutputString.trim() === '') {
    return { personaJsonString: "", error: "LLMの出力が空です。" };
  }

  let jsonString = llmOutputString;

  let dataArray;
  try {
    dataArray = JSON.parse(jsonString);
  } catch (error) {
    return { personaJsonString: "", error: "LLMの出力のJSONパースに失敗しました: " + error.message };
  }

  if (!Array.isArray(dataArray) || dataArray.length < 3) {
    return { personaJsonString: "", error: "LLMの出力が3件未満の配列です。" };
  }

  const requiredKeys = ["searchIntent", "details", "personaName", "age", "gender", "job", "companyCategory", "position", "challengesToSolve", "needsToSatisfy", "marketingFunnel", "nextExpectedKeywords"];
  const firstItem = dataArray[0];
  const hasRequiredKeys = requiredKeys.every(key => Object.prototype.hasOwnProperty.call(firstItem, key));
  if (!hasRequiredKeys) {
    return { personaJsonString: "", error: "LLM output objects are missing required keys." };
  }

  const finalJsonString = JSON.stringify(dataArray);

  return { personaJsonString: finalJsonString };
}

ステップ5:HTTPリクエストノード

  • ノードタイプ:HTTPリクエスト
  • メソッド:POST
  • URL:GASのWebアプリURL
  • ボディタイプ:JSON
  • ボディ
{
  "method": "createPersonaSheet",
  "spreadsheetId": "YOUR_SPREADSHEET_ID",
  "personaData": {{Codeノード名_LLM出力検証.finalPersonaJsonString}}
}

spreadsheetIdは書き込み先のスプレッドシートIDに置き換えてください。
personaDataの値はダブルクォート不要です。


ステップ6:Google Apps Script(GAS)

  1. スプレッドシートを開き、「ツール」>「スクリプトエディタ」
  2. 以下のコードを貼り付けて保存(例:writePersonaToSheet
  3. 「デプロイ」>「新しいデプロイ」>「ウェブアプリ」を選択

GASコード

function doPost(e) {
  let requestData;
  try {
    requestData = JSON.parse(e.postData.contents);
  } catch (error) {
    return ContentService.createTextOutput(JSON.stringify({ status: "error", message: "JSONパース失敗: " + error.message })).setMimeType(ContentService.MimeType.JSON);
  }

  const method = requestData.method;
  const spreadsheetId = requestData.spreadsheetId;
  const personaDataString = requestData.personaData;

  let response;
  switch (method) {
    case "createPersonaSheet":
      response = createPersonaSheet(spreadsheetId, personaDataString);
      break;
    default:
      response = { status: "error", message: "不明なメソッド: " + method };
  }

  return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

function createPersonaSheet(spreadsheetId, personaDataString) {
  try {
    const personaData = JSON.parse(personaDataString);
    const ss = SpreadsheetApp.openById(spreadsheetId);
    const sheetName = "ペルソナ分析結果";
    let sheet = ss.getSheetByName(sheetName) || ss.insertSheet(sheetName);
    
    sheet.clearContents();
    sheet.appendRow(["検索意図", "詳細", "ペルソナ名", "年齢", "性別", "職業", "企業のカテゴリー", "役職", "課題", "ニーズ", "ファネル", "想定キーワード"]);

    personaData.forEach(p => {
      sheet.appendRow([
        p.searchIntent, p.details, p.personaName, p.age, p.gender,
        p.job, p.companyCategory, p.position, p.challengesToSolve,
        p.needsToSatisfy, p.marketingFunnel, p.nextExpectedKeywords
      ]);
    });

    return { success: true, message: "スプレッドシートに書き込みました。", spreadsheetUrl: ss.getUrl() };
  } catch (error) {
    return { status: "error", message: error.message };
  }
}

Difyワークフローの構成要素まとめ

ステップ ノードタイプ 説明
初期データ 初期データ取得ノード サイト概要・訪問目的を含むJSON出力
ステップ2 Code JSONを整形してLLM用プロンプト作成
ステップ3 LLM Geminiでペルソナ分析
ステップ4 Code LLM出力のJSON整形・検証
ステップ5 HTTPリクエスト GASにPOST送信
ステップ6 GAS スプレッドシートに書き込み

おわりに

DifyとGASを連携させれば、面倒な転記作業を自動化し、業務の効率化を大きく推進できます。

ぜひこのワークフローを試してみてください!質問があれば気軽にどうぞ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?