8
n8n 中文网amn8n.com

Chatwoot 多通道 AI 助手演示

中级

这是一个Miscellaneous, AI Chatbot, Multimodal AI领域的自动化工作流,包含 13 个节点。主要使用 If, Set, Code, Webhook, HttpRequest 等节点。 使用Chatwoot和OpenRouter构建多通道客户支持AI助手

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "gfA9Xdug8uza14hb",
  "meta": {
    "instanceId": "db407c8f66a7d599018aa1edf828f4170b2b2800a0674fff7140b6681ef113b0",
    "templateCredsSetupCompleted": true
  },
  "name": "Chatwoot 多通道 AI 助手演示",
  "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": "压缩 Webhook 数据",
      "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": "检查是否为传入消息",
      "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": "加载 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": "处理已加载的历史记录",
      "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": "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": "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": "发送消息",
      "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": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -560
      ],
      "parameters": {
        "width": 476,
        "height": 1344,
        "content": "## Chatwoot 多通道 AI 助手演示"
      },
      "typeVersion": 1
    },
    {
      "id": "679990cb-6239-4f4f-87fc-b94f0535f334",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 648,
        "height": 476,
        "content": "## 接收和准备数据"
      },
      "typeVersion": 1
    },
    {
      "id": "48c75b75-beaa-43c8-b758-72b0f614641c",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        -528
      ],
      "parameters": {
        "color": 7,
        "width": 536,
        "height": 508,
        "content": "## 加载和处理对话历史"
      },
      "typeVersion": 1
    },
    {
      "id": "c8752288-6a02-41a1-9443-b07f5bb4044c",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        -432
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 684,
        "content": "## 简单 AI 助手"
      },
      "typeVersion": 1
    },
    {
      "id": "dd325687-7207-44f2-be87-3c88d3499f09",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 312,
        "height": 492,
        "content": "## 将 AI 响应发送到 Chatwoot"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "0f04c96e-2827-4d12-b25a-d3d0aab1d01a",
  "connections": {
    "Chatwoot Webhook": {
      "main": [
        [
          {
            "node": "Squize Webhook Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chatwoot Assistant": {
      "main": [
        [
          {
            "node": "Send Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Squize Webhook Data": {
      "main": [
        [
          {
            "node": "Check If Incoming Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Chatwoot Assistant",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Process Loaded History": {
      "main": [
        [
          {
            "node": "Chatwoot Assistant",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Incoming Message": {
      "main": [
        [
          {
            "node": "Load Chatwoot Conversation History",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Load Chatwoot Conversation History": {
      "main": [
        [
          {
            "node": "Process Loaded History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 杂项, AI 聊天机器人, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量13
分类3
节点类型8
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
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.

外部链接
在 n8n.io 查看

分享此工作流