{
  "name": "Tự trả lời bình luận Fanpage",
  "nodes": [
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "loai",
              "name": "loai",
              "value": "={{ $json.value?.item ?? $json.changes?.[0]?.value?.item ?? $json.entry?.[0]?.changes?.[0]?.value?.item ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "hanh_dong",
              "name": "hanh_dong",
              "value": "={{ $json.value?.verb ?? $json.changes?.[0]?.value?.verb ?? $json.entry?.[0]?.changes?.[0]?.value?.verb ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "comment_id",
              "name": "comment_id",
              "value": "={{ $json.value?.comment_id ?? $json.changes?.[0]?.value?.comment_id ?? $json.entry?.[0]?.changes?.[0]?.value?.comment_id ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "post_id",
              "name": "post_id",
              "value": "={{ $json.value?.post_id ?? $json.changes?.[0]?.value?.post_id ?? $json.entry?.[0]?.changes?.[0]?.value?.post_id ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "nguoi_id",
              "name": "nguoi_id",
              "value": "={{ $json.value?.from?.id ?? $json.changes?.[0]?.value?.from?.id ?? $json.entry?.[0]?.changes?.[0]?.value?.from?.id ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "nguoi_ten",
              "name": "nguoi_ten",
              "value": "={{ $json.value?.from?.name ?? $json.changes?.[0]?.value?.from?.name ?? $json.entry?.[0]?.changes?.[0]?.value?.from?.name ?? \"bạn\" }}",
              "type": "string"
            },
            {
              "id": "noi_dung",
              "name": "noi_dung",
              "value": "={{ $json.value?.message ?? $json.changes?.[0]?.value?.message ?? $json.entry?.[0]?.changes?.[0]?.value?.message ?? \"\" }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "ff69f27f-6381-4180-8d4c-c20338f2669a",
      "name": "Chuẩn hóa bình luận",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        256,
        272
      ],
      "notes": "Payload webhook của Facebook lồng nhiều tầng khác nhau tùy trường hợp, nên đọc theo nhiều đường rồi lấy đường nào có dữ liệu."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{ $json.loai }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "comment",
              "id": "78d69ff6-a6c0-44df-a5c3-08f7dc842470"
            },
            {
              "leftValue": "={{ $json.hanh_dong }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "add",
              "id": "522f0f4d-9c66-410e-8af9-713c6806cdc3"
            },
            {
              "leftValue": "={{ $json.nguoi_id }}",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "rightValue": "DIEN_PAGE_ID_CUA_BAN",
              "id": "25ddcf92-6642-4267-a49d-cc1fac5e842d"
            },
            {
              "leftValue": "={{ $json.noi_dung }}",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "id": "aca0255f-aca3-4922-95c7-6dc78cb25239"
            },
            {
              "leftValue": "={{ $json.comment_id }}",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "id": "836de56c-5666-4801-948a-34d3daca109f"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "2eab8529-7be8-4541-aa21-03b7aeb9674b",
      "name": "Chỉ giữ bình luận mới của người khác",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        480,
        272
      ],
      "notes": "Chốt chặn vòng lặp: bỏ mọi bình luận do chính Page viết, vì mỗi câu trả lời của hệ thống cũng làm Facebook bắn một sự kiện mới về."
    },
    {
      "parameters": {
        "operation": "rowNotExists",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "DIEN_ID_BANG_CUA_BAN",
          "cachedResultName": "CHON LAI BANG CUA BAN"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "comment_id",
              "keyValue": "={{ $json.comment_id }}"
            }
          ]
        }
      },
      "id": "218536bf-49cc-43d8-a8d8-da35747eb83f",
      "name": "Chưa trả lời bình luận này",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        704,
        272
      ],
      "notes": "Facebook có thể gửi lại cùng một sự kiện. Bảng này bảo đảm mỗi bình luận chỉ được trả lời đúng một lần."
    },
    {
      "parameters": {
        "graphApiVersion": "v23.0",
        "node": "={{ $json.post_id }}",
        "options": {
          "queryParameters": {
            "parameter": [
              {
                "name": "fields",
                "value": "id,message,created_time,permalink_url"
              }
            ]
          }
        }
      },
      "id": "5d64cf51-c563-453c-b644-b73e8c5bedb0",
      "name": "Lấy nội dung bài gốc",
      "type": "n8n-nodes-base.facebookGraphApi",
      "typeVersion": 1,
      "position": [
        928,
        272
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Bài viết gốc trên fanpage:\n\"\"\"\n{{ $(\"Lấy nội dung bài gốc\").item.json.message }}\n\"\"\"\n\nBình luận cần phân loại:\n\"\"\"\n{{ $(\"Chuẩn hóa bình luận\").item.json.noi_dung }}\n\"\"\"",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "Bạn phân loại bình luận trên fanpage. Chọn đúng một nhãn trong sáu nhãn sau:\n\nkhen: khen bài, cảm ơn, đồng tình, không hỏi gì thêm.\nchuyen_mon: hỏi kiến thức, cách làm, công cụ, khái niệm trong bài.\nkhoa_hoc: hỏi sản phẩm hoặc dịch vụ đang bán, giá, lịch, cách đăng ký, hoặc bày tỏ muốn mua và muốn tham gia.\ntieu_cuc: chê bai, phàn nàn, nghi ngờ, châm chọc, tranh cãi.\nspam: quảng cáo dịch vụ khác, rao vặt, link lạ, nội dung không liên quan.\nkhong_ro: không thuộc rõ nhóm nào ở trên, hoặc bạn không chắc.\n\ndo_tin_cay là số từ 0 tới 1 thể hiện mức chắc chắn của bạn. Nếu phân vân thì cho điểm thấp, đừng cố đoán bừa. ly_do viết một câu ngắn bằng tiếng Việt.\n\nGHI CHÚ CHO NGƯỜI DÙNG TEMPLATE: sáu nhãn này là bộ khung. Muốn đổi tên nhãn hay thêm nhãn thì nhớ sửa đồng thời ở ba chỗ: đây, node Chốt nhãn và chế độ, và node Soạn câu trả lời."
            }
          ]
        },
        "batching": {}
      },
      "id": "ed18438c-9dc2-4ca1-8178-62917b92d97a",
      "name": "Phân loại bình luận",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.9,
      "position": [
        1152,
        272
      ]
    },
    {
      "parameters": {
        "modelName": "models/gemini-3.5-flash",
        "options": {
          "temperature": 0
        }
      },
      "id": "61dc4201-4d1f-4223-bc2b-e1fcc981d72e",
      "name": "Model phân loại",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1.1,
      "position": [
        1168,
        496
      ]
    },
    {
      "parameters": {
        "jsonSchemaExample": "{ \"nhan\": \"chuyen_mon\", \"do_tin_cay\": 0.9, \"ly_do\": \"Người này hỏi Skill khác prompt chỗ nào\" }"
      },
      "id": "a4a5ec95-f039-463e-8e04-d8b47d9f50f5",
      "name": "Khuôn nhãn",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        1296,
        496
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "nhan",
              "name": "nhan",
              "value": "={{ $json.output?.nhan ?? $json.nhan ?? \"khong_ro\" }}",
              "type": "string"
            },
            {
              "id": "do_tin_cay",
              "name": "do_tin_cay",
              "value": "={{ Number($json.output?.do_tin_cay ?? $json.do_tin_cay ?? 0) }}",
              "type": "number"
            },
            {
              "id": "ly_do",
              "name": "ly_do",
              "value": "={{ $json.output?.ly_do ?? $json.ly_do ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "che_do",
              "name": "che_do",
              "value": "={{ ($json.output?.nhan ?? $json.nhan ?? \"khong_ro\") === \"spam\" ? \"bo_qua\" : \"duyet\" }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "8b72abe9-6370-4387-973c-ea82fede5d4a",
      "name": "Chốt nhãn và chế độ",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1504,
        272
      ],
      "notes": "Quy tắc bất di bất dịch: độ tin cậy dưới 0.7 thì luôn đẩy sang duyệt, không bao giờ đoán bừa rồi đăng."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{ $json.che_do }}",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "rightValue": "bo_qua",
              "id": "33df8d4d-ee76-466b-9799-ea1566217d93"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "09135a91-9123-4608-9bca-11083ec98c8f",
      "name": "Có đáng trả lời không",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1728,
        272
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Bài viết gốc trên fanpage:\n\"\"\"\n{{ $(\"Lấy nội dung bài gốc\").item.json.message }}\n\"\"\"\n\nNgười bình luận tên: {{ $(\"Chuẩn hóa bình luận\").item.json.nguoi_ten }}\nNhóm bình luận: {{ $(\"Chốt nhãn và chế độ\").item.json.nhan }}\n\nBình luận của họ:\n\"\"\"\n{{ $(\"Chuẩn hóa bình luận\").item.json.noi_dung }}\n\"\"\"\n\nViết câu trả lời của fanpage cho bình luận này. Chỉ xuất ra đúng câu trả lời, không lời dẫn, không dấu ngoặc kép bao ngoài.",
        "messages": {
          "messageValues": [
            {
              "message": "===== PHẦN 1. BẠN TỰ ĐIỀN =====\nThay ba chỗ trong ngoặc vuông bằng thông tin trang của bạn, rồi xóa luôn cặp ngoặc đi.\n\nBạn trả lời bình luận trên fanpage [TÊN TRANG CỦA BẠN], một trang về [CHỦ ĐỀ TRANG NÓI VỀ].\nXưng [CÁCH TRANG TỰ XƯNG, ví dụ: mình], gọi người đọc là bạn.\n\n===== PHẦN 2. GIỌNG VĂN, SỬA THOẢI MÁI =====\nNếu gọi tên thì chỉ gọi TÊN RIÊNG, tức chữ cuối cùng trong họ tên. Ví dụ Nguyễn Văn An thì gọi An. Đừng bao giờ đọc cả họ tên đầy đủ, nghe như đọc danh sách lớp.\nNhiều khi không gọi tên lại tự nhiên hơn, cứ vào thẳng câu trả lời.\nẤm, gọn, đúng chất người thật viết. Từ một tới ba câu.\nTiếng Việt tự nhiên. Tuyệt đối không dùng dấu gạch dài. Chỉ dùng dấu gạch ngang thường khi thật cần.\nTối đa một biểu tượng cảm xúc, và chỉ khi thật sự hợp.\nMỗi câu trả lời phải mở đầu một kiểu khác nhau. Năm người khen mà nhận năm câu giống hệt là lộ ngay ra máy.\n\n===== PHẦN 3. ĐIỀU CẤM TUYỆT ĐỐI, ĐừNG GỠ PHẦN NÀY =====\nMỗi dòng dưới đây đều đổi bằng một lần suýt hỏng thật. Giữ nguyên.\n\nChỉ được nói những gì bài gốc nói rõ. Bài gốc không nhắc tới thứ gì thì đừng nhắc tới thứ đó, dù bạn đoán là đúng.\nKhông nêu giá, ngày tháng, ưu đãi, hay bất kỳ con số nào không có trong bài gốc.\nKhông hứa hẹn thay chủ trang, không cam kết kết quả.\nKhông bịa link, không bịa tên sản phẩm, không bịa tên mục hay tên tệp trong một dự án.\nKhông tranh luận, không mỉa mai, không dạy đời.\nNgười ta hỏi thứ không có trong bài gốc thì mời họ nhắn tin riêng cho trang, đừng tự chế câu trả lời.\n\n===== PHẦN 4. THEO TỪNG NHÓM =====\nkhen: cảm ơn chân thành, thêm một ý ngắn liên quan tới bài.\nchuyen_mon: trả lời thẳng câu hỏi dựa trên bài gốc, dễ hiểu, không thuật ngữ khô.\nkhoa_hoc: cảm ơn sự quan tâm và mời nhắn tin riêng để được hướng dẫn. Không nói giá.\ntieu_cuc: lắng nghe, không cãi, cảm ơn góp ý, mời trao đổi riêng nếu cần.\nkhong_ro: hỏi lại một câu ngắn cho rõ ý họ."
            }
          ]
        },
        "batching": {}
      },
      "id": "3d856d2d-1258-4d5c-8cd0-266a1a32e646",
      "name": "Soạn câu trả lời",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.9,
      "position": [
        1952,
        16
      ]
    },
    {
      "parameters": {
        "modelName": "models/gemini-3.5-flash",
        "options": {
          "maxOutputTokens": 2048,
          "temperature": 0.7
        }
      },
      "id": "940760d1-4724-4be8-aa3d-166864e4f29c",
      "name": "Model soạn câu trả lời",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1.1,
      "position": [
        2032,
        240
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const raw = $input.item.json.text ?? $input.item.json.output ?? '';\nconst traLoi = String(raw).trim().replace(/^[\"'“”]+|[\"'“”]+$/g, '').trim();\nconst loi = [];\nif (!traLoi) loi.push('câu trả lời rỗng');\nif (traLoi.length > 400) loi.push('dài quá 400 ký tự');\nif (/https?:\\/\\//i.test(traLoi)) loi.push('có chèn link');\nif (/[–—]/.test(traLoi)) loi.push('có dấu gạch dài');\nif (/\\d[\\d.,]{4,}/.test(traLoi)) loi.push('có con số giống học phí');\n\n// Chặn câu bị cắt cụt giữa chừng.\n// Model có bước suy nghĩ nên đôi lúc hết ngân sách token trước khi viết xong câu.\n// Bỏ khoảng trắng, ký tự nối emoji và variation selector ở cuối rồi mới xét dấu kết thúc.\nconst cuoi = traLoi.replace(/[️‍\\s]+$/u, '');\nconst ketThucTron = /[.!?…:)\\]\"'”’»]$/u.test(cuoi) || /\\p{Extended_Pictographic}$/u.test(cuoi);\nif (traLoi && !ketThucTron) loi.push('câu bị cắt cụt, không kết thúc trọn vẹn');\n\nreturn { json: { tra_loi: traLoi, an_toan: loi.length === 0, ly_do_chan: loi.join('; ') } };"
      },
      "id": "742c0a4e-4469-4773-9d54-832546c641cb",
      "name": "Cửa kiểm an toàn",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2304,
        128
      ],
      "notes": "Kiểm bằng code chứ không nhờ AI tự giác. Dính bất kỳ lỗi nào thì không đăng tự động mà đẩy sang Telegram cho bạn duyệt."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{ $json.an_toan }}",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "7c520ad2-efa6-435f-a3bd-72018669e732"
            },
            {
              "leftValue": "={{ $(\"Chốt nhãn và chế độ\").item.json.che_do }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "tu_dong",
              "id": "ab1a645b-a253-4e9f-b7b1-a1cac93a88b0"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "a13eb0a4-cab9-4972-a5da-e6c9d106f144",
      "name": "Được đăng thẳng không",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2528,
        128
      ]
    },
    {
      "parameters": {
        "httpRequestMethod": "POST",
        "graphApiVersion": "v23.0",
        "node": "={{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}",
        "edge": "comments",
        "options": {
          "queryParameters": {
            "parameter": [
              {
                "name": "message",
                "value": "={{ $(\"Cửa kiểm an toàn\").first().json.tra_loi }}"
              }
            ]
          }
        }
      },
      "id": "b3f92a01-88ef-4c54-b378-5b1cd5cc4625",
      "name": "Đăng câu trả lời lên Facebook",
      "type": "n8n-nodes-base.facebookGraphApi",
      "typeVersion": 1,
      "position": [
        3200,
        0
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "DIEN_ID_BANG_CUA_BAN",
          "cachedResultName": "CHON LAI BANG CUA BAN"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "comment_id": "={{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}",
            "post_id": "={{ $(\"Chuẩn hóa bình luận\").first().json.post_id }}",
            "nguoi_binh_luan": "={{ $(\"Chuẩn hóa bình luận\").first().json.nguoi_ten }}",
            "noi_dung": "={{ $(\"Chuẩn hóa bình luận\").first().json.noi_dung }}",
            "nhan": "={{ $(\"Chốt nhãn và chế độ\").first().json.nhan }}",
            "trang_thai": "={{ $json.id ? \"da_dang\" : \"loi_khi_dang\" }}",
            "cau_tra_loi": "={{ $(\"Cửa kiểm an toàn\").first().json.tra_loi }}"
          },
          "schema": [
            {
              "id": "comment_id",
              "displayName": "comment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "post_id",
              "displayName": "post_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nguoi_binh_luan",
              "displayName": "nguoi_binh_luan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "noi_dung",
              "displayName": "noi_dung",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nhan",
              "displayName": "nhan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "trang_thai",
              "displayName": "trang_thai",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "cau_tra_loi",
              "displayName": "cau_tra_loi",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "id": "dbab1424-6c49-4a7a-935d-8bbd663c3c1d",
      "name": "Ghi nhận đã đăng",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        3424,
        0
      ]
    },
    {
      "parameters": {
        "chatId": "DIEN_CHAT_ID_TELEGRAM_CUA_BAN",
        "text": "=<b>Bình luận cần duyệt</b>\n\n<b>Người bình luận:</b> {{ $(\"Chuẩn hóa bình luận\").first().json.nguoi_ten }}\n<b>Nhóm:</b> {{ $(\"Chốt nhãn và chế độ\").first().json.nhan }} ({{ $(\"Chốt nhãn và chế độ\").first().json.do_tin_cay }})\n<b>Lý do phải duyệt:</b> {{ $(\"Cửa kiểm an toàn\").first().json.ly_do_chan || $(\"Chốt nhãn và chế độ\").first().json.ly_do }}\n\n<b>Họ viết:</b>\n{{ $(\"Chuẩn hóa bình luận\").first().json.noi_dung }}\n\n<b>Bản nháp trả lời:</b>\n{{ $(\"Cửa kiểm an toàn\").first().json.tra_loi }}",
        "replyMarkup": "inlineKeyboard",
        "inlineKeyboard": {
          "rows": [
            {
              "row": {
                "buttons": [
                  {
                    "text": "Đăng",
                    "additionalFields": {
                      "callback_data": "=dang|{{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}"
                    }
                  },
                  {
                    "text": "Sửa",
                    "additionalFields": {
                      "callback_data": "=sua|{{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}"
                    }
                  },
                  {
                    "text": "Bỏ qua",
                    "additionalFields": {
                      "callback_data": "=bo|{{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}"
                    }
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "appendAttribution": false,
          "disable_web_page_preview": true,
          "parse_mode": "HTML"
        }
      },
      "id": "eea6f0d4-e16f-413a-b080-1ccc5d617c91",
      "name": "Gửi bạn duyệt qua Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        3200,
        224
      ],
      "webhookId": "833b2022-66a9-454b-a557-ff5e9187e59c",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "DIEN_ID_BANG_CUA_BAN",
          "cachedResultName": "CHON LAI BANG CUA BAN"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "comment_id": "={{ $(\"Chuẩn hóa bình luận\").first().json.comment_id }}",
            "post_id": "={{ $(\"Chuẩn hóa bình luận\").first().json.post_id }}",
            "nguoi_binh_luan": "={{ $(\"Chuẩn hóa bình luận\").first().json.nguoi_ten }}",
            "noi_dung": "={{ $(\"Chuẩn hóa bình luận\").first().json.noi_dung }}",
            "nhan": "={{ $(\"Chốt nhãn và chế độ\").first().json.nhan }}",
            "trang_thai": "cho_duyet",
            "cau_tra_loi": "={{ $(\"Cửa kiểm an toàn\").first().json.tra_loi }}"
          },
          "schema": [
            {
              "id": "comment_id",
              "displayName": "comment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "post_id",
              "displayName": "post_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nguoi_binh_luan",
              "displayName": "nguoi_binh_luan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "noi_dung",
              "displayName": "noi_dung",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nhan",
              "displayName": "nhan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "trang_thai",
              "displayName": "trang_thai",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "cau_tra_loi",
              "displayName": "cau_tra_loi",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "id": "3310b162-e733-49c9-ae95-7781d8f0c60e",
      "name": "Ghi nhận chờ duyệt",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        3424,
        224
      ]
    },
    {
      "parameters": {
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "DIEN_ID_BANG_CUA_BAN",
          "cachedResultName": "CHON LAI BANG CUA BAN"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "comment_id": "={{ $(\"Chuẩn hóa bình luận\").item.json.comment_id }}",
            "post_id": "={{ $(\"Chuẩn hóa bình luận\").item.json.post_id }}",
            "nguoi_binh_luan": "={{ $(\"Chuẩn hóa bình luận\").item.json.nguoi_ten }}",
            "noi_dung": "={{ $(\"Chuẩn hóa bình luận\").item.json.noi_dung }}",
            "nhan": "={{ $json.nhan }}",
            "trang_thai": "bo_qua",
            "cau_tra_loi": ""
          },
          "schema": [
            {
              "id": "comment_id",
              "displayName": "comment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "post_id",
              "displayName": "post_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nguoi_binh_luan",
              "displayName": "nguoi_binh_luan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "noi_dung",
              "displayName": "noi_dung",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "nhan",
              "displayName": "nhan",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "trang_thai",
              "displayName": "trang_thai",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "cau_tra_loi",
              "displayName": "cau_tra_loi",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "id": "5620358c-96a1-4050-a1f0-4557c75a9c86",
      "name": "Ghi nhận bỏ qua",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        2016,
        416
      ]
    },
    {
      "parameters": {
        "content": "### Cửa vào, và bốn bước bên Meta\nFacebook bắn sự kiện về đây mỗi khi fanpage có hoạt động mới.\n\n**Bốn việc phải làm tay, n8n không tự làm hộ:**\n\n**1.** Đưa ứng dụng sang chế độ Live. Để Development thì Meta chỉ gửi sự kiện thử bấm tay, không gửi bình luận thật, kể cả bình luận của chính bạn. Muốn chuyển Live thì phải điền trước Privacy Policy URL, User data deletion, và Category.\n\n**2.** Đăng ký Callback URL trong mục Webhooks, chọn product là Page. Dùng địa chỉ **Production** của node này. Verify token điền chính App Access Token.\n\n**3.** Bật Subscribe cho trường **feed**. Xong bước 2 mà quên bước này thì coi như chưa đăng ký.\n\n**4.** Gọi `POST /me/subscribed_apps?subscribed_fields=feed` bằng **Page token** để gắn ứng dụng vào đúng trang. Đây là bước bị quên nhiều nhất vì nó không nằm trong giao diện bấm nút.\n\n**Cả bốn bước hỏng theo cùng một kiểu: im lặng.** Không báo lỗi, chỉ là không có gì chạy về. Nên khi im lặng, soát đủ bốn, đừng chỉ soát một.",
        "height": 460,
        "width": 380,
        "color": 4
      },
      "id": "e5acb481-a2a6-494d-beeb-7ffceaac1b79",
      "name": "Sticky Note 2c604c98",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -64,
        32
      ]
    },
    {
      "parameters": {
        "content": "## ĐỪNG GỠ\n### Chốt chặn vòng lặp\n\nMỗi câu trả lời hệ thống đăng lên cũng làm Facebook bắn một sự kiện mới về cho chính nó.\n\nNode bên dưới lọc bỏ bình luận do chính Page viết. Đây là thứ duy nhất chặn vòng lặp đó.\n\nGỡ ra hoặc điền sai Page ID thì hệ thống tự trả lời chính mình, không dừng cho tới khi bạn tắt đi.\n\nBất kỳ hệ thống nào vừa nghe vừa nói ở cùng một chỗ đều cần một chốt như thế.",
        "height": 300,
        "width": 300,
        "color": 3
      },
      "id": "7ab9fcbf-cdfe-4cf5-922e-53baec60e766",
      "name": "Sticky Note df8b7430",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        400,
        32
      ]
    },
    {
      "parameters": {
        "content": "## ĐỪNG GỠ\n### Cửa kiểm an toàn\n\nCâu trả lời phải qua cửa kiểm bằng code trước khi được đăng. Rỗng, dài quá, có link, có dấu gạch dài, có con số giống giá tiền, hoặc câu bị cắt cụt giữa chừng thì chuyển sang cho bạn duyệt.\n\nKiểm bằng code chứ không nhờ AI tự giác, vì code chạy lần nào cũng như nhau còn AI thì có ngày hứng lên nói khác.\n\n**Cửa này chỉ bắt được lỗi về hình thức.** Nó KHÔNG bắt được một câu trôi chảy đúng giọng mà sai sự thật. Đó là lý do nhóm nào sai mà tốn uy tín thì luôn phải có người đọc.\n\nCâu bị chặn không bị vứt đi, nó rẽ sang Telegram.",
        "height": 360,
        "width": 320,
        "color": 3
      },
      "id": "7d8e695c-4dc3-4ccf-90ac-e5e5125fc808",
      "name": "Sticky Note f803bb40",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2224,
        -128
      ]
    },
    {
      "parameters": {
        "appId": "DIEN_APP_ID_CUA_BAN",
        "object": "page",
        "fields": [
          "feed"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.facebookTrigger",
      "typeVersion": 1,
      "position": [
        32,
        272
      ],
      "id": "71ae52ee-3f04-4f19-b2b5-e70e60af468c",
      "name": "Facebook Trigger",
      "webhookId": "3d110e08-aca1-458b-a76e-10265dbc13e4"
    },
    {
      "parameters": {
        "content": "## ĐANG Ở NẤC MỘT: CHẠY KHAN\n\nFile mẫu giao tới tay bạn ở nấc an toàn nhất: **không câu nào tự đăng**. Spam thì bỏ qua, mọi câu còn lại đều qua Telegram cho bạn duyệt tay.\n\nCứ ở nấc này cho tới khi bạn bấm Đăng mà không phải sửa câu chữ nữa.\n\n### NỚI VAN LÊN NẤC HAI\nSửa biểu thức `che_do` trong node **Chốt nhãn và chế độ** thành:\n\n`{{ ($json.output?.nhan ?? $json.nhan ?? \"khong_ro\") === \"spam\" ? \"bo_qua\" : ( Number($json.output?.do_tin_cay ?? $json.do_tin_cay ?? 0) >= 0.7 && [\"khen\", \"chuyen_mon\"].includes($json.output?.nhan ?? $json.nhan) ? \"tu_dong\" : \"duyet\" ) }}`\n\nKhi đó chỉ nhãn khen và chuyen_mon với độ tin cậy từ 0.7 mới được đi thẳng. Nhóm nhạy cảm vẫn về tay bạn.\n\n**Lần đầu nới van, mở fanpage nhìn tận mắt câu tự đăng đầu tiên.** Đường duyệt tay chạy được không có nghĩa đường tự đăng cũng chạy được, vì hai đường đi qua các node khác nhau.",
        "height": 420,
        "width": 380,
        "color": 5
      },
      "id": "9fcea95c-1a11-4fa1-80a3-f9303225de3d",
      "name": "Sticky chế độ chạy thật",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1424,
        480
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "DIEN_ID_BANG_CUA_BAN",
          "cachedResultName": "CHON LAI BANG CUA BAN"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "updatedAt",
              "condition": "gte",
              "keyValue": "={{ $now.minus({ hours: 1 }).toISO() }}"
            }
          ]
        },
        "returnAll": true
      },
      "id": "92015058-1de1-40a7-bba1-5c27222eef64",
      "name": "Đếm câu đã đăng trong 1 giờ",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        2752,
        48
      ],
      "alwaysOutputData": true,
      "onError": "continueRegularOutput",
      "notes": "Đọc mọi dòng được cập nhật trong một giờ gần nhất. Việc lọc ra dòng nào thật sự đã đăng để ở node sau, vì bộ lọc của Data Table chỉ ghép điều kiện bằng AND."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ $(\"Đếm câu đã đăng trong 1 giờ\").all().filter(r => [\"da_dang\", \"da_dang_ban_sua\"].includes(r.json.trang_thai)).length }}",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "rightValue": 10
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "aace8dd8-4aff-49a9-b079-d34d739075f7",
      "name": "Còn dưới trần mỗi giờ",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2976,
        48
      ],
      "notes": "Trần đặt ở 10 câu mỗi giờ. Muốn đổi thì sửa con số 10 ngay trong điều kiện này."
    },
    {
      "parameters": {
        "content": "### Trần 10 câu tự đăng mỗi giờ\n\nĐếm các dòng trong bảng được cập nhật trong một giờ gần nhất, rồi giữ lại dòng có trạng thái da_dang hoặc da_dang_ban_sua.\n\nPhải làm hai bước vì bộ lọc của Data Table chỉ ghép điều kiện bằng AND, không có OR.\n\nVượt trần thì bình luận KHÔNG bị bỏ. Nó chuyển sang Telegram cho bạn duyệt tay, nên bài đông bình luận vẫn được trả lời đủ, chỉ là có người đọc trước.\n\nĐổi trần thì sửa số 10 trong node Còn dưới trần mỗi giờ.\n\nTrần này chưa có tác dụng khi còn ở nấc chạy khan, vì chưa câu nào đi đường tự đăng.",
        "height": 340,
        "width": 320,
        "color": 6
      },
      "id": "adb8758f-1392-4556-b068-dfe8d36bee00",
      "name": "Sticky trần mỗi giờ",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2624,
        -144
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ $json.trang_thai }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "loi_khi_dang"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "f8891356-0962-453a-a317-79395b6ad52f",
      "name": "Đăng có hỏng không",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3168,
        16
      ],
      "notes": "Đọc chính dòng vừa ghi vào bảng. Chỉ nhánh hỏng đi tiếp, đăng được thì dừng ở đây và không làm phiền bạn."
    },
    {
      "parameters": {
        "chatId": "DIEN_CHAT_ID_TELEGRAM_CUA_BAN",
        "text": "=<b>Tự đăng HỎNG</b>\n\nFacebook không nhận câu trả lời này, chưa có gì lên fanpage.\n\n<b>Người bình luận:</b> {{ $json.nguoi_binh_luan }}\n<b>Nhóm:</b> {{ $json.nhan }}\n\n<b>Họ viết:</b>\n{{ $json.noi_dung }}\n\n<b>Câu định đăng:</b>\n{{ $json.cau_tra_loi }}\n\nBấm Đăng để thử lại.",
        "replyMarkup": "inlineKeyboard",
        "inlineKeyboard": {
          "rows": [
            {
              "row": {
                "buttons": [
                  {
                    "text": "Đăng",
                    "additionalFields": {
                      "callback_data": "=dang|{{ $json.comment_id }}"
                    }
                  },
                  {
                    "text": "Sửa",
                    "additionalFields": {
                      "callback_data": "=sua|{{ $json.comment_id }}"
                    }
                  },
                  {
                    "text": "Bỏ qua",
                    "additionalFields": {
                      "callback_data": "=bo|{{ $json.comment_id }}"
                    }
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "appendAttribution": false,
          "disable_web_page_preview": true,
          "parse_mode": "HTML"
        }
      },
      "id": "7645fffc-bdd6-4b85-b59b-5ccb860dee7b",
      "name": "Báo bạn đăng hỏng",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        3392,
        16
      ],
      "webhookId": "8da7eaf3-6fce-4a69-aeda-2d708a5e3072",
      "notes": "Ba nút dùng đúng định dạng callback_data của workflow duyệt, nên bạn bấm Đăng là hệ thống thử đăng lại ngay câu đó."
    },
    {
      "parameters": {
        "content": "# BẮT ĐẦU Ở ĐÂY\n\nWorkflow này đã lắp sẵn toàn bộ luồng chạy. Việc của bạn là cấp quyền và điền chỗ trống.\n\n**Đọc các khối ghi chú theo tiêu đề của chúng:**\n- **BẠN PHẢI ĐIỀN** → chỗ còn bỏ trống, không điền thì không chạy.\n- **ĐỪNG GỠ** → tháo ra là hỏng, mỗi cái đổi bằng một lần sự cố thật.\n- Không có tiền tố → giải thích cho hiểu.\n\n---\n\n### NĂM VIỆC LÀM THEO THỨ TỰ\n\n**1. Tạo bảng lưu.** File này không mang bảng theo được. Tự tạo một Data Table với bảy cột: comment_id, post_id, nguoi_binh_luan, noi_dung, nhan, trang_thai, cau_tra_loi. Rồi chọn lại bảng đó trong MỌI node có nhắc tới bảng.\n\n**2. Khai hai credential Facebook, đừng lẫn.** Một loại App chứa App Access Token và App Secret, cho node nhận tin báo. Một loại thường chứa Page Access Token, cho node đọc bài và node đăng. Page token cần đủ bốn quyền: pages_show_list, pages_manage_metadata, pages_read_engagement, pages_manage_engagement.\n\n**3. Điền các chỗ DIEN_...** Xem các khối BẠN PHẢI ĐIỀN.\n\n**4. Bốn bước bên Meta.** Xem khối ghi chú cạnh node Facebook Trigger. Bỏ sót bước nào cũng dẫn tới cùng một triệu chứng: không có gì chạy về và không báo lỗi gì.\n\n**5. Chạy khan trước.** Xem khối nói về nấc van.",
        "height": 700,
        "width": 520,
        "color": 5
      },
      "id": "1b58728c-075f-44b1-927e-044fc5017920",
      "name": "BẮT ĐẦU Ở ĐÂY",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -64,
        -560
      ]
    },
    {
      "parameters": {
        "content": "## BẠN PHẢI ĐIỀN\n### App ID, ở node Facebook Trigger\n\nÔ App ID đang là `DIEN_APP_ID_CUA_BAN`. Thay bằng mã ứng dụng Meta của bạn.\n\nNode này dùng credential loại **App**, không phải loại thường. Cầm nhầm chìa thì hệ thống nghe được mà không nói được.\n\n**Lưu ý về địa chỉ webhook:** node này cho bạn hai địa chỉ, Test và Production. Đưa cho Meta địa chỉ **Production**. Địa chỉ Test chỉ sống lúc bạn đang bấm chạy thử.",
        "height": 300,
        "width": 300,
        "color": 6
      },
      "id": "379890a8-0632-42a5-969e-cc099defcd6b",
      "name": "BẠN PHẢI ĐIỀN - App ID",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        496,
        -560
      ]
    },
    {
      "parameters": {
        "content": "## BẠN PHẢI ĐIỀN\n### Page ID, ở node bên dưới\n\nĐiều kiện thứ ba trong node lọc đang là `DIEN_PAGE_ID_CUA_BAN`. Thay bằng mã số Fanpage của bạn.\n\nĐây không phải một ô bình thường. Nó chính là chốt chặn không cho hệ thống trả lời chính mình.\n\nĐiền sai hoặc để nguyên thì câu trả lời của chính trang cũng bị coi là bình luận mới, và hệ thống sẽ tự nói chuyện với nó không dừng.",
        "height": 300,
        "width": 300,
        "color": 6
      },
      "id": "9a26f8cf-c004-4793-b012-54387eaa105e",
      "name": "BẠN PHẢI ĐIỀN - Page ID",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        816,
        -560
      ]
    },
    {
      "parameters": {
        "content": "## BẠN PHẢI ĐIỀN\n### Bảng lưu, ở năm node\n\nNăm node trong luồng này có nhắc tới bảng lưu, và tất cả đều đang trỏ vào một bảng không thuộc về bạn. Mở từng node chọn lại bảng bạn vừa tạo.\n\nNăm node đó: Chưa trả lời bình luận này, Ghi nhận đã đăng, Ghi nhận chờ duyệt, Ghi nhận bỏ qua, Đếm câu đã đăng trong 1 giờ.\n\nSót một node là sổ ghi thiếu, và triệu chứng thường thấy là một người nhận mấy câu trả lời giống nhau.",
        "height": 300,
        "width": 300,
        "color": 6
      },
      "id": "947d33e0-8e9b-462b-9593-7a622c907008",
      "name": "BẠN PHẢI ĐIỀN - bảng lưu",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1136,
        -560
      ]
    },
    {
      "parameters": {
        "content": "## BẠN PHẢI ĐIỀN\n### Chat ID Telegram, ở hai node\n\nHai node Telegram đang để `DIEN_CHAT_ID_TELEGRAM_CUA_BAN`. Thay bằng mã cuộc trò chuyện của chính bạn.\n\nNhớ bấm Start với bot trước, chưa bấm thì bot không được phép nhắn cho bạn.\n\nWorkflow duyệt đi kèm còn một ô Chat ID nữa trong trigger, điền luôn để khóa quyền điều khiển. Không điền thì người lạ bấm nút cũng đăng được lên fanpage của bạn.",
        "height": 300,
        "width": 320,
        "color": 6
      },
      "id": "d0c58bd3-6ca4-4f9f-9b3c-c67f37c70aea",
      "name": "BẠN PHẢI ĐIỀN - Chat ID Telegram",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        3168,
        448
      ]
    },
    {
      "parameters": {
        "content": "## ĐỪNG GỠ\n### Ngân sách chữ của model soạn câu\n\nNode model bên cạnh đặt ngân sách chữ rộng hơn nhiều so với độ dài câu trả lời. Đó là cố ý.\n\nModel đời mới có bước suy nghĩ trước khi viết, và phần suy nghĩ ăn chung ngân sách với câu trả lời. Để hẹp thì có lúc model nghĩ hết sạch ngân sách, câu viết ra đứt ngang giữa chừng.\n\nLỗi này không xảy ra đều nên rất dễ tưởng đã chạy tốt.\n\nCâu trả lời không vì ngân sách rộng mà dài ra, vì prompt đã ràng một tới ba câu và cửa kiểm vẫn chặn ở 400 ký tự.\n\nĐổi sang model khác thì nhớ xem lại con số này.",
        "height": 320,
        "width": 320,
        "color": 3
      },
      "id": "d61e3e41-cd30-48ee-892d-55d3ee2fa367",
      "name": "ĐỪNG GỠ - ngân sách chữ của model",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1808,
        480
      ]
    }
  ],
  "connections": {
    "Chuẩn hóa bình luận": {
      "main": [
        [
          {
            "node": "Chỉ giữ bình luận mới của người khác",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chỉ giữ bình luận mới của người khác": {
      "main": [
        [
          {
            "node": "Chưa trả lời bình luận này",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chưa trả lời bình luận này": {
      "main": [
        [
          {
            "node": "Lấy nội dung bài gốc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lấy nội dung bài gốc": {
      "main": [
        [
          {
            "node": "Phân loại bình luận",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Phân loại bình luận": {
      "main": [
        [
          {
            "node": "Chốt nhãn và chế độ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model phân loại": {
      "ai_languageModel": [
        [
          {
            "node": "Phân loại bình luận",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Khuôn nhãn": {
      "ai_outputParser": [
        [
          {
            "node": "Phân loại bình luận",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Chốt nhãn và chế độ": {
      "main": [
        [
          {
            "node": "Có đáng trả lời không",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Có đáng trả lời không": {
      "main": [
        [
          {
            "node": "Soạn câu trả lời",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ghi nhận bỏ qua",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Soạn câu trả lời": {
      "main": [
        [
          {
            "node": "Cửa kiểm an toàn",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model soạn câu trả lời": {
      "ai_languageModel": [
        [
          {
            "node": "Soạn câu trả lời",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Cửa kiểm an toàn": {
      "main": [
        [
          {
            "node": "Được đăng thẳng không",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Được đăng thẳng không": {
      "main": [
        [
          {
            "node": "Đếm câu đã đăng trong 1 giờ",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gửi bạn duyệt qua Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Đăng câu trả lời lên Facebook": {
      "main": [
        [
          {
            "node": "Ghi nhận đã đăng",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Facebook Trigger": {
      "main": [
        [
          {
            "node": "Chuẩn hóa bình luận",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Đếm câu đã đăng trong 1 giờ": {
      "main": [
        [
          {
            "node": "Còn dưới trần mỗi giờ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Còn dưới trần mỗi giờ": {
      "main": [
        [
          {
            "node": "Đăng câu trả lời lên Facebook",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gửi bạn duyệt qua Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ghi nhận đã đăng": {
      "main": [
        [
          {
            "node": "Đăng có hỏng không",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Đăng có hỏng không": {
      "main": [
        [
          {
            "node": "Báo bạn đăng hỏng",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gửi bạn duyệt qua Telegram": {
      "main": [
        [
          {
            "node": "Ghi nhận chờ duyệt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": true
  },
  "nodeGroups": [
    {
      "id": "58640d67-9612-4950-8ae8-b1fa5701f849",
      "name": "1. Nhận và lọc bình luận",
      "nodeIds": [
        "ff69f27f-6381-4180-8d4c-c20338f2669a",
        "2eab8529-7be8-4541-aa21-03b7aeb9674b",
        "218536bf-49cc-43d8-a8d8-da35747eb83f"
      ]
    },
    {
      "id": "e29e3d42-4635-4863-b229-fb6bf2c0bd32",
      "name": "2. Hiểu bối cảnh và phân loại",
      "nodeIds": [
        "5d64cf51-c563-453c-b644-b73e8c5bedb0",
        "ed18438c-9dc2-4ca1-8178-62917b92d97a",
        "61dc4201-4d1f-4223-bc2b-e1fcc981d72e",
        "a4a5ec95-f039-463e-8e04-d8b47d9f50f5",
        "8b72abe9-6370-4387-973c-ea82fede5d4a"
      ]
    },
    {
      "id": "66184527-3952-4831-9c12-49517f918821",
      "name": "3. Soạn câu và cửa kiểm",
      "nodeIds": [
        "3d856d2d-1258-4d5c-8cd0-266a1a32e646",
        "940760d1-4724-4be8-aa3d-166864e4f29c",
        "742c0a4e-4469-4773-9d54-832546c641cb"
      ]
    },
    {
      "id": "4b2fb96c-c322-4fcc-8c0d-56681db3444f",
      "name": "4. Ghi sổ và báo hỏng",
      "nodeIds": [
        "dbab1424-6c49-4a7a-935d-8bbd663c3c1d",
        "f8891356-0962-453a-a317-79395b6ad52f",
        "7645fffc-bdd6-4b85-b59b-5ccb860dee7b"
      ]
    }
  ]
}