Claude AI、競合分析、Supabase RAGを使用したSEOコンテンツジェネレーター

上級

これはContent Creation, Multimodal AI分野の自動化ワークフローで、40個のノードを含みます。主にIf, Code, Filter, HttpRequest, GoogleSheetsなどのノードを使用。 Claude AI、製品分析、Supabase RAGを使用してSEOコンテンツ生成

前提条件
  • ターゲットAPIの認証情報が必要な場合あり
  • Google Sheets API認証情報
  • Anthropic API Key
  • OpenAI API Key
  • Supabase URL と API Key
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "meta": {
    "instanceId": "393ca9e36a1f81b0f643c72792946a5fe5e49eb4864181ba4032e5a408278263"
  },
  "nodes": [
    {
      "id": "032fa5cd-ddba-4004-9c16-395ca9f8509b",
      "name": "フィルター1",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1280,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d0a801f4-942f-4f2b-b71f-f31f23066f28",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json['Keyword'] }}",
              "rightValue": ""
            },
            {
              "id": "6e0d041d-30cd-413d-913d-3c1775840277",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json['<h1>'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6d0d3e23-ce99-4151-acb7-9d78dca10961",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        -1088,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b5344169-b18b-482d-9d03-b02c170668b9",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json['Keyword'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4f7306be-5788-451b-9974-b3e509b7bfc9",
      "name": "Anthropic チャットモデル2",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        896,
        640
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514",
          "cachedResultName": "Claude Sonnet 4"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "id": "WXQf5QsxCs3AyxlW",
          "name": "Anthropic account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "6ac8f3a1-1eb9-448f-b962-9260fdfe6fc6",
      "name": "Supabase ベクトルストア2",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1056,
        640
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 5,
        "options": {
          "queryName": "=match_{{ $('Client Information').item.json['Supabase database'] }}_documents"
        },
        "toolName": "BaseDeDonnees",
        "tableName": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Client Information').item.json['Supabase database'] }}_documents"
        },
        "toolDescription": "=Here's a database with information about {{ $('Client Information').item.json['Client name'] }}, you can use it to improve the relevance in your writing."
      },
      "credentials": {
        "supabaseApi": {
          "id": "WXo0zqqBO5HTdEW5",
          "name": "Clients"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "430268c9-f9dc-41ff-b7aa-a51794efe0fc",
      "name": "OpenAI 埋め込み2",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1152,
        768
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "Wk5dyBYFy6HDwml2",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ebc3843c-55a9-426e-877a-a34b56b30e01",
      "name": "構造化出力パーサー2",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1392,
        640
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"meta_title\": \"Courtage Assurance : Services & Avantages d'un Courtier en 2023\",\n\t\"meta_description\": \"Découvrez comment optimiser votre compte de libre passage avec Revolution. Conseils d'experts pour maximiser votre capital retraite et faire les meilleurs choix. Consultez-nous !\",\n    \"h1\": \"Compte de libre passage : Guide complet pour gérer votre 2e pilier\"\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "0b01c8ed-fb64-4793-9ad5-23e8f2cbb042",
      "name": "Anthropic チャットモデル",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1760,
        640
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514",
          "cachedResultName": "Claude Sonnet 4"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "id": "WXQf5QsxCs3AyxlW",
          "name": "Anthropic account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3a3bff06-54d9-4e63-9b48-bcd35714a6ce",
      "name": "Supabase ベクトルストア",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1920,
        640
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 5,
        "options": {
          "queryName": "=match_{{ $('Client Information').item.json['Supabase database'] }}_documents"
        },
        "toolName": "BaseDeDonnees",
        "tableName": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Client Information').item.json['Supabase database'] }}_documents"
        },
        "toolDescription": "=Here's a database with information about {{ $('Client Information').item.json['Client name'] }}, you can use it to improve the relevance in your writing."
      },
      "credentials": {
        "supabaseApi": {
          "id": "WXo0zqqBO5HTdEW5",
          "name": "Clients"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "6956f1b1-a7f5-4350-b2f0-d4a65e7f2423",
      "name": "OpenAI 埋め込み",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2016,
        768
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "Wk5dyBYFy6HDwml2",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7670a1db-3d6e-4d42-842f-49de3d307bef",
      "name": "Titre 1",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        -64
      ],
      "parameters": {
        "jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n  // Expression régulière pour capturer les titres h1-h6\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n  \n  // Initialiser tous les niveaux avec \"pas de h{n}\"\n  const titlesByLevel = {\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: []\n  };\n  \n  let match;\n  \n  // Parcourir toutes les correspondances\n  while ((match = headingRegex.exec(markdownText)) !== null) {\n    const level = match[1].length; // Nombre de #\n    let text = match[2].trim();\n    \n    // Retirer les liens markdown : [texte](url) -> texte\n    text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n    \n    const levelTag = `h${level}`;\n    \n    titlesByLevel[levelTag].push(text);\n  }\n  \n  // Créer l'objet de résultat\n  const result = {};\n  \n  Object.keys(titlesByLevel).forEach(level => {\n    if (titlesByLevel[level].length === 0) {\n      result[level] = `${level} : pas de ${level}`;\n    } else {\n      result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n    }\n  });\n  \n  return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n  markdown = inputData.json.data.markdown;\n} else {\n  console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n  return {\n    json: {\n      h1: \"h1 : pas de h1\",\n      h2: \"h2 : pas de h2\",\n      h3: \"h3 : pas de h3\",\n      h4: \"h4 : pas de h4\",\n      h5: \"h5 : pas de h5\",\n      h6: \"h6 : pas de h6\"\n    }\n  };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n  json: titres\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "27649231-5440-4099-82c0-ad2d96092b85",
      "name": "Titre 2",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        160
      ],
      "parameters": {
        "jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n  // Expression régulière pour capturer les titres h1-h6\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n  \n  // Initialiser tous les niveaux avec \"pas de h{n}\"\n  const titlesByLevel = {\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: []\n  };\n  \n  let match;\n  \n  // Parcourir toutes les correspondances\n  while ((match = headingRegex.exec(markdownText)) !== null) {\n    const level = match[1].length; // Nombre de #\n    let text = match[2].trim();\n    \n    // Retirer les liens markdown : [texte](url) -> texte\n    text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n    \n    const levelTag = `h${level}`;\n    \n    titlesByLevel[levelTag].push(text);\n  }\n  \n  // Créer l'objet de résultat\n  const result = {};\n  \n  Object.keys(titlesByLevel).forEach(level => {\n    if (titlesByLevel[level].length === 0) {\n      result[level] = `${level} : pas de ${level}`;\n    } else {\n      result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n    }\n  });\n  \n  return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n  markdown = inputData.json.data.markdown;\n} else {\n  console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n  return {\n    json: {\n      h1: \"h1 : pas de h1\",\n      h2: \"h2 : pas de h2\",\n      h3: \"h3 : pas de h3\",\n      h4: \"h4 : pas de h4\",\n      h5: \"h5 : pas de h5\",\n      h6: \"h6 : pas de h6\"\n    }\n  };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n  json: titres\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "ce4ed824-ce7c-4d18-b1e7-c473e257e514",
      "name": "Titre 3",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        384
      ],
      "parameters": {
        "jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n  // Expression régulière pour capturer les titres h1-h6\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n  \n  // Initialiser tous les niveaux avec \"pas de h{n}\"\n  const titlesByLevel = {\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: []\n  };\n  \n  let match;\n  \n  // Parcourir toutes les correspondances\n  while ((match = headingRegex.exec(markdownText)) !== null) {\n    const level = match[1].length; // Nombre de #\n    let text = match[2].trim();\n    \n    // Retirer les liens markdown : [texte](url) -> texte\n    text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n    \n    const levelTag = `h${level}`;\n    \n    titlesByLevel[levelTag].push(text);\n  }\n  \n  // Créer l'objet de résultat\n  const result = {};\n  \n  Object.keys(titlesByLevel).forEach(level => {\n    if (titlesByLevel[level].length === 0) {\n      result[level] = `${level} : pas de ${level}`;\n    } else {\n      result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n    }\n  });\n  \n  return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n  markdown = inputData.json.data.markdown;\n} else {\n  console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n  return {\n    json: {\n      h1: \"h1 : pas de h1\",\n      h2: \"h2 : pas de h2\",\n      h3: \"h3 : pas de h3\",\n      h4: \"h4 : pas de h4\",\n      h5: \"h5 : pas de h5\",\n      h6: \"h6 : pas de h6\"\n    }\n  };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n  json: titres\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "743ed1ac-a884-43cb-ab5b-c461c901a70c",
      "name": "Titre 4",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        592
      ],
      "parameters": {
        "jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n  // Expression régulière pour capturer les titres h1-h6\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n  \n  // Initialiser tous les niveaux avec \"pas de h{n}\"\n  const titlesByLevel = {\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: []\n  };\n  \n  let match;\n  \n  // Parcourir toutes les correspondances\n  while ((match = headingRegex.exec(markdownText)) !== null) {\n    const level = match[1].length; // Nombre de #\n    let text = match[2].trim();\n    \n    // Retirer les liens markdown : [texte](url) -> texte\n    text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n    \n    const levelTag = `h${level}`;\n    \n    titlesByLevel[levelTag].push(text);\n  }\n  \n  // Créer l'objet de résultat\n  const result = {};\n  \n  Object.keys(titlesByLevel).forEach(level => {\n    if (titlesByLevel[level].length === 0) {\n      result[level] = `${level} : pas de ${level}`;\n    } else {\n      result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n    }\n  });\n  \n  return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n  markdown = inputData.json.data.markdown;\n} else {\n  console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n  return {\n    json: {\n      h1: \"h1 : pas de h1\",\n      h2: \"h2 : pas de h2\",\n      h3: \"h3 : pas de h3\",\n      h4: \"h4 : pas de h4\",\n      h5: \"h5 : pas de h5\",\n      h6: \"h6 : pas de h6\"\n    }\n  };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n  json: titres\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "0ad858fb-78d9-400e-8f08-4d46e1716000",
      "name": "Titre 5",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        784
      ],
      "parameters": {
        "jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n  // Expression régulière pour capturer les titres h1-h6\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n  \n  // Initialiser tous les niveaux avec \"pas de h{n}\"\n  const titlesByLevel = {\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: []\n  };\n  \n  let match;\n  \n  // Parcourir toutes les correspondances\n  while ((match = headingRegex.exec(markdownText)) !== null) {\n    const level = match[1].length; // Nombre de #\n    let text = match[2].trim();\n    \n    // Retirer les liens markdown : [texte](url) -> texte\n    text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n    \n    const levelTag = `h${level}`;\n    \n    titlesByLevel[levelTag].push(text);\n  }\n  \n  // Créer l'objet de résultat\n  const result = {};\n  \n  Object.keys(titlesByLevel).forEach(level => {\n    if (titlesByLevel[level].length === 0) {\n      result[level] = `${level} : pas de ${level}`;\n    } else {\n      result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n    }\n  });\n  \n  return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n  markdown = inputData.json.data.markdown;\n} else {\n  console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n  return {\n    json: {\n      h1: \"h1 : pas de h1\",\n      h2: \"h2 : pas de h2\",\n      h3: \"h3 : pas de h3\",\n      h4: \"h4 : pas de h4\",\n      h5: \"h5 : pas de h5\",\n      h6: \"h6 : pas de h6\"\n    }\n  };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n  json: titres\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "f7948f6b-a650-41c2-8c7d-2603e393cb73",
      "name": "コード",
      "type": "n8n-nodes-base.code",
      "position": [
        2464,
        432
      ],
      "parameters": {
        "jsCode": "// Code avec conservation de toutes les colonnes existantes\nconst items = [];\n\n// Récupérer les données de vos différents nodes\nconst loopItem = $('Loop Over Items').item.json;\nconst metaTagsOutput = $('Meta tag + h1').item.json.output;\nconst briefOutput = $json.output;\n\n// Créer l'objet avec toutes les colonnes et le mapping des nouvelles valeurs\nconst transformedItem = {\n  // Copier toutes les propriétés existantes\n  ...loopItem,\n  \n  // Écraser/ajouter les nouvelles valeurs\n  '<title>': metaTagsOutput.meta_title,\n  '<meta-desc>': metaTagsOutput.meta_description,\n  '<h1>': metaTagsOutput.h1,\n  'brief': briefOutput\n};\n\n// Retourner l'item transformé\nitems.push(transformedItem);\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "a4485f65-cb46-4282-b0f4-1cdb95277592",
      "name": "Apify",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -432,
        448
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/nFJndFXA5zjCTuudP/run-sync-get-dataset-items",
        "method": "POST",
        "options": {
          "timeout": 300000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "jsonBody": "={\n    \"countryCode\": \"fr\",\n    \"forceExactMatch\": false,\n    \"includeIcons\": false,\n    \"includeUnfilteredResults\": false,\n    \"languageCode\": \"fr\",\n    \"maxPagesPerQuery\": 1,\n    \"mobileResults\": false,\n    \"queries\": \"{{ $json['Keyword'] }}\",\n    \"resultsPerPage\": 10,\n    \"saveHtml\": false,\n    \"saveHtmlToKeyValueStore\": false\n}",
        "sendBody": true,
        "sendQuery": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "timeout",
              "value": "240"
            },
            {
              "name": "memory",
              "value": "512"
            },
            {
              "name": "maxItems",
              "value": "10"
            },
            {
              "name": "format",
              "value": "json"
            },
            {
              "name": "maxTotalChargeUsd",
              "value": "0.50"
            }
          ]
        },
        "nodeCredentialType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "jAy18eDHHP2ZoGrH",
          "name": "Apify"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2
    },
    {
      "id": "a5ef41de-4718-4902-adb9-cff82e1b3885",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2816,
        432
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Niv 0",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Niv 0",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Niv 1",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Niv 1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Niv 2",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Niv 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Niv 3",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Niv 3",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "mots clés",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "mots clés",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "vol",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "vol",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "KD%",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "KD%",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Type de page",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Type de page",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "<title>",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "<title>",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "<meta-desc>",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "<meta-desc>",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "<h1>",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "<h1>",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "brief",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "brief",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "mots clés secondaires",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "mots clés secondaires",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intentions de recherche",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "intentions de recherche",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nombre de mots",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "nombre de mots",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Premiere version",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Premiere version",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Thot",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Thot",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "col_11",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "col_11",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "col_13",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "col_13",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "col_15",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "col_15",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "mots clés"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "FR"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $('When chat message received').item.json.chatInput }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "wBRLUCktxqXE6DVJ",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "d953e577-f521-4162-8f41-28f6962e593f",
      "name": "Scrape 1",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "onError": "continueRegularOutput",
      "position": [
        64,
        -64
      ],
      "parameters": {
        "url": "={{ $('Apify').item.json.organicResults[0].url }}",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "headers": {},
            "includeTags": {
              "items": [
                {
                  "tag": "h1, h2, h3, h4"
                }
              ]
            }
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "id": "E34WDB80ik5VHjiI",
          "name": "Firecrawl account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "4fb36ed5-04fd-415f-b288-b1f6c6681b67",
      "name": "Scrape 2",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "onError": "continueRegularOutput",
      "position": [
        64,
        160
      ],
      "parameters": {
        "url": "={{ $('Apify').item.json.organicResults[1].url }}",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "headers": {},
            "includeTags": {
              "items": [
                {
                  "tag": "h1, h2, h3, h4"
                }
              ]
            }
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "id": "E34WDB80ik5VHjiI",
          "name": "Firecrawl account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "9fe7da48-4ce4-4dd9-b8db-719c91a4bd8e",
      "name": "Scrape 5",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "onError": "continueRegularOutput",
      "position": [
        64,
        784
      ],
      "parameters": {
        "url": "={{ $('Apify').item.json.organicResults[4].url }}",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "headers": {},
            "includeTags": {
              "items": [
                {
                  "tag": "h1, h2, h3, h4"
                }
              ]
            }
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "id": "E34WDB80ik5VHjiI",
          "name": "Firecrawl account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "a5a1bbe4-8e4a-43c3-a79d-17ccaf4a62f8",
      "name": "Scrape 4",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "onError": "continueRegularOutput",
      "position": [
        64,
        592
      ],
      "parameters": {
        "url": "={{ $('Apify').item.json.organicResults[3].url }}",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "headers": {},
            "includeTags": {
              "items": [
                {
                  "tag": "h1, h2, h3, h4"
                }
              ]
            }
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "id": "E34WDB80ik5VHjiI",
          "name": "Firecrawl account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "0212ab73-03c1-4469-a577-7929052ed3f4",
      "name": "Scrape 3",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "onError": "continueRegularOutput",
      "position": [
        64,
        384
      ],
      "parameters": {
        "url": "={{ $('Apify').item.json.organicResults[2].url }}",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "headers": {},
            "includeTags": {
              "items": [
                {
                  "tag": "h1, h2, h3, h4"
                }
              ]
            }
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "id": "E34WDB80ik5VHjiI",
          "name": "Firecrawl account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "a428387e-f48a-4441-85ab-5633df895e02",
      "name": "Client Information",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1728,
        448
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Client information"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $('When chat message received').item.json.chatInput }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "wBRLUCktxqXE6DVJ",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "6980bc20-deff-4b86-aff9-aa6532e5af96",
      "name": "SEO information",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1504,
        448
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "SEO"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $('When chat message received').item.json.chatInput }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "wBRLUCktxqXE6DVJ",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "56cd7226-72cf-4a1f-9175-646c2d701851",
      "name": "チャットメッセージ受信時",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -2000,
        448
      ],
      "webhookId": "88a8efaa-7712-49bd-ba94-4bb130719dbe",
      "parameters": {
        "mode": "webhook",
        "public": true,
        "options": {
          "responseMode": "responseNode"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "81fdb3c4-5fe0-42aa-8ec8-f74438331ef8",
      "name": "ループ処理",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -848,
        432
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
      "name": "Meta tag + h1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 5,
      "position": [
        1024,
        432
      ],
      "parameters": {
        "text": "=[Main keyword]: {{ $('Loop Over Items').item.json['Keyword'] }}\n\n[Page]: {{ $('SEO information').item.json.Page }}\n\n[Site]: {{ $('Client Information').item.json['Client name'] }} ({{ $('Client Information').item.json['Client information'] }})\n\n[Description]:{{ $('Loop Over Items').item.json.Description }}\n\n[Competitor info]:\n\nCompetitor 1:\n{{ $('Apify').item?.json?.organicResults?.[0]?.url || '' }}\n\nMeta title: {{ $('Apify').item?.json?.organicResults?.[0]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[0]?.description || '' }}\n{{ $('Titre 1').item.json.h1 }}\n\nCompetitor 2:\n{{ $('Apify').item?.json?.organicResults?.[1]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[1]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[1]?.description || '' }}\n{{ $('Titre 2').item.json.h1 }}\n\nCompetitor 3:\n{{ $('Apify').item?.json?.organicResults?.[2]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[2]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[2]?.description || '' }}\n{{ $('Titre 3').item.json.h1 }}\n\nCompetitor 4:\n{{ $('Apify').item?.json?.organicResults?.[3]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[3]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[3]?.description || '' }}\n{{ $('Titre 4').item.json.h1 }}\n\nCompetitor 5:\n{{ $('Apify').item?.json?.organicResults?.[4]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[4]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[4]?.description || '' }}\n{{ $('Titre 5').item.json.h1 }}\n\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
        "options": {
          "systemMessage": "# Rules\n\nAs an SEO expert, I need you to analyze the [Main keyword] for the page [Page], for the site [Site]. You also have a short description [Description] of what the page is about. You must also analyze the competitor info [Competitor info] (url, meta title, meta description, h1)\n\n# Deliverables\n\nto provide the following elements:\n\nMETA TITLE (65 characters maximum):\nCreate a catchy and optimized meta title that includes the main keyword at the beginning of the title if possible, while remaining natural and click-inducing. The format should be in sentence case. Expected structure for the title: Main keyword, cta (do not include the [Client name] in the title)\n\nMETA DESCRIPTION (165 characters maximum):\nWrite a persuasive meta description that clearly summarizes the page's added value, includes the main keyword and features an effective call-to-action.\n\nH1 (70 characters maximum):\nPropose an impactful H1 that integrates the main keyword while being attractive to the user. The format should be in sentence case.\n\nDo not write an introduction or conclusion to your response.\n\n# Tools\n\nYou have access to a RAG database with information about the client [Client name] to help you write the requested information as effectively as possible."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 1.9,
      "waitBetweenTries": 5000
    },
    {
      "id": "08ed03ff-61de-474e-bfc5-23d0b65adb08",
      "name": "付箋",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2048,
        352
      ],
      "parameters": {
        "color": 2,
        "width": 1360,
        "height": 256,
        "content": "# Phase 1: Data Input and Configuration"
      },
      "typeVersion": 1
    },
    {
      "id": "4bc76db0-11e9-415b-b43e-d8e7cf8d9bf1",
      "name": "付箋1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        -128
      ],
      "parameters": {
        "color": 3,
        "width": 1248,
        "height": 1072,
        "content": "# Phase 2: Competitor Research and Analysis\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1effb4a8-4543-46b3-9792-7d496c749015",
      "name": "付箋2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        352
      ],
      "parameters": {
        "color": 5,
        "width": 656,
        "height": 560,
        "content": "# Phase 3: Meta Tags and H1 Generation"
      },
      "typeVersion": 1
    },
    {
      "id": "feada2a4-5e65-482a-aacc-4cd5b1361c80",
      "name": "付箋4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2416,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 256,
        "content": "# Phase 5: Data Integration and Sheet Updates"
      },
      "typeVersion": 1
    },
    {
      "id": "89e6932d-e4a1-494c-8fac-c763ce46513a",
      "name": "付箋5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2704,
        128
      ],
      "parameters": {
        "color": 4,
        "width": 544,
        "height": 944,
        "content": "# Phase 0: Setup and Configuration\n\n## What you do:\n\nCopy the template spreadsheet from this link: https://docs.google.com/spreadsheets/d/1cRlqsueCTgfMjO7AzwBsAOzTCPBrGpHSzRg05fLDnWc\n\n### Fill in the Client Information sheet with your business details:\n\nClient name: Your company or client's name\nClient information: Brief description of the business and what it does\nURL: The website address\nSupabase database: Database name (prevents AI from making up information)\nTone of voice: How you want the content to sound (professional, friendly, etc.)\nRestrictive instructions: Topics or approaches to avoid\n\n\n### Complete the SEO sheet with your page details:\n\nPage: What page you're optimizing (e.g., \"Homepage\", \"About Us\")\nKeyword: The main search term you want to rank for\nAwareness level: How familiar visitors are with your business\nPage type: Category of page (homepage, product page, blog article, etc.)\n\n\n\n## What the system does:\n\nStores your configuration for use throughout the workflow\nValidates your data to ensure all required fields are completed\nPrepares the automation to process your keywords and generate SEO content\n\n## Result:\n\n✅ Personalized workflow configured with your business information\n✅ Target keywords and pages ready for optimization\n✅ AI system trained on your specific requirements and restrictions\n✅ Foundation set for automated SEO content generation"
      },
      "typeVersion": 1
    },
    {
      "id": "f24fbe21-4f20-4349-837f-fda54fc844fb",
      "name": "付箋6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2048,
        656
      ],
      "parameters": {
        "color": 2,
        "width": 1360,
        "height": 464,
        "content": "### What you do:\n\nProvide a Google Sheets URL via the chat trigger to initialize the workflow\nConfigure the Client Information sheet with your client details (name, description, website URL, Supabase database name, tone of voice, and content restrictions)\nSet up the SEO sheet with page information (page name, target keywords, user awareness level, and page type)\n\n### What the system does:\n\nReceives the chat input and extracts the Google Sheets document ID\nReads the Client Information sheet to gather all client-specific configuration data\nReads the SEO sheet to retrieve keyword and page targeting information\nFilters the data to process only rows with valid keywords and empty H1 fields\nValidates keyword existence using conditional logic\nInitiates batch processing to handle multiple keywords sequentially\n\n### Result:\n\n✅ Workflow configured with client-specific parameters\n✅ Valid keywords identified and queued for processing\n✅ Data properly structured for automated analysis\n✅ Batch processing system activated for efficient handling\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9a08f7ac-681f-40a2-9216-0f31628b98e4",
      "name": "付箋7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        992
      ],
      "parameters": {
        "color": 3,
        "width": 1248,
        "height": 368,
        "content": "### What the system does:\n\nSearches Google using Apify API to retrieve top 10 organic results for each target keyword\nScrapes competitor websites using Firecrawl to extract content from the first 5 search results\nAnalyzes page structure by extracting H1-H6 headings from each competitor page using JavaScript\nProcesses markdown content to identify heading hierarchies and content organization\nHandles scraping errors gracefully by continuing execution even if some sites fail\nCompiles competitor intelligence including URLs, meta titles, meta descriptions, and heading structures\n\n### Result:\n\n✅ Comprehensive competitor analysis for each keyword\n✅ Detailed heading structure mapping from top 5 competitors\n✅ Meta tag information collected for benchmarking\n✅ Content organization patterns identified\n✅ Robust error handling ensures workflow completion\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e2c12fe5-a19f-461b-8293-e9947de3a487",
      "name": "付箋8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        960
      ],
      "parameters": {
        "color": 5,
        "width": 656,
        "height": 384,
        "content": "### What the system does:\n\nAnalyzes keyword context using Claude AI with competitor intelligence and client information\nAccesses client database via Supabase vector store for relevant company-specific information\nGenerates optimized meta elements including title (65 chars max), description (165 chars max), and H1 (70 chars max)\nApplies SEO best practices by positioning keywords naturally while maintaining readability\nUses structured output parsing to ensure consistent JSON formatting\nIncorporates RAG database to personalize content with client-specific details\n\n### Result:\n\n✅ SEO-optimized meta title with target keyword placement\n✅ Compelling meta description with effective call-to-action\n✅ User-focused H1 that balances SEO and engagement\n✅ Content personalized using client database information\n✅ Character limits respected for optimal search display\n"
      },
      "typeVersion": 1
    },
    {
      "id": "07dbbd72-4d44-44e0-ad8e-8f3e0ef5b033",
      "name": "付箋3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        352
      ],
      "parameters": {
        "color": 6,
        "width": 656,
        "height": 560,
        "content": "# Phase 4: Content Brief Creation"
      },
      "typeVersion": 1
    },
    {
      "id": "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee",
      "name": "Content brief",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 5,
      "position": [
        1872,
        432
      ],
      "parameters": {
        "text": "=[Site]:  {{ $('Client Information').item.json['Client name'] }}({{ $('Client Information').item.json['Client information'] }})\n[Main keyword]: {{ $('Loop Over Items').item.json.Keyword }}\n[h1]: {{ $('Meta tag + h1').item.json.output.h1 }}\n[Description]: {{ $('Loop Over Items').item.json.Description }}\n[Awareness]: {{ $('Loop Over Items').item.json['Awareness level'] }}\n[Competitor info]:\nCompetitor 1:\n{{ $('Apify').item.json.organicResults[0].url }}\n{{ $('Titre 1').item.json.h1 }}\n{{ $('Titre 1').item.json.h2 }}\n{{ $('Titre 1').item.json.h3 }}\n{{ $('Titre 1').item.json.h4 }}\n{{ $('Titre 1').item.json.h5 }}\n{{ $('Titre 1').item.json.h6 }}\nCompetitor 2:\n{{ $('Apify').item.json.organicResults[1].url }}\n{{ $('Titre 2').item.json.h1 }}\n{{ $('Titre 2').item.json.h2 }}\n{{ $('Titre 2').item.json.h3 }}\n{{ $('Titre 2').item.json.h4 }}\n{{ $('Titre 2').item.json.h5 }}\n{{ $('Titre 2').item.json.h6 }}\nCompetitor 3:\n{{ $('Apify').item.json.organicResults[2].url }}\n{{ $('Titre 3').item.json.h1 }}\n{{ $('Titre 3').item.json.h2 }}\n{{ $('Titre 3').item.json.h3 }}\n{{ $('Titre 3').item.json.h4 }}\n{{ $('Titre 3').item.json.h5 }}\n{{ $('Titre 3').item.json.h6 }}\nCompetitor 4:\n{{ $('Apify').item.json.organicResults[3].url }}\n{{ $('Titre 4').item.json.h1 }}\n{{ $('Titre 4').item.json.h2 }}\n{{ $('Titre 4').item.json.h3 }}\n{{ $('Titre 4').item.json.h4 }}\n{{ $('Titre 4').item.json.h5 }}\n{{ $('Titre 4').item.json.h6 }}\nCompetitor 5:\n{{ $('Apify').item.json.organicResults[4].url }}\n{{ $('Titre 5').item.json.h1 }}\n{{ $('Titre 5').item.json.h2 }}\n{{ $('Titre 5').item.json.h3 }}\n{{ $('Titre 5').item.json.h4 }}\n{{ $('Titre 5').item.json.h5 }}\n{{ $('Titre 5').item.json.h6 }}\n[Page type]: {{ $('Loop Over Items').item.json['Type de page'] ? $('Loop Over Items').item.json['Type de page'] : '' }}\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
        "options": {
          "systemMessage": "# Rules\n\nI want to create an SEO content brief for a web page for the site [Site]. The main keyword I'm targeting is [Main keyword] and the h1 is the following [h1]. Here's a short description of the page [Description] And here's the awareness level that corresponds to the page [Awareness] Here's additional information about competitors positioning on this keyword, use this as inspiration to respond to the request [Competitor info]\n\n# Deliverables\n\nCan you provide a complete content brief including:\n\nPage type: [Page type]\nDetailed analysis of the search intent behind the main keyword (informational, transactional, navigational as percentages for each intent)\nStrategy to highlight the company in this content based on the main keyword\nRich media suggestions to integrate (images, videos, infographics, tables, etc.)\nDetailed MECE (Mutually Exclusive, Collectively Exhaustive) page structure with:\n\nthe h1 [h1]\nIntroduction\nH2 sections with key points for each section\nH3 subsections if necessary\n\n\nRecommended level of detail for writing on a scale of 1 to 10\n\nPlease ensure that the proposed structure is coherent, exhaustive, without redundancies, and optimized for SEO while remaining relevant for users.\nDo not write an introduction or conclusion to your response.\n\n# Tools\n\nYou have access to a RAG database with information about [Client name] to help you write the requested information as effectively as possible."
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 1.9,
      "waitBetweenTries": 5000
    },
    {
      "id": "a9554edf-3b91-4a27-a9b8-bdad45920583",
      "name": "付箋9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        960
      ],
      "parameters": {
        "color": 6,
        "width": 656,
        "height": 400,
        "content": "### What the system does:\n\nAnalyzes search intent behind the target keyword (informational, transactional, navigational percentages)\nDevelops content strategy based on competitor analysis and client positioning\nCreates MECE page structure with detailed H2 sections and H3 subsections where needed\nSuggests rich media elements (images, videos, infographics, tables) for enhanced engagement\nProvides writing recommendations including detail level scoring (1-10 scale)\nIntegrates client database information to ensure brand-consistent messaging\nDelivers comprehensive brief covering all aspects needed for content creation\n\n### Result:\n\n✅ Complete content strategy with search intent analysis\n✅ Detailed page structure optimized for SEO and user experience\n✅ Rich media recommendations for improved engagement\n✅ Brand-consistent messaging aligned with client database\n✅ Writing guidelines with specific detail level recommendations\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7141cb57-f915-47bf-83fb-1c6283bddcac",
      "name": "付箋10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2416,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 416,
        "content": "### What the system does:\n\nCombines all generated content (meta tags, H1, and content brief) into a unified data structure\nPreserves existing data while updating only the new SEO elements in the spreadsheet\nMaps output fields to corresponding Google Sheets columns (title, meta-desc, h1, brief)\nUpdates the original sheet using Google Sheets API with the generated content\nTriggers loop continuation to process the next keyword in the batch\nMaintains data integrity throughout the update process\n\n### Result:\n\n✅ Google Sheets automatically updated with generated SEO content\n✅ Original data preserved with new SEO elements added\n✅ Batch processing continues until all keywords are processed\n✅ Complete SEO content package ready for implementation\n✅ Workflow loops back for additional keywords in the queue"
      },
      "typeVersion": 1
    },
    {
      "id": "4af149e0-c216-4075-9aab-9f6e27f6ddf5",
      "name": "付箋13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1744,
        -176
      ],
      "parameters": {
        "width": 816,
        "height": 336,
        "content": "## Need more advanced automation solutions? Contact us for custom enterprise workflows!\n\n# Growth-AI.fr\n\n## https://www.linkedin.com/in/allanvaccarizi/\n## https://www.linkedin.com/in/hugo-marinier-%F0%9F%A7%B2-6537b633/"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {
    "When chat message received": [
      {
        "action": "sendMessage",
        "chatInput": "t",
        "sessionId": "bae7e54a70ab4df5a59a2f8841897496"
      }
    ]
  },
  "connections": {
    "6d0d3e23-ce99-4151-acb7-9d78dca10961": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "a5ef41de-4718-4902-adb9-cff82e1b3885",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a4485f65-cb46-4282-b0f4-1cdb95277592": {
      "main": [
        [
          {
            "node": "d953e577-f521-4162-8f41-28f6962e593f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter1": {
      "main": [
        [
          {
            "node": "6d0d3e23-ce99-4151-acb7-9d78dca10961",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7670a1db-3d6e-4d42-842f-49de3d307bef": {
      "main": [
        [
          {
            "node": "4fb36ed5-04fd-415f-b288-b1f6c6681b67",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "27649231-5440-4099-82c0-ad2d96092b85": {
      "main": [
        [
          {
            "node": "0212ab73-03c1-4469-a577-7929052ed3f4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ce4ed824-ce7c-4d18-b1e7-c473e257e514": {
      "main": [
        [
          {
            "node": "a5a1bbe4-8e4a-43c3-a79d-17ccaf4a62f8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "743ed1ac-a884-43cb-ab5b-c461c901a70c": {
      "main": [
        [
          {
            "node": "9fe7da48-4ce4-4dd9-b8db-719c91a4bd8e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0ad858fb-78d9-400e-8f08-4d46e1716000": {
      "main": [
        [
          {
            "node": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d953e577-f521-4162-8f41-28f6962e593f": {
      "main": [
        [
          {
            "node": "7670a1db-3d6e-4d42-842f-49de3d307bef",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4fb36ed5-04fd-415f-b288-b1f6c6681b67": {
      "main": [
        [
          {
            "node": "27649231-5440-4099-82c0-ad2d96092b85",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0212ab73-03c1-4469-a577-7929052ed3f4": {
      "main": [
        [
          {
            "node": "ce4ed824-ce7c-4d18-b1e7-c473e257e514",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a5a1bbe4-8e4a-43c3-a79d-17ccaf4a62f8": {
      "main": [
        [
          {
            "node": "743ed1ac-a884-43cb-ab5b-c461c901a70c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9fe7da48-4ce4-4dd9-b8db-719c91a4bd8e": {
      "main": [
        [
          {
            "node": "0ad858fb-78d9-400e-8f08-4d46e1716000",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "26c815ed-adc8-4ecd-80ff-ff51d92fdda1": {
      "main": [
        [
          {
            "node": "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "a4485f65-cb46-4282-b0f4-1cdb95277592",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6980bc20-deff-4b86-aff9-aa6532e5af96": {
      "main": [
        [
          {
            "node": "Filter1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "a428387e-f48a-4441-85ab-5633df895e02": {
      "main": [
        [
          {
            "node": "6980bc20-deff-4b86-aff9-aa6532e5af96",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI2": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store2",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "a5ef41de-4718-4902-adb9-cff82e1b3885": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store": {
      "ai_tool": [
        [
          {
            "node": "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store2": {
      "ai_tool": [
        [
          {
            "node": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser2": {
      "ai_outputParser": [
        [
          {
            "node": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "a428387e-f48a-4441-85ab-5633df895e02",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

上級 - コンテンツ作成, マルチモーダルAI

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

ワークフロー情報
難易度
上級
ノード数40
カテゴリー2
ノードタイプ14
難易度説明

上級者向け、16ノード以上の複雑なワークフロー

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34