Demostración del asistente multicanal de Chatwoot

Intermedio

Este es unMiscellaneous, AI Chatbot, Multimodal AIflujo de automatización del dominio deautomatización que contiene 13 nodos.Utiliza principalmente nodos como If, Set, Code, Webhook, HttpRequest. Construye un asistente de soporte al cliente multicanal usando Chatwoot y OpenRouter

Requisitos previos
  • Punto final de HTTP Webhook (n8n generará automáticamente)
  • Pueden requerirse credenciales de autenticación para la API de destino
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "id": "gfA9Xdug8uza14hb",
  "meta": {
    "instanceId": "db407c8f66a7d599018aa1edf828f4170b2b2800a0674fff7140b6681ef113b0",
    "templateCredsSetupCompleted": true
  },
  "name": "Multichannel AI Assistant Demo for Chatwoot",
  "tags": [],
  "nodes": [
    {
      "id": "your-id",
      "name": "Chatwoot Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        48,
        -48
      ],
      "webhookId": "your-id",
      "parameters": {
        "path": "your-path",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "2aed8dcb-506a-4ede-a708-06b8c3087461",
      "name": "Squize Webhook Data",
      "type": "n8n-nodes-base.set",
      "position": [
        272,
        -48
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"data\": {\n    \"inbox_id\": \"{{ $json.body.inbox.id }}\",\n    \"inbox_title\": \"{{ $json.body.inbox.name }}\",\n    \"conv_id\": \"{{ $json.body.conversation.id }}\",\n    \"channel_type\": \"{{ $json.body.conversation.channel }}\",\n    \"message_id\": \"{{ $json.body.id }}\",\n    \"message_content\": \"{{ $json.body.content.replace(/\\r?\\n/g, '\\\\n') }}\",\n    \"message_type\": \"{{ $json.body.message_type }}\",\n    \"private\": \"{{ $json.body.private }}\",\n    \"account_id\": \"{{ $json.body.account.id }}\",\n    \"account_name\": \"{{ $json.body.account.name }}\",\n    \"content_type\": \"{{ $json.body.content_type }}\",\n    \"created_at\": \"{{ $json.body.created_at }}\",\n    \"event\": \"{{ $json.body.event }}\",\n    \"conversation_labels\": {{ $json.body.conversation.labels || [] }},\n    \"attachments\": {{ $json.body.attachments || [] }},\n    \"meta\": {{ $json.body.conversation.meta || null }}\n  }\n} "
      },
      "typeVersion": 3.4
    },
    {
      "id": "c8691100-44a3-47b1-9724-662da1875ad2",
      "name": "Verificar si es Mensaje Entrante",
      "type": "n8n-nodes-base.if",
      "position": [
        496,
        -48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e60a5d22-65b5-4500-b59b-cdf70b19c945",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.data.message_type }}",
              "rightValue": "incoming"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "04d24443-a918-42a3-b96b-ae0cf9d93082",
      "name": "Cargar Historial de Conversación de Chatwoot",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        -208
      ],
      "parameters": {
        "url": "=https://yourchatwooturl.com/api/v1/accounts/{{ $('Squize Webhook Data').item.json.data.account_id }}/conversations/{{ $('Squize Webhook Data').item.json.data.conv_id }}/messages",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "api_access_token",
              "value": "YOUR_ACCESS_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3d5acbb7-88ee-4758-9130-378986cc6713",
      "name": "Procesar Historial Cargado",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        -208
      ],
      "parameters": {
        "jsCode": "// Initialize the default output structure to be returned in case of error or empty input.\nconst defaultOutput = {\n    \"conversation_text\": \"\"\n};\n\ntry {\n    // --- INPUTS ---\n    // Assuming the primary message payload is from the first input item.\n    const messages = $('Load Chatwoot Conversation History').first().json.payload;\n\n    // Ensure 'messages' is a valid array and messages.length > 0 before proceeding.\n    if (Array.isArray(messages) && messages.length > 0) {\n\n        // Map over each message to transform it into the desired format.\n        const fullHistory = messages.map(msg => {\n            // RULE 1: Determine the role based on the sender type.\n            const role = (msg.sender && msg.sender.type === 'contact') ? 'user' : 'assistant';\n\n            // RULE 2: Replace '/start' content with 'Hello!'.\n            // FIX: Default null content to an empty string to ensure safe concatenation.\n            let content = msg.content || '';\n\n            if (content === '/start') {\n                content = 'Hello!';\n            }\n\n            return {\n                role,\n                content\n            };\n        });\n\n        // --- TASK 2: Remove Messages with Empty Content ---\n        // Filter the generated history to exclude any messages where the content is empty or just whitespace.\n        const filteredHistory = fullHistory.filter(msg => msg.content && msg.content.trim() !== '');\n\n        // --- TASK 3: Create a single text string from the entire history ---\n        // This now uses the entire filteredHistory instead of a slice.\n        const conversationText = filteredHistory\n            .map(msg => `[${msg.role.toUpperCase()}] : ${msg.content}`)\n            .join(\", \\n\");\n\n        // Return the final string in the expected n8n JSON format.\n        return [{\n            json: {\n                \"conversation_text\": conversationText\n            }\n        }];\n\n    }\n\n    // If the input was invalid or empty, return the default empty structure.\n    return [{\n        json: defaultOutput\n    }];\n\n} catch (error) {\n    // RULE 3: If any error occurs during execution, return the default empty structure.\n    // This ensures the workflow doesn't fail.\n    console.error(\"Error processing history:\", error.message);\n    return [{\n        json: defaultOutput\n    }];\n}\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f8992fc5-23c5-41f7-9e42-66a6a24dd07e",
      "name": "Modelo de Chat OpenRouter",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1904,
        96
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "id": "hrSKg9wcHKBUTAkN",
          "name": "OpenRouter account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0ba89367-f064-4a1d-9442-debb80b00228",
      "name": "Asistente de Chatwoot",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1952,
        -48
      ],
      "parameters": {
        "text": "=`conversation history`: `{{ $json.conversation_text }}` ",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=# ROLE & GOAL\nYou are a friendly and helpful AI assistant for Chatwoot Integration. Your primary goal is to answer user questions about Chatwoot's APIs accurately and concisely.\n\n# PRIMARY DIRECTIVE\nYou MUST provide assistance based *only* on the information provided in the `KNOWLEDGE BASE` section below. Do not use any external knowledge. If the `KNOWLEDGE BASE` does not contain the necessary information to answer a question, you must refer the user to the official documentation.\n\n# KNOWLEDGE BASE\n---\nWhether you’re building custom workflows for your support team, integrating Chatwoot into your product, or managing users across installations, our APIs provide the flexibility and power to help you do more with Chatwoot.\nChatwoot provides three categories of APIs, each designed with a specific use case in mind:\n- **Application APIs:** For account-level automation and agent-facing integrations.\n- **Client APIs:** For building custom chat interfaces for end-users\n- **Platform APIs:** For managing and administering installations at scale\n\n**Application APIs** are designed for interacting with a Chatwoot account from an agent/admin perspective. Use them to build internal tools, automate workflows, or perform bulk operations like data import/export.\n- **Authentication:** Requires a user `access_token`, which can be generated from Profile Settings after logging into your Chatwoot account.\n- **Availability:** Supported on both Cloud and Self-hosted Chatwoot installations.\n\n**Client APIs** are intended for building custom messaging experiences over Chatwoot. If you’re not using the native website widget or want to embed chat in your mobile app, these APIs are the way to go.\n- **Authentication:** Uses `inbox_identifier` (from Settings → Configuration in API inboxes) and `contact_identifier` (returned when creating a contact).\n- **Availability:** Supported on both Cloud and Self-hosted Chatwoot installations.\n\n**Platform APIs** are used to manage Chatwoot installations at the admin level. These APIs allow you to control users, roles, and accounts, or sync data from external authentication systems.\n- **Note:** Platform APIs cannot access accounts or users created via the Chatwoot UI, or by other API keys. They can only access objects created by the specific platform API key used for authentication.\n- **Authentication:** Requires an `access_token` generated by a Platform App, which can be created in the Super Admin Console.\n- **Availability:** Available on Self-hosted / Managed Hosting Chatwoot installations only.\n---\n\n# OPERATING RULES\n1.  **Persona:** Your tone is friendly and helpful, but your answers must be compact and concise. Get straight to the point.\n2.  **Knowledge Constraint:** Adhere strictly to the `KNOWLEDGE BASE`. Do not invent or infer information.\n3.  **Complete Fallback:** If the user's question cannot be answered *at all* from the `KNOWLEDGE BASE`, your only response should be to refer them to the official documentation at `https://developers.chatwoot.com/introduction`.\n4.  **Partial Answer Rule:** If you can answer part of the question from the `KNOWLEDGE BASE`, provide that partial answer first, then state that for more details, the user should consult the official documentation.\n5.  **Focus on Last Message:** The `conversation_history` is for context only. Your main focus is always the last user message.\n6.  **Final Output:** Your response must ONLY be the final, user-facing message. Do not include any explanations, preambles, or self-commentary.\n\n# INPUT & OUTPUT FORMAT\n-   **INPUT:** You will receive the conversation history as a single string.\n-   **OUTPUT:** You will provide only the direct response to the user.\n\n# EXAMPLES\n---\n**EXAMPLE 1: Information is in the Knowledge Base**\n\n**INPUT:**\n`conversation_history`: `[ASSISTANT]: Sure, what else can I help you with? \\n [USER]: Hi, does Chatwoot provide API?`\n\n**ASSISTANT RESPONSE:**\nYes, Chatwoot provides three categories of APIs: Application APIs for account-level automation, Client APIs for building custom chat interfaces, and Platform APIs for managing installations. Which one are you interested in?\n---\n**EXAMPLE 2: Information is NOT in the Knowledge Base**\n\n**INPUT:**\n`conversation_history`: `[ASSISTANT]: The Client API is available on both cloud and self-hosted installations. \\n [USER]: What are the rate limits for the Client API?`\n\n**ASSISTANT RESPONSE:**\nI do not have information on specific API rate limits. For technical details like that, please consult the official documentation at `https://developers.chatwoot.com/introduction`.\n---"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "7fe05d5a-b8ac-4bab-84b7-cae0dee8c9f1",
      "name": "Enviar Mensaje",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2576,
        -48
      ],
      "parameters": {
        "url": "=https://yourchatwooturl.com/api/v1/accounts/{{ $('Squize Webhook Data').item.json.data.account_id }}/conversations/{{ $('Squize Webhook Data').item.json.data.conv_id }}/messages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "content",
              "value": "={{ $json.text }}"
            },
            {
              "name": "message_type",
              "value": "outgoing"
            },
            {
              "name": "private",
              "value": "false"
            },
            {
              "name": "content_type",
              "value": "text"
            },
            {
              "name": "content_attributes",
              "value": "{}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "api_access_token",
              "value": "YOUR_ACCESS_TOKEN"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e60f34f5-e688-44b6-8d96-b323cfdb0bf2",
      "name": "Nota Adhesiva 7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -560
      ],
      "parameters": {
        "width": 476,
        "height": 1344,
        "content": "## Multichannel AI Assistant Demo for Chatwoot\n\n### This simple n8n template demonstrates a Chatwoot integration that can:\n\n* Receive new messages via a webhook.\n* Retrieve conversation history.\n* Process the message history into a format suitable for an LLM.\n* Demonstrate an AI Assistant processing a user's query.\n* Send the AI Assistant's response back to Chatwoot.\n\n**Use Case:**\nIf you have multiple communication channels with your clients (e.g., Telegram, Instagram, WhatsApp, Facebook) integrated with Chatwoot, you can use this template as a starting point to build more sophisticated and tailored AI solutions that cover all channels at once.\n\n### How it works\n* A webhook receives the `message created` event from Chatwoot.\n* The webhook data is then filtered to keep only the necessary information for a cleaner workflow.\n* The workflow checks if the message is \"incoming.\" This is crucial to prevent the assistant from replying to its own messages and creating endless loops.\n* The conversation history is retrieved from Chatwoot via an API call using the HTTP Request node. This allows the assistant's interaction to be more natural and continuous without needing to store conversation history locally.\n* A simple AI Assistant processes the conversation history and generates a response to the user based on its built-in knowledge base (see the prompt in the assistant node).\n* The final HTTP Request node sends the AI-generated response back to the appropriate Chatwoot conversation.\n\n### How to Use\n1.  In Chatwoot, go to Settings → Integrations → Webhooks and add your n8n webhook URL. Be sure to select the `message created` event.\n2.  In the HTTP Request nodes, replace the placeholder values:\n    * `https://yourchatwooturl.com`\n    * `api_access_token`\n    You can find these values on your Chatwoot super admin page.\n3.  The LLM node is configured to use OpenRouter. Add your OpenRouter credentials, or replace the node with your preferred LLM provider.\n\n### Requirements\n* An API key for OpenRouter or credentials for your preferred LLM provider.\n* A Chatwoot account with at least one integrated channel and super admin access to obtain the `api_access_token`.\n\n### Need Help Building Something More?\nContact me on Telegram: @ninesfork\n\nHappy Hacking!"
      },
      "typeVersion": 1
    },
    {
      "id": "679990cb-6239-4f4f-87fc-b94f0535f334",
      "name": "Nota Adhesiva 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 648,
        "height": 476,
        "content": "## Receiving and Preparing Data\n\nThis part of the workflow **receives data** from the webhook trigger. This data is immediately filtered to remove irrelevant fields and keep only the necessary information. A crucial final check verifies that the message type is `incoming`, which is essential for preventing the system from replying to its own messages and creating infinite loops. 📡"
      },
      "typeVersion": 1
    },
    {
      "id": "48c75b75-beaa-43c8-b758-72b0f614641c",
      "name": "Nota Adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        -528
      ],
      "parameters": {
        "color": 7,
        "width": 536,
        "height": 508,
        "content": "## Load and Process Conversation History\n\nThis part of the workflow **retrieves the full conversation history** from the API using an `HTTP Request` node. A `Code` node then extracts the `payload` array from the response and processes it into a single, clean string.\n\nThe output is formatted specifically for the language model:\n`\"[USER]: text\\n[ASSISTANT]: text\\n...\"`\n\nThis plain-text format is more efficient and prevents sending complex or \"noisy\" JSON data directly to the LLM. 🤖"
      },
      "typeVersion": 1
    },
    {
      "id": "c8752288-6a02-41a1-9443-b07f5bb4044c",
      "name": "Nota Adhesiva 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        -432
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 684,
        "content": "## Simple AI Assistant\n\nThis demo provides a basic example of how to structure `system` and `user` messages in `Basic LLM Node`. This method ensures the AI's response stays within the context of a provided knowledge base.\n\nFor more dynamic and powerful systems, you may need to augment this workflow with more advanced approaches, such as:\n\n* **Retrieval-Augmented Generation (RAG):** Integrate a vector database to pull in relevant, real-time information.\n* **Advanced Prompting Techniques:** Apply methods like Chain-of-Thought or few-shot examples to improve the AI's reasoning and response quality. 🧠"
      },
      "typeVersion": 1
    },
    {
      "id": "dd325687-7207-44f2-be87-3c88d3499f09",
      "name": "Nota Adhesiva 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 312,
        "height": 492,
        "content": "## Send AI Response to Chatwoot\n\nThis final `HTTP Request` node **sends the AI-generated response** back to the correct conversation in Chatwoot.\n\nTo do this, it uses the `account_id` and `conv_id` values that were retrieved and isolated by a previous node in the workflow. 🚀"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "0f04c96e-2827-4d12-b25a-d3d0aab1d01a",
  "connections": {
    "your-id": {
      "main": [
        [
          {
            "node": "2aed8dcb-506a-4ede-a708-06b8c3087461",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0ba89367-f064-4a1d-9442-debb80b00228": {
      "main": [
        [
          {
            "node": "7fe05d5a-b8ac-4bab-84b7-cae0dee8c9f1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2aed8dcb-506a-4ede-a708-06b8c3087461": {
      "main": [
        [
          {
            "node": "c8691100-44a3-47b1-9724-662da1875ad2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f8992fc5-23c5-41f7-9e42-66a6a24dd07e": {
      "ai_languageModel": [
        [
          {
            "node": "0ba89367-f064-4a1d-9442-debb80b00228",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "3d5acbb7-88ee-4758-9130-378986cc6713": {
      "main": [
        [
          {
            "node": "0ba89367-f064-4a1d-9442-debb80b00228",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c8691100-44a3-47b1-9724-662da1875ad2": {
      "main": [
        [
          {
            "node": "04d24443-a918-42a3-b96b-ae0cf9d93082",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "04d24443-a918-42a3-b96b-ae0cf9d93082": {
      "main": [
        [
          {
            "node": "3d5acbb7-88ee-4758-9130-378986cc6713",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Intermedio - Varios, Chatbot de IA, IA Multimodal

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Flujos de trabajo relacionados recomendados

Asistente de rastreador de búsqueda de propiedades
Usar PropertyFinder.ae, OpenRouter y SerpAPI para responder preguntas sobre bienes inmuebles a través de AI
If
Set
Code
+
If
Set
Code
18 NodosGeorge Zargaryan
Varios
Construir un asistente de WhatsApp con memoria, Google Workspace y múltiples imágenes de investigación de IA
Construir un asistente de WhatsApp con memoria, Google Workspace e investigación de imágenes de múltiples IAs
If
Set
Code
+
If
Set
Code
71 NodosIniyavan JC
Chatbot de IA
Análisis inteligente diario de grupos de WhatsApp: Análisis con GPT-4.1 y transcripción de mensajes de voz
Análisis inteligente diario de grupos de WhatsApp: análisis con GPT-4.1 y transcripción de mensajes de voz
If
Set
Code
+
If
Set
Code
52 NodosDaniel Lianes
Varios
Pulso del foro de Telegram: monitoreo de la comunidad con modelos de IA Gemini y Groq
Pulso del foro de Telegram: Monitoreo de la comunidad con Gemini y modelos de IA Groq
If
Set
Code
+
If
Set
Code
59 NodosNguyen Thieu Toan
Varios
Construir un Chatbot Impulsado por IA para la Evaluación de Candidatos en Slack
Análisis de CV con IA y Evaluación de Candidatos: Integración de Slack y Hojas de Cálculo de Google
If
Code
Slack
+
If
Code
Slack
29 NodosTrung Tran
Chatbot de IA
Sistema de procesamiento de pedidos de alimentos impulsado por IA, integrado con Facebook Messenger, Google Sheets y Calendario
Sistema de procesamiento de pedidos de alimentos impulsado por IA, integrado con Facebook Messenger, Google Sheets y Calendario
If
Code
Webhook
+
If
Code
Webhook
26 NodosHans Wilhelm Radam
Nutrición de leads
Información del flujo de trabajo
Nivel de dificultad
Intermedio
Número de nodos13
Categoría3
Tipos de nodos8
Descripción de la dificultad

Adecuado para usuarios con experiencia intermedia, flujos de trabajo de complejidad media con 6-15 nodos

Autor
George Zargaryan

George Zargaryan

@zrgrn

Building AI Systems & Multi-Agent Assistants incorporating data collection, intent classification, human handoff, RAG, and API-driven CRM actions. 10+ years in software development including iOS and Android. Now in the process of founding my AI Automation Platform - Agenza AI.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34