{
  "name": "rag_faq_extractor",
  "nodes": [
    {
      "parameters": {},
      "id": "b7e8c306-95d7-493a-9594-0b0549e93eeb",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1440,
        80
      ]
    },
    {
      "parameters": {
        "model": "mistral-large-latest",
        "options": {}
      },
      "id": "656b9cbe-b346-479f-8a27-dde776a95391",
      "name": "Mistral Chat Model 1",
      "type": "@n8n/n8n-nodes-langchain.lmChatMistralCloud",
      "typeVersion": 1,
      "position": [
        -1008,
        272
      ],
      "credentials": {
        "mistralCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "mistral-large-latest",
        "options": {}
      },
      "id": "7361d2aa-9ee4-430a-89c1-9cbfef84d0d6",
      "name": "Mistral Chat Model 2",
      "type": "@n8n/n8n-nodes-langchain.lmChatMistralCloud",
      "typeVersion": 1,
      "position": [
        -272,
        288
      ],
      "credentials": {
        "mistralCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "mistral-large-latest",
        "options": {}
      },
      "id": "e1dc4ace-daa6-48a1-ab51-2ee4aa65e6f5",
      "name": "Mistral Chat Model 3",
      "type": "@n8n/n8n-nodes-langchain.lmChatMistralCloud",
      "typeVersion": 1,
      "position": [
        608,
        -48
      ],
      "credentials": {
        "mistralCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "inputDataFieldName": "json_output",
        "name": "faq.json",
        "driveId": {
          "__rl": true,
          "value": "My Drive",
          "mode": "list",
          "cachedResultName": "My Drive",
          "cachedResultUrl": "https://drive.google.com/drive/my-drive"
        },
        "folderId": {
          "__rl": true,
          "value": "root",
          "mode": "list",
          "cachedResultName": "/ (Root folder)",
          "cachedResultUrl": "https://drive.google.com/drive"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1808,
        -240
      ],
      "id": "2eeeb088-b51f-4ffa-ac9e-4e0d457f0ed4",
      "name": "Upload file",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "https://r.jina.ai/https://faq.tagheuer.com/?l=fr&c=Products:All_TAG_Heuer_Connected",
        "options": {}
      },
      "id": "38daefdb-59e1-4276-83c9-f778af33a18f",
      "name": "Get FAQ first page",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1216,
        80
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Analyse ce contenu markdown d'une page FAQ et extrait UNIQUEMENT les URLs des sous-cat\u00e9gories de la section Connected et ajoute aussi l'url : https://faq.tagheuer.com/?l=fr&c=Products:All_TAG_Heuer_Connected.\n\nContenu:\n{{ $json.data }}\n\nRetourne un JSON array avec les URLs compl\u00e8tes des sous-cat\u00e9gories. Format attendu:\n{\n  \"subcategories\": [\n    \"https://faq.tagheuer.com/?l=fr&c=Products:Connected:Subcategory1\",\n    \"https://faq.tagheuer.com/?l=fr&c=Products:Connected:Subcategory2\"\n  ]\n}\n\nRetourne UNIQUEMENT le JSON, rien d'autre."
      },
      "id": "9b7ebca8-e46e-4dd0-89c5-b718e3b83d21",
      "name": "Extract categories",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.4,
      "position": [
        -1008,
        80
      ]
    },
    {
      "parameters": {
        "jsCode": "// R\u00e9cup\u00e9rer la r\u00e9ponse du LLM\nconst input = $input.first().json;\nlet response = input.output || input.text || input.response || JSON.stringify(input);\n\nconsole.log('R\u00e9ponse brute du LLM:', response);\n\nlet parsed;\n\ntry {\n  // Si la r\u00e9ponse est d\u00e9j\u00e0 un objet\n  if (typeof response === 'object') {\n    parsed = response;\n  } else {\n    // Nettoyer la r\u00e9ponse (enlever markdown, backticks, etc.)\n    response = response.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n    \n    // Extraire le JSON de la r\u00e9ponse\n    const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n    if (jsonMatch) {\n      parsed = JSON.parse(jsonMatch[0]);\n    } else {\n      parsed = JSON.parse(response);\n    }\n  }\n} catch (e) {\n  console.error('Erreur de parsing:', e.message);\n  console.error('R\u00e9ponse qui a caus\u00e9 l\\'erreur:', response);\n  return [{ error: 'Parsing failed', rawResponse: response }];\n}\n\nconsole.log('JSON pars\u00e9:', parsed);\n\nconst urls = parsed.subcategories || [];\n\nif (urls.length === 0) {\n  console.warn('Aucune sous-cat\u00e9gorie trouv\u00e9e');\n  return [{ warning: 'No subcategories found', parsed: parsed }];\n}\n\nreturn urls.map(url => ({ url: url }));"
      },
      "id": "f86956ae-a0bc-40dc-860f-908107b0034a",
      "name": "Parser categories",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -688,
        80
      ]
    },
    {
      "parameters": {
        "url": "=https://r.jina.ai/{{ $json.url }}",
        "options": {}
      },
      "id": "884ea90d-9e69-42c2-85e8-89c805977aa2",
      "name": "Get questions / answers url by category",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -464,
        80
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Analyse ce contenu markdown d'une page FAQ et extrait TOUTES les questions avec leurs liens vers les r\u00e9ponses.\n\nContenu:\n{{ $json.data }}\n\nRetourne un JSON array avec les questions et URLs. Format attendu:\n{\n  \"questions\": [\n    {\n      \"question\": \"Texte de la question\",\n      \"url\": \"https://faq.tagheuer.com/...\"\n    }\n  ]\n}\n\nRetourne UNIQUEMENT le JSON, rien d'autre."
      },
      "id": "20e8df4b-f238-4f8a-951b-d01d32e2b1ff",
      "name": "Extract questions / answers",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.4,
      "position": [
        -272,
        80
      ]
    },
    {
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "import json\nimport re\n\nresults = []\n\nfor item in _items:\n  response = item[\"json\"][\"text\"]\n\n  response = re.sub(r'```json\\n?', '', response, flags=re.IGNORECASE)\n  response = re.sub(r'```\\n?', '', response).strip()\n\n  results.extend(json.loads(response)[\"questions\"])\n\nreturn results\n"
      },
      "id": "a1ff0f1e-8060-49ab-9183-d9584dd7cbfa",
      "name": "Parser questions / answers",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        80,
        80
      ]
    },
    {
      "parameters": {
        "url": "=https://r.jina.ai/{{ $('Loop Over Questions').item.json.url }}",
        "options": {}
      },
      "id": "53b629bc-f4e9-4305-984e-cf7ce31fe9be",
      "name": "Get answer",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1184,
        112
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        336,
        80
      ],
      "id": "86854aa5-cb4f-488e-9b99-8de90ddf7bbe",
      "name": "Loop Over Questions"
    },
    {
      "parameters": {
        "amount": 10
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        960,
        112
      ],
      "id": "db4ea897-23f1-4221-b0f0-70c578046da8",
      "name": "Wait"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Extrait la r\u00e9ponse compl\u00e8te de cette page FAQ.\n\nContenu:\n{{ $json.data }}\n\nRetourne un JSON avec la r\u00e9ponse. Format attendu:\n{\n  \"answer\": \"Texte complet de la r\u00e9ponse\"\n}\n\nRetourne UNIQUEMENT le JSON, rien d'autre."
      },
      "id": "7574e42f-f75f-44bd-a634-4e264d5f4f32",
      "name": "Extract answer",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.4,
      "position": [
        608,
        -256
      ]
    },
    {
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "import json\nimport re\n\nresults = []\n\nfor item in _items:\n  response = item[\"json\"][\"text\"]\n\n  response = re.sub(r'```json\\n?', '', response, flags=re.IGNORECASE)\n  response = re.sub(r'```\\n?', '', response).strip()\n\n  results.append(json.loads(response))\n\nreturn results"
      },
      "id": "e55b2a2b-244e-40b8-aedc-1eac9130348e",
      "name": "Parse answer",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        928,
        -256
      ]
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        1184,
        -240
      ],
      "id": "04110840-9a2f-4e71-8ed9-4a850f744cf9",
      "name": "Merge1"
    },
    {
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "import json\nimport base64\n\noutput_items = []\nall_data = []\n\n# Collecte toutes les donn\u00e9es JSON entrantes (items)\nfor item in _items:\n    all_data.append(item['json'])\n\n# Convertit le tableau d'objets JSON en une cha\u00eene JSON format\u00e9e\n# s'assurer qu'on encode en UTF-8 pour la compatibilit\u00e9\njson_string = json.dumps(all_data, indent=2, ensure_ascii=False)\njson_bytes = json_string.encode('utf8')\n\n# Cr\u00e9e les donn\u00e9es binaires au format attendu par n8n (base64)\n# Le nom du champ binaire doit \u00eatre unique, ex: 'json_output'\nbinary_data = {\n    'json_output': {\n        # Encode en base64 pour le transfert\n        'data': base64.b64encode(json_bytes).decode('utf8'), \n        'mimeType': 'application/json',\n        'fileName': 'faq_complete_rag_source.json',\n        'fileSize': len(json_bytes)\n    }\n}\n\n# Cr\u00e9e l'objet de sortie avec les donn\u00e9es binaires\noutput_items.append({\n    'json': {'success': True, 'message': 'JSON converti en binaire'},\n    'binary': binary_data\n})\n\nreturn output_items"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1616,
        -240
      ],
      "id": "288e023a-bd03-4fec-ac93-87c3ef8cd082",
      "name": "Create file context"
    },
    {
      "parameters": {
        "dataTableId": {
          "__rl": true,
          "value": "6bJjcVcg9rJne4UJ",
          "mode": "list",
          "cachedResultName": "faq",
          "cachedResultUrl": "/projects/yJGMCjVHH04zJMly/datatables/6bJjcVcg9rJne4UJ"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "question": "={{ $json.question }}",
            "answer": "={{ $json.data }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "question",
              "displayName": "question",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "answer",
              "displayName": "answer",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        1584,
        112
      ],
      "id": "df4335ba-af06-4fc2-b9aa-57fd845979fd",
      "name": "Save question / answer"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "6bJjcVcg9rJne4UJ",
          "mode": "list",
          "cachedResultName": "faq",
          "cachedResultUrl": "/projects/yJGMCjVHH04zJMly/datatables/6bJjcVcg9rJne4UJ"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "question",
              "keyValue": "={{ $json.question }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        544,
        96
      ],
      "id": "99f7a78b-62f6-498d-9373-0741d97e96e8",
      "name": "Get row(s)",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "56a3c12e-911b-4144-88ea-571b5f0d699b",
              "leftValue": "={{ $json.id }}",
              "rightValue": "",
              "operator": {
                "type": "number",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        752,
        96
      ],
      "id": "199a10fe-26ae-471f-95ed-2b4e981577df",
      "name": "If question exists"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "3de5c651-80a8-44bc-9221-8dd3549c7a26",
              "name": "data",
              "value": "={{ $json.data }}",
              "type": "string"
            },
            {
              "id": "3a8ef59f-b67e-474d-af62-8865f47894b4",
              "name": "question",
              "value": "={{ $('Loop Over Questions').item.json.question }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1392,
        112
      ],
      "id": "4d36a9ed-865b-4199-ab73-07161cd60a62",
      "name": "Rebuild data"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "4baf92a0-091c-427e-a50f-aae3324001d8",
              "name": "data",
              "value": "={{ $('Rebuild data').item.json.data }}",
              "type": "string"
            },
            {
              "id": "0c04d064-da0f-41bd-b98e-058f9c761062",
              "name": "question",
              "value": "={{ $('Rebuild data').item.json.question }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1792,
        112
      ],
      "id": "7e06d6c9-7aa9-488d-84e9-4331865062e9",
      "name": "Build response"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "d3518942-62c5-4452-a9b9-5823608764df",
              "name": "answer",
              "value": "={{ $json.answer }}",
              "type": "string"
            },
            {
              "id": "6f05e761-a887-49a4-aced-c3241005c436",
              "name": "question",
              "value": "={{ $json.question }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1408,
        -240
      ],
      "id": "9e520a50-3b69-4efd-abb7-5dd107e90fdc",
      "name": "Edit Fields"
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Get FAQ first page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mistral Chat Model 1": {
      "ai_languageModel": [
        [
          {
            "node": "Extract categories",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Mistral Chat Model 2": {
      "ai_languageModel": [
        [
          {
            "node": "Extract questions / answers",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Mistral Chat Model 3": {
      "ai_languageModel": [
        [
          {
            "node": "Extract answer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get FAQ first page": {
      "main": [
        [
          {
            "node": "Extract categories",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract categories": {
      "main": [
        [
          {
            "node": "Parser categories",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parser categories": {
      "main": [
        [
          {
            "node": "Get questions / answers url by category",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get questions / answers url by category": {
      "main": [
        [
          {
            "node": "Extract questions / answers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract questions / answers": {
      "main": [
        [
          {
            "node": "Parser questions / answers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parser questions / answers": {
      "main": [
        [
          {
            "node": "Loop Over Questions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get answer": {
      "main": [
        [
          {
            "node": "Rebuild data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Questions": {
      "main": [
        [
          {
            "node": "Extract answer",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Get row(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Get answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract answer": {
      "main": [
        [
          {
            "node": "Parse answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse answer": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge1": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create file context": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save question / answer": {
      "main": [
        [
          {
            "node": "Build response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s)": {
      "main": [
        [
          {
            "node": "If question exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If question exists": {
      "main": [
        [
          {
            "node": "Loop Over Questions",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rebuild data": {
      "main": [
        [
          {
            "node": "Save question / answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build response": {
      "main": [
        [
          {
            "node": "Loop Over Questions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Create file context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "93ba1de9-f9e7-438a-aee7-446203760439",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "9u8lhjFWHBTpcyR6",
  "tags": []
}