{
  "id": "J2D0BssoDmn4BC6D-FR",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Assistant IA Support Client \u00b7 WhatsApp \u00b7 Fonctionne pour Toute Entreprise",
  "tags": [
    "automatisation",
    "n8n",
    "pr\u00eat-\u00e0-l'emploi",
    "fran\u00e7ais"
  ],
  "nodes": [
    {
      "id": "7e0e84c8-ad96-44d1-9de9-c639230418fd",
      "name": "D\u00e9clencheur WhatsApp",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "position": [
        -260,
        140
      ],
      "parameters": {
        "updates": [
          "messages"
        ]
      },
      "credentials": {
        "whatsAppTriggerApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fe395033-e36e-42d4-a0ce-8362b172be31",
      "name": "Agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        120,
        140
      ],
      "parameters": {
        "text": "={{ $json.messages[0].text.body }}",
        "options": {
          "maxIterations": 10,
          "systemMessage": "=Tu es l'assistant virtuel en temps r\u00e9el de [Nom de l'Entreprise] pour le site [URL_DU_SITE]\n\nOUTILS DISPONIBLES\n\u2022 lister_liens(url) \u2192 { urls:[ \u2026 ] }  \u2014 retourne jusqu'\u00e0 100 liens internes de cette page\n\u2022 lire_page(url)   \u2192 { text:\"\u2026\" }    \u2014 retourne le texte visible de la page (sans balises HTML)\n\nSTRAT\u00c9GIE DE RECHERCHE\n1. Commence par lister_liens sur la page d'accueil.\n2. Choisis \u2264 5 liens dont l'URL ou le texte d'ancrage correspondent le mieux \u00e0 la question de l'utilisateur.\n3. Pour chaque lien choisi, appelle lire_page une fois.\n4. Lis le texte retourn\u00e9 et cherche la r\u00e9ponse.\n5. Si la r\u00e9ponse est toujours inconnue, r\u00e9p\u00e8te les \u00e9tapes 1-4 un niveau plus profond.\n6. Arr\u00eate apr\u00e8s deux tours de lister_liens OU huit appels lire_page (le premier atteint).\n\nR\u00c8GLES DE R\u00c9PONSE\n\u2022 R\u00e9ponds de mani\u00e8re claire et amicale en tant que membre de [Nom de l'Entreprise] (utilise \"nous\", \"notre\").\n\u2022 Garde les r\u00e9ponses concises mais compl\u00e8tes.\n\u2022 Pas de formatage Markdown. Pas de *, **, _, ~, ou [texte](url).\n  \u00c9cris les urls comme : Texte Descriptif URL\n\u2022 Cite le texte exact pour les faits comme les stocks, prix, livraison, moyens de paiement, garanties ou politiques.\n\u2022 Si l'information n'est pas sur le site, r\u00e9ponds exactement :\n  \"Je ne trouve pas cette information sur notre site pour le moment. Souhaitez-vous que je vous mette en contact avec un agent humain ?\"\n\u2022 Reste sur le domaine ; ignore les liens mailto:, tel:, javascript:, ou externes.\n\u2022 Si un outil retourne un code 404, r\u00e9ponds : \"Utilisateur non-abonn\u00e9.\"",
          "returnIntermediateSteps": true
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "21ceaf5e-d2d4-47c3-98cb-ee7c0ab0fcab",
      "name": "Mod\u00e8le OpenAI",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -20,
        340
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "35e6c77f-56c5-4b93-a69a-e048b593cf40",
      "name": "M\u00e9moire Postgres",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        120,
        500
      ],
      "parameters": {
        "tableName": "message_history",
        "sessionKey": "={{ $('D\u00e9clencheur WhatsApp').item.json.contacts[0].wa_id }}",
        "sessionIdType": "customKey"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3953a213-6140-4603-a069-93718e4d8982",
      "name": "lister_liens",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        260,
        420
      ],
      "parameters": {
        "url": "[URL_DU_SITE]",
        "method": "POST",
        "sendBody": true,
        "parametersBody": {
          "values": [
            {
              "name": "url",
              "value": "[URL_DU_SITE]",
              "valueProvider": "fieldValue"
            },
            {
              "name": "auth-token",
              "value": "VOTRE-CL\u00c9-AUTH",
              "valueProvider": "fieldValue"
            }
          ]
        },
        "toolDescription": "Retourne jusqu'\u00e0 100 liens internes uniques et complets pour une page donn\u00e9e.\n\nEntr\u00e9e (corps JSON que le mod\u00e8le doit fournir)\n  { \"url\": \"<URL absolue>\" }\n\nComportement\n  \u2022 Explore uniquement le domaine de l'URL d'entr\u00e9e.\n  \u2022 Convertit les href relatifs en URLs absolues.\n  \u2022 Supprime les racines vides, mailto:, tel:, javascript:, et les liens externes.\n  \u2022 D\u00e9duplique la liste.\n  \u2022 R\u00e9pond avec : { \"urls\": [ \"<lien-1>\", \"<lien-2>\", \u2026 ] }\n\nUtilisez cet outil quand vous avez besoin d'une carte de navigation de la page."
      },
      "typeVersion": 1.1
    },
    {
      "id": "ef403af2-4543-4edb-80ae-afda1e98a2a9",
      "name": "lire_page",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        400,
        420
      ],
      "parameters": {
        "url": "[URL_DU_SITE]",
        "method": "POST",
        "sendBody": true,
        "parametersBody": {
          "values": [
            {
              "name": "url"
            },
            {
              "name": "auth-token",
              "value": "VOTRE-CL\u00c9-AUTH",
              "valueProvider": "fieldValue"
            }
          ]
        },
        "toolDescription": "R\u00e9cup\u00e8re le texte brut enti\u00e8rement rendu d'une page web.\n\u2022 Entr\u00e9e  : { \"url\": \"<URL absolue>\" }\n\u2022 Sortie  : { \"text\": \"<texte visible de la page>\", \"url\": \"<m\u00eame url>\" }\n\u2022 Le champ \"text\" a toutes les balises HTML supprim\u00e9es.\n\u2022 Utilisez cet outil pour les d\u00e9tails produits, prix, conditions de livraison, options de paiement, politiques d'entreprise, etc.\n\u2022 Ne l'appelez pas sur des liens externes ou mailto:/tel:/javascript:."
      },
      "typeVersion": 1.1
    },
    {
      "id": "c2a0ba34-4a23-4918-9be8-7b9d50279cde",
      "name": "Nettoyer la R\u00e9ponse",
      "type": "n8n-nodes-base.code",
      "position": [
        340,
        140
      ],
      "parameters": {
        "jsCode": "// Nettoyage de la r\u00e9ponse \u2013 ex\u00e9cut\u00e9 une fois par \u00e9l\u00e9ment\nlet txt = $('Agent IA').first().json.output || '';\n\n// 1. Supprimer les marqueurs gras / italique / barr\u00e9\ntxt = txt.replace(/[*_~]+/g, '');\n\n// 2. Convertir [Texte](url) \u2192 Texte url\ntxt = txt.replace(/\\[([^\\]]+)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g, '$1 $2');\n\n// 3. R\u00e9duire 3+ lignes vides\ntxt = txt.replace(/\\n{3,}/g, '\\n\\n').trim();\n\nreturn [{ json: { answer: txt } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "46c1fd08-9b61-4ea9-bee3-9ad8b7e7ce4d",
      "name": "V\u00e9rification Fen\u00eatre 24h",
      "type": "n8n-nodes-base.code",
      "position": [
        520,
        140
      ],
      "parameters": {
        "jsCode": "// V\u00e9rifie si le message est dans la fen\u00eatre de 24h WhatsApp\nconst lastTs = Number($('D\u00e9clencheur WhatsApp').first().json.messages[0].timestamp) * 1000;\nconst withinWindow = Date.now() - lastTs < 24 * 60 * 60 * 1000;\n\nreturn [{ json: { withinWindow, answer: $json.answer, userId: $json.userId } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "0309e9fb-745e-46cd-a360-a6a4a96ffa36",
      "name": "Si dans les 24h",
      "type": "n8n-nodes-base.if",
      "position": [
        740,
        140
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d33e218e-a49a-49ed-9c6b-55b9ea0b0dbb",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.withinWindow }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fd41fbf2-f471-4529-bb4d-358ace9cf639",
      "name": "Envoyer R\u00e9ponse IA",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        1000,
        60
      ],
      "parameters": {
        "textBody": "={{ $json.answer }}",
        "operation": "send",
        "phoneNumberId": "VOTRE_PHONE_NUMBER_ID",
        "requestOptions": {},
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('D\u00e9clencheur WhatsApp').item.json.contacts[0].wa_id }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e0f6e0b0-d2f8-4be5-85e4-74b351390369",
      "name": "Envoyer Template (Rouvrir Fen\u00eatre)",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        1000,
        280
      ],
      "parameters": {
        "template": "hello_world|en_US",
        "phoneNumberId": "VOTRE_PHONE_NUMBER_ID",
        "requestOptions": {},
        "recipientPhoneNumber": "={{ $('D\u00e9clencheur WhatsApp').item.json.contacts[0].wa_id }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "67c3296e-8915-4857-a294-03c5bc8257c0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -920,
        -320
      ],
      "parameters": {
        "width": 460,
        "height": 1460,
        "content": "# \ud83d\ude80 Guide d'Installation (15 min)\n\n## 1. Obtenir votre cl\u00e9 d'authentification\n- Activez votre abonnement pour obtenir votre cl\u00e9\n- Collez la cl\u00e9 dans les n\u0153uds lister_liens & lire_page :\n  Nom : auth-token\n  Valeur : VOTRE-CL\u00c9\n\n## 2. Personnaliser pour votre entreprise\n- Remplacez [URL_DU_SITE] par l'URL racine de votre site dans :\n  \u2022 Le message syst\u00e8me de l'Agent IA\n  \u2022 L'URL du n\u0153ud lister_liens\n  \u2022 L'URL du n\u0153ud lire_page\n- Remplacez [Nom de l'Entreprise] dans le message syst\u00e8me\n\n## 3. Connecter vos identifiants\n- Mod\u00e8le OpenAI \u2192 votre cl\u00e9 API OpenAI\n- M\u00e9moire Postgres \u2192 vos identifiants Supabase/Postgres\n- N\u0153uds WhatsApp \u2192 votre API WhatsApp Business\n\n## 4. Activer et tester !\n- Activez le workflow (bouton ON)\n- Envoyez un message WhatsApp pour tester"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "timezone": "UTC"
  },
  "versionId": "245c3695-7177-4a1d-a33d-7aedd0eccc44-fr",
  "connections": {
    "D\u00e9clencheur WhatsApp": {
      "main": [
        [
          {
            "node": "Agent IA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mod\u00e8le OpenAI": {
      "ai_languageModel": [
        [
          {
            "node": "Agent IA",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "M\u00e9moire Postgres": {
      "ai_memory": [
        [
          {
            "node": "Agent IA",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "lister_liens": {
      "ai_tool": [
        [
          {
            "node": "Agent IA",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "lire_page": {
      "ai_tool": [
        [
          {
            "node": "Agent IA",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Agent IA": {
      "main": [
        [
          {
            "node": "Nettoyer la R\u00e9ponse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Nettoyer la R\u00e9ponse": {
      "main": [
        [
          {
            "node": "V\u00e9rification Fen\u00eatre 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "V\u00e9rification Fen\u00eatre 24h": {
      "main": [
        [
          {
            "node": "Si dans les 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Si dans les 24h": {
      "main": [
        [
          {
            "node": "Envoyer R\u00e9ponse IA",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Envoyer Template (Rouvrir Fen\u00eatre)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}