8
n8n 中文网amn8n.com

集成Gemini AI的智能Facebook Messenger聊天机器人,支持消息批处理和历史记录

高级

这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 28 个节点。主要使用 If, Set, Code, Wait, Webhook 等节点。 集成Gemini AI的智能Facebook Messenger聊天机器人,支持消息批处理和历史记录

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证
  • Google Gemini API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "735886904af210643f438394a538e64374f0cb4ab13fd94d97005987482d652a",
    "templateId": "9192"
  },
  "nodes": [
    {
      "id": "183a6046-1115-401e-8510-5390fac643b8",
      "name": "Google Gemini 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        3008,
        2112
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "98cdc87a-0f97-4ce2-8a05-f9fad4fbb47c",
      "name": "是否为最大ID?",
      "type": "n8n-nodes-base.if",
      "position": [
        2256,
        1840
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c4f1518c-2d3d-4e7e-bc61-dd8bf02a34b4",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": "={{ $('Insert To Process').first().json.id }}"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "c9ef8f13-7f91-49bf-99bb-a06c540ba680",
      "name": "发送输入中状态",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2784,
        1696
      ],
      "parameters": {
        "url": "=https://graph.facebook.com/v23.0/{{ $('Set Context').item.json.page_id }}/messages",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"recipient\": {\n    \"id\": \"{{ $('Set Context').item.json.user_id }}\"\n  },\n  \"sender_action\": \"typing_on\"\n}\n",
        "sendBody": true,
        "sendQuery": true,
        "specifyBody": "json",
        "queryParameters": {
          "parameters": [
            {
              "name": "access_token",
              "value": "={{ $('Set Context').first().json.page_token }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "66b05dc9-67f2-42dd-9535-0358801055fc",
      "name": "是否为消息?",
      "type": "n8n-nodes-base.if",
      "onError": "continueRegularOutput",
      "position": [
        640,
        1744
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3f975e97-e281-4add-825e-f168f9ec6d50",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.entry[0].messaging[0].message.text }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "945a574e-6013-4828-b53e-227cc1f5e72f",
      "name": "是否来自页面?",
      "type": "n8n-nodes-base.if",
      "onError": "continueRegularOutput",
      "position": [
        864,
        1744
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "22aba732-f39d-473f-9336-6e9f0fdfd9ff",
              "operator": {
                "type": "boolean",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.entry[0].messaging[0].message.is_echo }}",
              "rightValue": ""
            },
            {
              "id": "5c2fa5c6-2c3a-4988-8635-d3984d864a87",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.entry[0].messaging[0].message.is_echo }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ba78b201-6798-4ceb-8ef3-f5446a33db47",
      "name": "确认Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        640,
        1552
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.query[\"hub.challenge\"] }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "aa1438a6-b174-4f28-b49b-2d5453a804d9",
      "name": "Facebook Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        416,
        1648
      ],
      "webhookId": "b12c5f3e-a7d7-4f0e-bd18-7b40f7c5f0d3",
      "parameters": {
        "path": "nguyenthieutoan-facebook-page",
        "options": {},
        "responseMode": "responseNode",
        "multipleMethods": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "9611d38c-5115-460e-b9cf-1183913e93bf",
      "name": "已读回执",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1312,
        1648
      ],
      "parameters": {
        "url": "=https://graph.facebook.com/v23.0/{{ $json.page_id }}/messages",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"recipient\": {\n    \"id\": \"{{ $json.user_id }}\"\n  },\n  \"sender_action\": \"mark_seen\"\n} ",
        "sendBody": true,
        "sendQuery": true,
        "specifyBody": "json",
        "queryParameters": {
          "parameters": [
            {
              "name": "access_token",
              "value": "={{ $json.page_token }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0ac00a0d-a627-4b67-8cd7-893aa6ad5181",
      "name": "发送文本",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3728,
        1872
      ],
      "parameters": {
        "url": "=https://graph.facebook.com/v23.0/{{ $('Set Context').first().json.page_id }}/messages",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"recipient\": {\n    \"id\": \"{{ $('Set Context').first().json.user_id }}\"\n  },\n  \"messaging_type\": \"RESPONSE\",\n  \"message\": {\n    \"text\": {{JSON.stringify($('Format for Facebook Output').item.json.text)}}\n  }\n}",
        "sendBody": true,
        "sendQuery": true,
        "specifyBody": "json",
        "queryParameters": {
          "parameters": [
            {
              "name": "access_token",
              "value": "={{ $('Set Context').first().json.page_token }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "71f74233-caf5-4ddd-b3b7-1f872338539c",
      "name": "设置上下文",
      "type": "n8n-nodes-base.set",
      "position": [
        1088,
        1744
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n\"user_id\":\"{{ $json.body.entry[0].messaging[0].sender.id }}\",\n\"user_text\":\"{{ $json.body.entry[0].messaging[0].message.text }}\",\n\"page_id\":\"{{ $json.body.entry[0].id }}\",\n\"page_token\":\"<YOUR_TOKEN>\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "fa878cbb-e5e2-43ed-8daf-be71b0555282",
      "name": "等待3秒",
      "type": "n8n-nodes-base.wait",
      "position": [
        1536,
        1840
      ],
      "webhookId": "bec8714e-5c19-4ff8-9644-f8ba6e8ecdfd",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "5291b6a6-0151-4282-af9f-32f637ccb61c",
      "name": "插入待处理",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1312,
        1840
      ],
      "parameters": {
        "columns": {
          "value": {
            "user_id": "={{ $json.user_id }}",
            "processed": false,
            "user_text": "={{ $json.user_text }}"
          },
          "schema": [
            {
              "id": "user_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "user_id",
              "defaultMatch": false
            },
            {
              "id": "user_text",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "user_text",
              "defaultMatch": false
            },
            {
              "id": "bot_rep",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "bot_rep",
              "defaultMatch": false
            },
            {
              "id": "processed",
              "type": "boolean",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "processed",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "nXPDtd1UiwqvIoh8",
          "cachedResultUrl": "/projects/mYtIzVb8cWfhFOhJ/datatables/nXPDtd1UiwqvIoh8",
          "cachedResultName": "Batch_messages"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a1140766-f895-4713-9911-e6aead996b83",
      "name": "获取未处理消息",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1760,
        1840
      ],
      "parameters": {
        "limit": 10,
        "filters": {
          "conditions": [
            {
              "keyName": "user_id",
              "keyValue": "={{ $json.user_id }}"
            },
            {
              "keyName": "processed",
              "condition": "isFalse"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "nXPDtd1UiwqvIoh8",
          "cachedResultUrl": "/projects/mYtIzVb8cWfhFOhJ/datatables/nXPDtd1UiwqvIoh8",
          "cachedResultName": "Batch_messages"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c253735c-1ab2-4cbb-891e-ffb08101c63b",
      "name": "处理合并消息",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3088,
        1888
      ],
      "parameters": {
        "text": "={{ $('Get Max ID + Merged Mess').first().json.merged_message }}",
        "options": {
          "systemMessage": "=# Persona\nYou are Jenix, the personal AI assistant for Nguyễn Thiệu Toàn. Your primary role is to act as a specialized consultant, advising potential clients on the AI and Automation services he provides.\n\n# Core Directives\n1.  *Consult on Services:* Your main goal is to understand the customer's needs and advise them on how Nguyễn Thiệu Toàn's services can help. The core services include:\n    a. *Automation Solutions for Businesses:* Providing custom automation workflows using platforms like n8n and other AI-powered tools.\n    b. *AI & Automation Training:* Offering training programs for individuals and companies on leveraging AI and automation.\n2.  *Facilitate Scheduling:* If a potential client expresses strong interest or has complex questions that require direct expertise, proactively offer to schedule a consultation with Nguyễn Thiệu Toàn.\n\n# Conversational Flow\n1.  *Opening Message:* In the very first message of a new conversation (when chat history is empty), you MUST introduce yourself. The introduction should be similar to this: \"Chào anh/chị, em là Jenix, trợ lý AI của anh Nguyễn Thiệu Toàn. Em có thể giúp anh/chị giải đáp các thắc mắc về dịch vụ và giải pháp Tự động hóa & AI ạ.\"\n2.  *Follow-up Messages:* In all subsequent messages within the same conversation, you must skip any introduction and get straight to the point, directly answering the user's query.\n\n# Constraints & Rules\n1.  *Extreme Brevity:* Your responses (after the opening message) must be concise and directly address the user's core question. Eliminate all filler words.\n2.  *Language and Addressing (Vietnamese):* You must adhere strictly to the following conversational protocol:\n    -   Address the customer as \"anh\" or \"chị\".\n    -   Refer to yourself as \"em\".\n\n# Tone of Voice\n-   *Clever & Witty:* Employ a smart and slightly humorous tone.\n-   *Friendly & Approachable:* Maintain a warm, welcoming, and helpful demeanor.\n-   *Efficient:* Your style should convey competence and respect for the customer's time.\n\n# Output Format\n-   Your entire output must be formatted in *Facebook Markdown*.\n\n# Context\n-   *Chat History:* The following JSON object contains the previous messages in this conversation. Use this history to maintain context and determine if you should deliver the opening message.\n{{JSON.stringify($json.history) }}"
        },
        "promptType": "define",
        "needsFallback": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2,
      "waitBetweenTries": 100
    },
    {
      "id": "36bfb457-dd1f-4e40-892d-954582980ef3",
      "name": "更新页面回复",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        3936,
        1952
      ],
      "parameters": {
        "columns": {
          "value": {
            "bot_rep": "={{ $('Process Merged Message').first().json.output }}"
          },
          "schema": [
            {
              "id": "user_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "user_id",
              "defaultMatch": false
            },
            {
              "id": "user_text",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "user_text",
              "defaultMatch": false
            },
            {
              "id": "bot_rep",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "bot_rep",
              "defaultMatch": false
            },
            {
              "id": "processed",
              "type": "boolean",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "processed",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "user_id",
              "keyValue": "={{ $('Set Context').first().json.user_id }}"
            },
            {
              "keyValue": "={{ $('Get Max ID + Merged Mess').first().json.id }}"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "nXPDtd1UiwqvIoh8",
          "cachedResultUrl": "/projects/mYtIzVb8cWfhFOhJ/datatables/nXPDtd1UiwqvIoh8",
          "cachedResultName": "Batch_messages"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "af7ae4cc-fa6d-4825-b64a-51219ab37aa2",
      "name": "将FALSE更新为TRUE",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        3936,
        1792
      ],
      "parameters": {
        "columns": {
          "value": {
            "processed": true
          },
          "schema": [
            {
              "id": "user_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "user_id",
              "defaultMatch": false
            },
            {
              "id": "user_text",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "user_text",
              "defaultMatch": false
            },
            {
              "id": "bot_rep",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "bot_rep",
              "defaultMatch": false
            },
            {
              "id": "processed",
              "type": "boolean",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "processed",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "user_id",
              "keyValue": "={{ $('Set Context').first().json.user_id }}"
            },
            {
              "keyName": "processed",
              "condition": "isFalse"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "nXPDtd1UiwqvIoh8",
          "cachedResultUrl": "/projects/mYtIzVb8cWfhFOhJ/datatables/nXPDtd1UiwqvIoh8",
          "cachedResultName": "Batch_messages"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d397a1c2-ca12-49de-8926-3467d180300c",
      "name": "格式化Facebook输出",
      "type": "n8n-nodes-base.code",
      "position": [
        3536,
        1872
      ],
      "parameters": {
        "jsCode": "const MAX_LEN = 2000;\n\n/* === Get input === */\nlet text = ($input.first().json.output || \"\").trim();\nif (!text) return [];\n\n/* --- Fix escape JSON: đổi \\\\n, \\\\\\n thành \\n thật --- */\ntext = text.replace(/\\\\+/g, '\\\\');   // gộp nhiều \\ thành 1\ntext = text.replace(/\\\\n/g, '\\n');   // đổi thành newline thật\n\n/* ---------- 1) Markdown → Facebook Markdown ---------- */\nfunction mdToFacebook(md){\n  let s = md;\n\n  // code block → giữ nguyên\n  s = s.replace(/```([\\s\\S]*?)```/g, (m,p1)=>`\\`\\`\\n${p1.trim()}\\n\\`\\`\\``);\n\n  // inline code\n  s = s.replace(/`([^`]+)`/g, (m,p1)=>`\\`${p1}\\``);\n\n  // bold (**text**) → *text*\n  s = s.replace(/\\*\\*([^*]+)\\*\\*/g, '*$1*');\n\n  // italic (_text_) → giữ nguyên\n\n  // underline & strike → bỏ\n  s = s.replace(/__([^_]+)__/g, '$1');\n  s = s.replace(/~~([^~]+)~~/g, '$1');\n\n  // headers → bold\n  s = s.replace(/^(#{1,6})\\s+(.+)$/gm, (m, hashes, content)=>`*${content.trim()}*`);\n\n  // list markers → bullet list Messenger\n  s = s.replace(/^[\\-\\*\\+]\\s+(.+)$/gm, '* $1');\n\n  // links → giữ text\n  s = s.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (m,txt,url)=>txt);\n\n  return s.trim();\n}\n\n/* ---------- 2) HTML → Facebook Markdown ---------- */\nfunction htmlToFbMarkdown(input){\n  let s = input;\n\n  s = s.replace(/<br\\s*\\/?>/gi, '\\n');\n\n  // headers → bold\n  s = s.replace(/<h[1-6][^>]*>([\\s\\S]*?)<\\/h[1-6]>/gi, (m, inner)=>`*${inner.trim()}*`);\n\n  // bold / italic\n  s = s.replace(/<\\/?strong[^>]*>/gi, '*');\n  s = s.replace(/<\\/?b[^>]*>/gi, '*');\n  s = s.replace(/<\\/?em[^>]*>/gi, '_');\n  s = s.replace(/<\\/?i[^>]*>/gi, '_');\n\n  // paragraphs/divs → newline\n  s = s.replace(/<\\/?(p|div)[^>]*>/gi, '\\n');\n\n  // lists → bullet\n  s = s.replace(/<li[^>]*>/gi, '* ').replace(/<\\/li>/gi, '\\n');\n  s = s.replace(/<\\/?(ul|ol)[^>]*>/gi, '');\n\n  // remove all other tags\n  s = s.replace(/<\\/?[^>]+>/g, '');\n\n  return s.trim();\n}\n\n/* ---------- 3) Normalize content ---------- */\nfunction normalizeToFacebookMarkdown(input){\n  const looksLikeMd = /(^|\\s)[*_`~]|^#{1,6}\\s|```/.test(input);\n  let s = looksLikeMd ? mdToFacebook(input) : htmlToFbMarkdown(input);\n\n  // collapse nhiều newline thành 1\n  s = s.replace(/\\n{3,}/g, '\\n\\n');\n\n  // xoá ký tự \"\\\" thừa còn sót\n  s = s.replace(/\\\\+/g, '');\n\n  return s.trim();\n}\n\n/* ---------- 4) Split by newlines (smart split) ---------- */\nfunction splitMarkdownSmart(text, maxLen) {\n  const lines = text.split('\\n');\n  const chunks = [];\n  let buffer = '';\n\n  for (const line of lines) {\n    if ((buffer + line + '\\n').length > maxLen) {\n      if (buffer.trim()) chunks.push(buffer.trim());\n      buffer = line + '\\n';\n    } else {\n      buffer += line + '\\n';\n    }\n  }\n\n  if (buffer.trim()) chunks.push(buffer.trim());\n\n  return chunks.map(c => c.replace(/\\n+$/,''));\n}\n\n/* ===== Run ===== */\nconst normalized = normalizeToFacebookMarkdown(text);\nconst chunks = splitMarkdownSmart(normalized, MAX_LEN);\n\nreturn chunks.map(c => ({ json: { text: c } }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "633ae695-402b-4ce5-b303-5e7403dc7ce4",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        1008
      ],
      "parameters": {
        "color": 5,
        "width": 848,
        "height": 1264,
        "content": "## 📥 Facebook Webhook 与初始消息预处理"
      },
      "typeVersion": 1
    },
    {
      "id": "7a2d3e40-921b-4f3e-b744-6de691988fb1",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        1008
      ],
      "parameters": {
        "color": 4,
        "width": 1184,
        "height": 1264,
        "content": "## 🗃️ 消息批处理与历史聚合(n8n数据表)"
      },
      "typeVersion": 1
    },
    {
      "id": "7b74805b-56d7-42dd-9f86-e00fac90f0cc",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        1008
      ],
      "parameters": {
        "color": 5,
        "width": 976,
        "height": 1264,
        "content": "## 🧠 AI处理与增强交互(LLM与AI Agent节点)"
      },
      "typeVersion": 1
    },
    {
      "id": "b3c91dc3-d19b-4f7d-9677-2f34a578590e",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        1008
      ],
      "parameters": {
        "color": 4,
        "width": 624,
        "height": 1264,
        "content": "## 📤 交付响应与更新批处理状态(完成批次)"
      },
      "typeVersion": 1
    },
    {
      "id": "ac913ab6-1fb1-4abf-bae0-9d7a7db5fbb3",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        240
      ],
      "parameters": {
        "color": 2,
        "width": 848,
        "height": 736,
        "content": "## 🛠️ Facebook应用与Messenger Webhook设置指南"
      },
      "typeVersion": 1
    },
    {
      "id": "536f5f3e-6a86-46a8-a215-edb22a977173",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        240
      ],
      "parameters": {
        "color": 2,
        "width": 624,
        "height": 736,
        "content": "## 📑 数据表设置:Batch_messages"
      },
      "typeVersion": 1
    },
    {
      "id": "452fdb7f-16d2-4a8a-be73-07764edff67a",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        240
      ],
      "parameters": {
        "color": 3,
        "width": 2192,
        "height": 736,
        "content": "## 📝 Facebook消息聊天机器人 - 使用n8n数据表实现智能批处理、格式化与通知 - Nguyen Thieu Toan"
      },
      "typeVersion": 1
    },
    {
      "id": "a921c1dc-41b2-4c38-9e84-c6f08539c1e7",
      "name": "获取最大ID + 合并消息",
      "type": "n8n-nodes-base.code",
      "position": [
        1984,
        1840
      ],
      "parameters": {
        "jsCode": "// Lấy danh sách input\nconst inputItems = items;\n\n// Nếu danh sách rỗng, trả về rỗng\nif (inputItems.length === 0) {\n  return [];\n}\n\n// Sắp xếp theo id tăng dần\nconst sortedItems = [...inputItems].sort((a, b) => a.json.id - b.json.id);\n\n// Tạo merged_message từ các user_text không null\nconst mergedMessage = sortedItems\n  .map(item => item.json.user_text)\n  .filter(text => text !== null && text !== undefined)\n  .join(' ');\n\n// Tìm item có id lớn nhất\nlet maxItem = sortedItems[sortedItems.length - 1];\n\n// Thêm các trường vào item lớn nhất\nmaxItem.json.merged_message = mergedMessage;\n// Trả về item có id lớn nhất kèm merged_message và history\nreturn [maxItem];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ee91ce2f-72fa-4db4-93cd-cfcfab96b8b2",
      "name": "获取历史消息",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2736,
        1888
      ],
      "parameters": {
        "limit": 10,
        "filters": {
          "conditions": [
            {
              "keyName": "user_id",
              "keyValue": "={{ $('Set Context').item.json.user_id }}"
            },
            {
              "keyName": "processed",
              "condition": "isTrue"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "nXPDtd1UiwqvIoh8",
          "cachedResultUrl": "/projects/mYtIzVb8cWfhFOhJ/datatables/nXPDtd1UiwqvIoh8",
          "cachedResultName": "Batch_messages"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "b6229500-13d6-4c68-864b-74dba5be32ee",
      "name": "合并历史",
      "type": "n8n-nodes-base.code",
      "position": [
        2912,
        1888
      ],
      "parameters": {
        "jsCode": "// Lấy danh sách input\nconst inputItems = items;\n\n// Nếu danh sách rỗng, trả về rỗng\nif (inputItems.length === 0) {\n  return [];\n}\n\n// Sắp xếp theo id tăng dần\nconst sortedItems = [...inputItems].sort((a, b) => a.json.id - b.json.id);\n\n// Tạo lịch sử chat gồm từng lượt chat user-bot riêng biệt\nconst historyArray = sortedItems.map(item => {\n  const userText = item.json.user_text;\n  const botRep = item.json.bot_rep;\n  const entries = [];\n\n  if (userText !== null && userText !== undefined) {\n    entries.push({ role: 'user', text: userText });\n  }\n  if (botRep !== null && botRep !== undefined) {\n    entries.push({ role: 'bot', text: botRep });\n  }\n\n  return entries; // array of {role, text}\n}).flat(); // làm phẳng mảng lồng nhau\n\n// Bọc toàn bộ vào một trường history\nreturn [\n  {\n    json: {\n      history: historyArray\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "a5b3d1ad-e827-48ad-8dbc-9d67e651e392",
      "name": "Groq 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        3152,
        2112
      ],
      "parameters": {
        "model": "groq/compound",
        "options": {}
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Wait 3s": {
      "main": [
        [
          {
            "node": "Get unprocessed message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Text": {
      "main": [
        [
          {
            "node": "Update Page Rep",
            "type": "main",
            "index": 0
          },
          {
            "node": "Update FALSE to TRUE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Max ID?": {
      "main": [
        [
          {
            "node": "Send Typing",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get history message",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Is message?": {
      "main": [
        [
          {
            "node": "Is from page?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Typing": {
      "main": [
        []
      ]
    },
    "Set Context": {
      "main": [
        [
          {
            "node": "Insert To Process",
            "type": "main",
            "index": 0
          },
          {
            "node": "Seen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is from page?": {
      "main": [
        [],
        [
          {
            "node": "Set Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge History": {
      "main": [
        [
          {
            "node": "Process Merged Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Process Merged Message",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "Update Page Rep": {
      "main": [
        []
      ]
    },
    "Facebook Webhook": {
      "main": [
        [
          {
            "node": "Confirm Webhook",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Is message?",
            "type": "main",
            "index": 0
          },
          {
            "node": "Confirm Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert To Process": {
      "main": [
        [
          {
            "node": "Wait 3s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get history message": {
      "main": [
        [
          {
            "node": "Merge History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Merged Message": {
      "main": [
        [
          {
            "node": "Format for Facebook Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get unprocessed message": {
      "main": [
        [
          {
            "node": "Get Max ID + Merged Mess",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Max ID + Merged Mess": {
      "main": [
        [
          {
            "node": "Is Max ID?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Process Merged Message",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Format for Facebook Output": {
      "main": [
        [
          {
            "node": "Send Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 内容创作, 多模态 AI

需要付费吗?

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

工作流信息
难度等级
高级
节点数量28
分类2
节点类型12
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Nguyen Thieu Toan

Nguyen Thieu Toan

@nguyenthieutoan

An AI Automation consultant and system builder specializing in business workflow optimization with n8n. As the Founder of GenStaff, Toan empowers teams to automate complex processes using no-code/low-code tools and AI Agents, making operations smarter and more efficient. He actively shares expertise and tutorials about n8n, AI, and automation on his blog and social channels.

外部链接
在 n8n.io 查看

分享此工作流