{
  "name": "NimbusDesk Support Triage Agent",
  "nodes": [
    {
      "parameters": {
        "content": "01 — Input Layer",
        "height": 704,
        "color": "#523C00"
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -720,
        -64
      ],
      "id": "f5485f24-281e-4691-b82f-637fbc866ba1",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "04 — AI Triage Layer",
        "height": 704,
        "width": 1108,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        224,
        -64
      ],
      "id": "c9916225-513c-4f8b-8c90-6b8365a93fb0",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "05 — Decision + Ticket Creation Layer + Support Email Notification Layer",
        "height": 704,
        "width": 800
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1360,
        -64
      ],
      "id": "5fc50506-572f-484b-a392-e7bc408ac35f",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.3,
      "position": [
        -656,
        240
      ],
      "id": "12b9ff5d-d52a-4822-87e7-38b57f4cd03c",
      "name": "Telegram Trigger - Customer Message",
      "webhookId": "824520db-6844-4a85-a334-088a536ed3fc",
      "credentials": {
        "telegramApi": {
          "id": "y1ArOk5CzpJ1Dlq1",
          "name": "Telegram account 2"
        }
      }
    },
    {
      "parameters": {
        "content": "07 — Customer Reply Layer",
        "height": 704
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2640,
        -64
      ],
      "id": "a9c4cb10-3284-483e-8ef7-c91003f4f5dd",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU",
          "mode": "list",
          "cachedResultName": "NimbusDesk Support Triage Agent",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Tickets",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "ticket_id": "={{ $('Prepare Decision').item.json.ticket_id }}",
            "created_at": "={{ $now.toISO() }}",
            "customer_name": "={{ $('Prepare Decision').item.json.customer_name }}",
            "customer_email": "={{ $('Prepare Decision').item.json.customer_email }}",
            "category": "={{ $('Prepare Decision').item.json.category }}",
            "urgency": "={{ $('Prepare Decision').item.json.urgency }}",
            "sentiment": "={{ $('Prepare Decision').item.json.sentiment }}",
            "issue_summary": "={{ $('Prepare Decision').item.json.issue_summary }}",
            "status": "needs_human_review",
            "needs_human_approval": "={{ $('Prepare Decision').item.json.needs_human_approval }}",
            "recommended_action": "={{ $('Prepare Decision').item.json.recommended_action }}",
            "raw_message": "={{ $('Prepare Decision').item.json.raw_message }}",
            "channel": "={{ $('Prepare Decision').item.json.channel }}",
            "sender_id": "={{ $('Prepare Decision').item.json.sender_id }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "ticket_id",
              "displayName": "ticket_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "displayName": "customer_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_email",
              "displayName": "customer_email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "displayName": "category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "urgency",
              "displayName": "urgency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "sentiment",
              "displayName": "sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_summary",
              "displayName": "issue_summary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "needs_human_approval",
              "displayName": "needs_human_approval",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "recommended_action",
              "displayName": "recommended_action",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "draft_reply",
              "displayName": "draft_reply",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "raw_message",
              "displayName": "raw_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "channel",
              "displayName": "channel",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "displayName": "sender_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "=RAW"
        }
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1392,
        96
      ],
      "id": "07563a04-d4be-4dfc-90fa-9a66e4f6e8e1",
      "name": "Google Sheets - Create Ticket",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "MsVFmAVYyUqJgPHu",
          "name": "Google Sheets OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "content": "08 — Logging Layer",
        "height": 704,
        "width": 288,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2912,
        -64
      ],
      "id": "76d45f80-863d-47c6-8ecc-ff8f78128350",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU",
          "mode": "list",
          "cachedResultName": "NimbusDesk Support Triage Agent",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 880447108,
          "mode": "list",
          "cachedResultName": "Conversation_Log",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit#gid=880447108"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "ticket_id": "={{ $('Prepare Decision').item.json.ticket_id }}",
            "log_id": "={{ \"LOG-\" + $now.toMillis() }}",
            "timestamp": "={{ $now.toISO() }}",
            "step_name": "={{ $('Prepare Decision').item.json.reply_type }}",
            "channel": "={{ $('Prepare Decision').item.json.channel }}",
            "sender_id": "={{ $('Prepare Decision').item.json.sender_id }}",
            "customer_name": "={{ $('Prepare Decision').item.json.customer_name }}",
            "customer_email": "={{ $('Prepare Decision').item.json.customer_email }}",
            "category": "={{ $('Prepare Decision').item.json.category }}",
            "urgency": "={{ $('Prepare Decision').item.json.urgency }}",
            "needs_human_approval": "={{ $('Prepare Decision').item.json.needs_human_approval }}",
            "action_taken": "={{ $('Prepare Decision').item.json.reply_type === 'ticket_confirmation' ? 'Ticket created, support email sent, and customer notified' : $('Prepare Decision').item.json.reply_type === 'existing_ticket' ? 'Existing ticket update sent to customer' : $('Prepare Decision').item.json.reply_type === 'missing_info' ? 'Requested missing customer information' : 'Safe direct reply sent to customer' }}",
            "message_text": "={{ $('Prepare Decision').item.json.raw_message }}",
            "reply_text": "={{ ($('AI - Reply Writer').item.json.output?.[0]?.content?.[0]?.text || $('AI - Reply Writer').item.json.message?.content || $('AI - Reply Writer').item.json.text || $('AI - Reply Writer').item.json.output || \"\").trim() }}",
            "ticket_status": "={{ $('Prepare Decision').item.json.status }}",
            "node_name": "Google Sheets - Conversation Log",
            "notes": "={{ $('Prepare Decision').item.json.reply_type === 'ticket_confirmation' ? 'Gmail support notification was sent before customer confirmation.' : 'No new support email was required for this branch.' }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "log_id",
              "displayName": "log_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "ticket_id",
              "displayName": "ticket_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "displayName": "timestamp",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "step_name",
              "displayName": "step_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "channel",
              "displayName": "channel",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "displayName": "sender_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "displayName": "customer_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_email",
              "displayName": "customer_email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "displayName": "category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "urgency",
              "displayName": "urgency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "needs_human_approval",
              "displayName": "needs_human_approval",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "action_taken",
              "displayName": "action_taken",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "message_text",
              "displayName": "message_text",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "reply_text",
              "displayName": "reply_text",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "ticket_status",
              "displayName": "ticket_status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "node_name",
              "displayName": "node_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "displayName": "error_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "notes",
              "displayName": "notes",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "=RAW"
        }
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        2992,
        208
      ],
      "id": "e53d9773-0c32-4fae-91a8-c547fd5404c8",
      "name": "Google Sheets - Conversation Log",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "MsVFmAVYyUqJgPHu",
          "name": "Google Sheets OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU",
          "mode": "list",
          "cachedResultName": "NimbusDesk Support Triage Agent",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 846559905,
          "mode": "list",
          "cachedResultName": "User_State",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit#gid=846559905"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "sender_id",
              "lookupValue": "={{ $('Normalize Message').item.json.sender_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -144,
        240
      ],
      "id": "a463d1b7-9785-4e2f-bc7b-363006227824",
      "name": "Google Sheets - Lookup User State",
      "alwaysOutputData": true,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "MsVFmAVYyUqJgPHu",
          "name": "Google Sheets OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "content": "03 — Memory Layer",
        "height": 704,
        "width": 374,
        "color": "#126B00"
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -192,
        -64
      ],
      "id": "548fbede-6eea-49db-9384-d9411efcae7f",
      "name": "Sticky Note6"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e424e049-63ba-48d9-b4c1-ad0400115646",
              "name": "existing_customer_name",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.customer_name || \"\" }}",
              "type": "string"
            },
            {
              "id": "8878767d-faef-424a-8709-c359f8eb7224",
              "name": "existing_customer_email",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.customer_email || \"\" }}",
              "type": "string"
            },
            {
              "id": "5059d21e-7437-414d-9048-deb515a61f40",
              "name": "existing_issue_summary",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.issue_summary || \"\" }}",
              "type": "string"
            },
            {
              "id": "1608f3f9-a3ef-4da0-9390-16c569f305b3",
              "name": "existing_category",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.category || \"\" }}",
              "type": "string"
            },
            {
              "id": "9bd78954-9897-49c2-bbbf-b8a389d1d59b",
              "name": "existing_urgency",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.urgency || \"\" }}",
              "type": "string"
            },
            {
              "id": "31a322d9-3241-4eb2-990d-fbfc43247f4d",
              "name": "existing_sentiment",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.sentiment || \"\" }}",
              "type": "string"
            },
            {
              "id": "abd807b1-39da-4097-858c-e34a4dc03f2d",
              "name": "existing_needs_human_approval",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.needs_human_approval || \"\" }}",
              "type": "string"
            },
            {
              "id": "43b35707-3ca1-415a-becd-057866361c7c",
              "name": "existing_draft_reply",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.draft_reply || \"\" }}",
              "type": "string"
            },
            {
              "id": "9d122515-6a3e-426d-9a15-80301976484d",
              "name": "existing_ticket_id",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.ticket_id || \"\" }}",
              "type": "string"
            },
            {
              "id": "49689557-9106-4951-95fc-6aae9713704d",
              "name": "existing_status",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.status || \"\" }}",
              "type": "string"
            },
            {
              "id": "4496d61a-0fb6-4842-8dfb-745c46b0a3c4",
              "name": "existing_raw_message_history",
              "value": "={{ $('Google Sheets - Lookup User State').item.json.raw_message_history || \"\" }}",
              "type": "string"
            },
            {
              "id": "67c6b593-f7d1-43ab-be6b-312c0ec02539",
              "name": "current_raw_message",
              "value": "={{ $('Normalize Message').item.json.raw_message }}",
              "type": "string"
            },
            {
              "id": "f0a4c275-ce9e-4884-a411-4d51f552dfc8",
              "name": "sender_id",
              "value": "={{ $('Normalize Message').item.json.sender_id }}",
              "type": "string"
            },
            {
              "id": "02413f1b-eff9-4da9-b7d8-0010911cb703",
              "name": "memory_exists",
              "value": "={{ !!$('Google Sheets - Lookup User State').item.json.sender_id }}",
              "type": "boolean"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        48,
        240
      ],
      "id": "03eb8802-8e7f-46cf-b20d-a8f872e1827f",
      "name": "Prepare Memory Context"
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU",
          "mode": "list",
          "cachedResultName": "NimbusDesk Support Triage Agent",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 846559905,
          "mode": "list",
          "cachedResultName": "User_State",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit#gid=846559905"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "sender_id": "={{ $('Prepare Decision').item.json.sender_id }}",
            "last_seen_at": "={{ $('Prepare Decision').item.json.last_seen_at }}",
            "customer_name": "={{ $('Prepare Decision').item.json.customer_name }}",
            "customer_email": "={{ $('Prepare Decision').item.json.customer_email }}",
            "issue_summary": "={{ $('Prepare Decision').item.json.issue_summary }}",
            "category": "={{ $('Prepare Decision').item.json.category }}",
            "urgency": "={{ $('Prepare Decision').item.json.urgency }}",
            "sentiment": "={{ $('Prepare Decision').item.json.sentiment }}",
            "needs_human_approval": "={{ $('Prepare Decision').item.json.needs_human_approval }}",
            "missing_fields": "={{ $('Prepare Decision').item.json.missing_fields }}",
            "next_expected_field": "={{ $('Prepare Decision').item.json.next_expected_field }}",
            "status": "={{ $('Prepare Decision').item.json.status }}",
            "ticket_id": "={{ $('Prepare Decision').item.json.ticket_id }}",
            "last_user_message": "={{ $('Prepare Decision').item.json.last_user_message }}",
            "raw_message_history": "={{ ($('Prepare Memory Context').item.json.existing_raw_message_history ? $('Prepare Memory Context').item.json.existing_raw_message_history + \" || \" : \"\") + $('Prepare Decision').item.json.raw_message }}"
          },
          "matchingColumns": [
            "sender_id"
          ],
          "schema": [
            {
              "id": "sender_id",
              "displayName": "sender_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "last_seen_at",
              "displayName": "last_seen_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "displayName": "customer_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_email",
              "displayName": "customer_email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_summary",
              "displayName": "issue_summary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "displayName": "category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "urgency",
              "displayName": "urgency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "sentiment",
              "displayName": "sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "needs_human_approval",
              "displayName": "needs_human_approval",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "draft_reply",
              "displayName": "draft_reply",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "missing_fields",
              "displayName": "missing_fields",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "next_expected_field",
              "displayName": "next_expected_field",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "ticket_id",
              "displayName": "ticket_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "last_user_message",
              "displayName": "last_user_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "raw_message_history",
              "displayName": "raw_message_history",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "=RAW"
        }
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        864,
        256
      ],
      "id": "fa4d7434-05cd-46ea-9256-e537cb61b948",
      "name": "Google Sheets - Upsert User State",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "MsVFmAVYyUqJgPHu",
          "name": "Google Sheets OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU",
          "mode": "list",
          "cachedResultName": "NimbusDesk Support Triage Agent",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 846559905,
          "mode": "list",
          "cachedResultName": "User_State",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19Eynn3-LrnPQTzwZgtM1Z4FjALzNMex6IkqW2P94izU/edit#gid=846559905"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "sender_id": "={{ $('Prepare Decision').item.json.sender_id }}",
            "last_seen_at": "={{ $now.toISO() }}",
            "ticket_id": "={{ $('Prepare Decision').item.json.ticket_id }}",
            "status": "ticket_created"
          },
          "matchingColumns": [
            "sender_id"
          ],
          "schema": [
            {
              "id": "sender_id",
              "displayName": "sender_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "last_seen_at",
              "displayName": "last_seen_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "displayName": "customer_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "customer_email",
              "displayName": "customer_email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_summary",
              "displayName": "issue_summary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "displayName": "category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "urgency",
              "displayName": "urgency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "sentiment",
              "displayName": "sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "needs_human_approval",
              "displayName": "needs_human_approval",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "draft_reply",
              "displayName": "draft_reply",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "missing_fields",
              "displayName": "missing_fields",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "next_expected_field",
              "displayName": "next_expected_field",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "ticket_id",
              "displayName": "ticket_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "last_user_message",
              "displayName": "last_user_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "raw_message_history",
              "displayName": "raw_message_history",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1968,
        96
      ],
      "id": "2c6ddfe9-3390-41fc-88f7-481b53b654ad",
      "name": "Google Sheets - Upsert User State - Mark Ticket Created",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "MsVFmAVYyUqJgPHu",
          "name": "Google Sheets OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "51477f09-039c-46ea-8f86-ce577ab6ebeb",
              "name": "raw_message",
              "value": "={{ $json.message.text || $json.message.caption || \"\" }}",
              "type": "string"
            },
            {
              "id": "c2d49224-e576-484e-949a-3947d574200e",
              "name": "channel",
              "value": "=telegram",
              "type": "string"
            },
            {
              "id": "489c793b-1dc3-4f75-b291-c5ed053d50cc",
              "name": "sender_id",
              "value": "={{ $json.message.chat.id }}",
              "type": "string"
            },
            {
              "id": "3c0557fa-d34b-44b1-806b-8f67f1c88677",
              "name": "received_at",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            },
            {
              "id": "e3c7b430-4bbd-40ca-97c4-ec0210978f99",
              "name": "source_node",
              "value": "Telegram Trigger - Customer Message",
              "type": "string"
            },
            {
              "id": "789a8ced-51a2-4473-a030-9315e6acf99a",
              "name": "telegram_message_id",
              "value": "={{ $json.message.message_id }}",
              "type": "string"
            },
            {
              "id": "8f58969a-73d7-4d19-80c2-7b59880842f2",
              "name": "telegram_user_id",
              "value": "={{ $json.message.from.id }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -400,
        240
      ],
      "id": "c34b80ac-5a20-4093-9d28-260c418debe7",
      "name": "Normalize Message"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4O-MINI"
        },
        "responses": {
          "values": [
            {
              "content": "=You are the triage engine for NimbusDesk customer support.\n\nYou do TWO jobs in one pass:\n1. Extract structured fields from the customer's CURRENT Telegram message only.\n2. Classify the message for support triage.\n\nThis is a STATELESS extraction. Do not guess, carry over, or invent any value not explicitly present in THIS message. Previous customer information is stored separately and merged later by the system.\n\nCurrent customer message:\n{{ $('Normalize Message').item.json.raw_message }}\n\nReturn ONLY valid JSON matching the schema. No markdown. No explanation.\n\nExtraction rules:\n- If a field is not explicitly stated in THIS message, return an empty string \"\".\n- Never fabricate a name, email, issue, or product.\n- If an email like alex@test.com appears, copy it exactly into customer_email.\n- Keep issue_summary short, factual, and based only on this message.\n- Do not use previous memory here. The system will merge memory later.\n\nClassification rules:\n- category must be exactly one of: Billing, Refund, Technical Support, Sales, Account Access, General Question.\n- If the message mentions charged twice, double charged, refund, invoice, payment, subscription, plan price, card, billing, or money issue, set category to \"Billing\".\n- If the message is mainly asking about refund status, refund request, refund eligibility, or money back, set category to \"Refund\" unless it is clearly about a billing charge issue.\n- If the message mentions login, password, account locked, verification, access, or cannot enter account, set category to \"Account Access\".\n- If the message mentions bug, error, not working, broken feature, app issue, website issue, or technical problem, set category to \"Technical Support\".\n- If the message asks about pricing, plans, discounts, annual billing, product availability, or buying, set category to \"Sales\".\n- If the message is unclear or just a greeting, set category to \"General Question\".\n\nUrgency rules:\n- urgency must be one of: low, medium, high.\n- Use \"high\" for urgent language like today, now, immediately, angry tone, money loss, account locked, repeated failure, or business-impacting issue.\n- Use \"medium\" for normal support requests.\n- Use \"low\" for simple general questions.\n\nSentiment rules:\n- sentiment must be one of: positive, neutral, negative, angry.\n- Use \"angry\" only for clear frustration, blame, rude language, repeated complaint, or strong urgency.\n- Use \"negative\" for concern, confusion, disappointment, or complaint without anger.\n- Use \"neutral\" for normal factual messages.\n- Use \"positive\" only when the customer is clearly happy or appreciative.\n\nHuman approval rules:\n- Set needs_human_approval to true for Billing, Refund, Account Access, angry tone, high urgency, money issue, cancellation, deletion, payment issue, refund request, or sensitive account action.\n- Set needs_human_approval to false for safe Sales and safe General Question messages.\n- When unsure, prefer true if the issue could affect money, account access, customer trust, or sensitive data.\n\nRecommended action rules:\n- For billing/refund/account access/sensitive issues, recommend creating a support ticket and sending it to human review.\n- Never recommend initiating, approving, confirming, or processing a refund.\n- Never recommend account deletion or account changes without human review.\n- For safe questions, recommend answering directly.\n\nDo NOT write a customer-facing reply here."
            }
          ]
        },
        "builtInTools": {},
        "options": {
          "maxTokens": 700,
          "textFormat": {
            "textOptions": {
              "type": "json_schema",
              "schema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"customer_name\": {\n      \"type\": \"string\"\n    },\n    \"customer_email\": {\n      \"type\": \"string\"\n    },\n    \"issue_summary\": {\n      \"type\": \"string\"\n    },\n    \"mentioned_product\": {\n      \"type\": \"string\"\n    },\n    \"category\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Billing\",\n        \"Refund\",\n        \"Technical Support\",\n        \"Sales\",\n        \"Account Access\",\n        \"General Question\"\n      ]\n    },\n    \"urgency\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"low\",\n        \"medium\",\n        \"high\"\n      ]\n    },\n    \"sentiment\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"positive\",\n        \"neutral\",\n        \"negative\",\n        \"angry\"\n      ]\n    },\n    \"needs_human_approval\": {\n      \"type\": \"boolean\"\n    },\n    \"recommended_action\": {\n      \"type\": \"string\"\n    }\n  },\n  \"required\": [\n    \"customer_name\",\n    \"customer_email\",\n    \"issue_summary\",\n    \"mentioned_product\",\n    \"category\",\n    \"urgency\",\n    \"sentiment\",\n    \"needs_human_approval\",\n    \"recommended_action\"\n  ],\n  \"additionalProperties\": false\n}",
              "strict": "={{ true }}"
            }
          },
          "temperature": 0,
          "topP": 1
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.3,
      "position": [
        272,
        256
      ],
      "id": "66261466-22e2-44ad-9ab5-93d455daa0f4",
      "name": "AI - Triage",
      "credentials": {
        "openAiApi": {
          "id": "6juJ2FE7TERex92K",
          "name": "OpenAI account 2"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// ===== Helper: safely read AI JSON/text output =====\nfunction getAiText(nodeName) {\n  const data = $(nodeName).item.json;\n  if (data.output?.[0]?.content?.[0]?.text !== undefined) return data.output[0].content[0].text;\n  if (typeof data.output === \"string\") return data.output;\n  if (typeof data.text === \"string\") return data.text;\n  if (typeof data.message === \"string\") return data.message;\n  return \"\";\n}\n\nfunction parseJsonMaybe(value, fallback = {}) {\n  if (!value) return fallback;\n  if (typeof value === \"object\") return value;\n  if (typeof value === \"string\") {\n    try {\n      return JSON.parse(value);\n    } catch (e) {\n      return fallback;\n    }\n  }\n  return fallback;\n}\n\n// ===== Inputs =====\nconst norm = $(\"Normalize Message\").item.json;\nconst mem = $(\"Prepare Memory Context\").item.json;\nconst ai = parseJsonMaybe(getAiText(\"AI - Triage\"), {});\n\nconst raw = String(norm.raw_message || \"\");\n\n// ===== Email fallback from current message =====\nconst emailRegex = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/i;\nconst newEmail = String(ai.customer_email || (raw.match(emailRegex) || [\"\"])[0])\n  .replace(/[.,;:!?]+$/, \"\")\n  .trim();\n\n// ===== MERGE: new value wins, else existing memory =====\nconst customer_name = String(ai.customer_name || mem.existing_customer_name || \"\").trim();\nconst customer_email = String(newEmail || mem.existing_customer_email || \"\").trim();\nconst issue_summary = String(ai.issue_summary || mem.existing_issue_summary || \"\").trim();\n\n// ===== Classification: current if new issue, else memory, else safe default =====\nconst hasNewIssue = Boolean(ai.issue_summary && String(ai.issue_summary).trim());\n\nconst category = String(\n  hasNewIssue\n    ? (ai.category || mem.existing_category || \"General Question\")\n    : (mem.existing_category || ai.category || \"General Question\")\n).trim();\n\nconst urgency = String(\n  hasNewIssue\n    ? (ai.urgency || mem.existing_urgency || \"medium\")\n    : (mem.existing_urgency || ai.urgency || \"medium\")\n).trim();\n\nconst sentiment = String(\n  hasNewIssue\n    ? (ai.sentiment || mem.existing_sentiment || \"neutral\")\n    : (mem.existing_sentiment || ai.sentiment || \"neutral\")\n).trim();\n\n// ===== Sticky approval: once true, stays true =====\nconst needs_human_approval =\n  ai.needs_human_approval === true ||\n  String(mem.existing_needs_human_approval || \"\").toLowerCase() === \"true\";\n\n// ===== Missing check on MERGED data =====\nconst missing = [];\nif (!customer_name) missing.push(\"customer_name\");\nif (!customer_email) missing.push(\"customer_email\");\nif (!issue_summary) missing.push(\"issue_summary\");\n\nconst missing_required_info = missing.length > 0;\nconst next_expected_field = missing[0] || \"none\";\n\n// ===== Ticket id reuse =====\nconst ticket_id = mem.existing_ticket_id || \"TKT-\" + Date.now();\nconst ticket_already_created = String(mem.existing_status || \"\") === \"ticket_created\";\n\n// ===== Status =====\nlet status;\n\nif (ticket_already_created) {\n  status = \"ticket_created\";\n} else if (missing_required_info) {\n  status =\n    \"waiting_for_\" +\n    (next_expected_field === \"customer_name\"\n      ? \"name\"\n      : next_expected_field === \"customer_email\"\n      ? \"email\"\n      : \"issue\");\n} else {\n  status = \"ready_for_ticket\";\n}\n\n// ===== Deterministic reply_type =====\nlet reply_type;\n\nif (ticket_already_created) {\n  reply_type = \"existing_ticket\";\n} else if (missing_required_info) {\n  reply_type = \"missing_info\";\n} else if (needs_human_approval) {\n  reply_type = \"ticket_confirmation\";\n} else {\n  reply_type = \"safe_reply\";\n}\n\n// ===== Output =====\nreturn {\n  json: {\n    sender_id: norm.sender_id,\n    channel: norm.channel,\n    telegram_message_id: norm.telegram_message_id,\n    raw_message: raw,\n\n    customer_name,\n    customer_email,\n    issue_summary,\n    mentioned_product: String(ai.mentioned_product || \"\").trim(),\n\n    category,\n    urgency,\n    sentiment,\n    needs_human_approval,\n    recommended_action: String(ai.recommended_action || \"\").trim(),\n\n    missing_required_info,\n    missing_fields: missing.join(\", \"),\n    next_expected_field,\n\n    ticket_id,\n    ticket_already_created,\n    status,\n    reply_type,\n\n    last_user_message: raw,\n    last_seen_at: new Date().toISOString()\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        640,
        256
      ],
      "id": "487da13c-446d-411b-8e8e-f0b7eae4222a",
      "name": "Prepare Decision"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Prepare Decision').item.json.reply_type }}",
                    "rightValue": "ticket_confirmation",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "29266667-6424-4cf3-900c-0738cdeb4bad"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "ticket_confirmation"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "a5714980-a667-4250-9dee-d7f591569350",
                    "leftValue": "={{ $('Prepare Decision').item.json.reply_type }}",
                    "rightValue": "existing_ticket",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "existing_ticket"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "ddc05d45-a936-4b8f-99dc-db6ab5c6af2e",
                    "leftValue": "={{ $('Prepare Decision').item.json.reply_type }}",
                    "rightValue": "missing_info",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "missing_info"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "e022f57b-ed05-4797-9910-e7dacbad9413",
                    "leftValue": "={{ $('Prepare Decision').item.json.reply_type }}",
                    "rightValue": "safe_reply",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "safe_reply"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        1072,
        256
      ],
      "id": "64414fc2-f302-47a7-90cd-f32a61316fb4",
      "name": "Switch - reply_type"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "283586cc-4df7-4a54-a535-083164a1d0ee",
              "name": "chat_id",
              "value": "={{ $('Normalize Message').item.json.sender_id }}",
              "type": "string"
            },
            {
              "id": "1e388fb8-90c1-46d9-9434-1d633aecde9f",
              "name": "reply_type",
              "value": "={{ $('Prepare Decision').item.json.reply_type }}",
              "type": "string"
            },
            {
              "id": "b5b52814-4a35-4899-8512-fd719f81fe3c",
              "name": "ticket_id",
              "value": "={{ $('Prepare Decision').item.json.ticket_id }}",
              "type": "string"
            },
            {
              "id": "3142a5e2-5dab-46fb-a006-26a467b2d390",
              "name": "customer_name",
              "value": "={{ $('Prepare Decision').item.json.customer_name }}",
              "type": "string"
            },
            {
              "id": "34e5ff32-9bda-4dd1-9d86-8c4e6196aeb6",
              "name": "missing_fields",
              "value": "={{ $('Prepare Decision').item.json.missing_fields }}",
              "type": "string"
            },
            {
              "id": "2a962953-a78f-43c7-8cfe-d6940a53a8b2",
              "name": "issue_summary",
              "value": "={{ $('Prepare Decision').item.json.issue_summary }}",
              "type": "string"
            },
            {
              "id": "d3694a61-5a02-4e60-92e1-f2ee31c3d823",
              "name": "category",
              "value": "={{ $('Prepare Decision').item.json.category }}",
              "type": "string"
            },
            {
              "id": "c061be96-dde2-436b-8f1b-1d31e7a07cb0",
              "name": "last_user_message",
              "value": "={{ $('Prepare Decision').item.json.last_user_message }}",
              "type": "string"
            },
            {
              "id": "667e51c6-961c-41fa-9459-95bf1414dd96",
              "name": "kb_context",
              "value": "",
              "type": "string"
            },
            {
              "id": "93602e24-f0a1-40a7-9593-c89a7eb45448",
              "name": "urgency",
              "value": "={{ $('Prepare Decision').item.json.urgency }}",
              "type": "string"
            },
            {
              "id": "dc270cd5-7beb-4aa6-866c-dd31755dcd2d",
              "name": "=sentiment",
              "value": "={{ $('Prepare Decision').item.json.sentiment }}",
              "type": "string"
            },
            {
              "id": "86615c83-a3dd-4e31-a1d4-6e48d25e96df",
              "name": "needs_human_approval",
              "value": "={{ $('Prepare Decision').item.json.needs_human_approval }}",
              "type": "string"
            },
            {
              "id": "fccaf9bd-61b2-455b-8dfa-b86b1400adc5",
              "name": "customer_email",
              "value": "={{ $('Prepare Decision').item.json.customer_email }}",
              "type": "string"
            },
            {
              "id": "ee0ec42b-b666-4372-b1f8-6d2ad21a65aa",
              "name": "recommended_action",
              "value": "={{ $('Prepare Decision').item.json.recommended_action }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": "={{ true }}",
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2000,
        400
      ],
      "id": "14330f87-7d67-4ef5-b517-b44a9c94d104",
      "name": "Prepare Reply Context"
    },
    {
      "parameters": {
        "chatId": "={{ $('Prepare Reply Context').item.json.chat_id }}",
        "text": "={{ ($('AI - Reply Writer').item.json.output?.[0]?.content?.[0]?.text || $('AI - Reply Writer').item.json.message?.content || $('AI - Reply Writer').item.json.text || $('AI - Reply Writer').item.json.output || \"\").trim() || $('Prepare Reply Context').item.json.fallback_reply }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2704,
        240
      ],
      "id": "91979169-30e8-4150-8d54-7c01ecbd7ea7",
      "name": "Telegram - Send Reply",
      "webhookId": "26cedfef-61f5-4007-9982-e11fdbfa471a",
      "credentials": {
        "telegramApi": {
          "id": "y1ArOk5CzpJ1Dlq1",
          "name": "Telegram account 2"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a035e191-34c9-4b87-8fe4-f4ced9dbf1ce",
              "name": "support_to",
              "value": "={{ $('Prepare Decision').item.json.customer_email }}",
              "type": "string"
            },
            {
              "id": "66a0c5c8-813a-4392-9698-0d9d7633bac5",
              "name": "email_subject",
              "value": "={{ \"[NimbusDesk] \" + $('Prepare Decision').item.json.urgency.toUpperCase() + \" \" + $('Prepare Decision').item.json.category + \" Ticket - \" + $('Prepare Decision').item.json.ticket_id }}",
              "type": "string"
            },
            {
              "id": "108e9dc8-f23d-4cae-9edb-a822ba4f491c",
              "name": "email_html",
              "value": "=={{ `\n<div style=\"font-family: Arial, sans-serif; background:#f6f7f9; padding:24px;\">\n  <div style=\"max-width:720px; margin:0 auto; background:#ffffff; border:1px solid #e5e7eb; border-radius:12px; overflow:hidden;\">\n    \n    <div style=\"background:#111827; color:#ffffff; padding:20px 24px;\">\n      <h2 style=\"margin:0; font-size:20px;\">New NimbusDesk Support Ticket</h2>\n      <p style=\"margin:6px 0 0; color:#d1d5db;\">A customer issue needs review.</p>\n    </div>\n\n    <div style=\"padding:24px;\">\n      <table style=\"width:100%; border-collapse:collapse; font-size:14px;\">\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Ticket ID</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.ticket_id}</td>\n        </tr>\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Customer Name</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.customer_name}</td>\n        </tr>\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Customer Email</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.customer_email}</td>\n        </tr>\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Category</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.category}</td>\n        </tr>\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Urgency</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.urgency}</td>\n        </tr>\n        <tr>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb; font-weight:bold;\">Sentiment</td>\n          <td style=\"padding:10px; border-bottom:1px solid #e5e7eb;\">${$('Prepare Decision').item.json.sentiment}</td>\n        </tr>\n      </table>\n\n      <div style=\"margin-top:22px;\">\n        <h3 style=\"margin:0 0 8px; font-size:16px;\">Issue Summary</h3>\n        <p style=\"background:#f9fafb; border:1px solid #e5e7eb; padding:14px; border-radius:8px; margin:0;\">\n          ${$('Prepare Decision').item.json.issue_summary}\n        </p>\n      </div>\n\n      <div style=\"margin-top:22px;\">\n        <h3 style=\"margin:0 0 8px; font-size:16px;\">Raw Customer Message</h3>\n        <p style=\"background:#fff7ed; border:1px solid #fed7aa; padding:14px; border-radius:8px; margin:0;\">\n          ${$('Prepare Decision').item.json.raw_message}\n        </p>\n      </div>\n\n      <div style=\"margin-top:22px;\">\n        <h3 style=\"margin:0 0 8px; font-size:16px;\">Recommended Action</h3>\n        <p style=\"background:#ecfdf5; border:1px solid #a7f3d0; padding:14px; border-radius:8px; margin:0;\">\n          ${$('Prepare Decision').item.json.recommended_action}\n        </p>\n      </div>\n\n      <p style=\"margin-top:24px; color:#6b7280; font-size:13px;\">\n        Generated by NimbusDesk Support Triage Agent.\n      </p>\n    </div>\n  </div>\n</div>\n` }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1584,
        96
      ],
      "id": "23f94c50-ac65-4edf-ac8e-9fc98d9b1ec2",
      "name": "Prepare Support Email"
    },
    {
      "parameters": {
        "sendTo": "={{ $json.support_to }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        1792,
        96
      ],
      "id": "5ebb0165-fa74-4cb1-883d-472ea53a5b70",
      "name": "Gmail - Send Support Ticket",
      "webhookId": "5fd7d472-bea3-4262-b402-7b22a31a191f",
      "credentials": {
        "gmailOAuth2": {
          "id": "JJODTtvPWID3luMS",
          "name": "Gmail OAuth2 API"
        }
      }
    },
    {
      "parameters": {
        "content": "06 — Reply Writer Layer",
        "height": 704,
        "width": 384,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2208,
        -64
      ],
      "id": "f924934b-b23f-4aa0-8edc-d91b004bf749",
      "name": "06 — Reply Writer Layer"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4.1-mini",
          "mode": "list",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "responses": {
          "values": [
            {
              "content": "=Write the final Telegram customer reply.\n\nData:\nreply_type: {{ $json.reply_type }}\ncustomer_name: {{ $json.customer_name }}\ncustomer_email: {{ $json.customer_email }}\nticket_id: {{ $json.ticket_id }}\nmissing_fields: {{ $json.missing_fields }}\nissue_summary: {{ $json.issue_summary }}\ncategory: {{ $json.category }}\nurgency: {{ $json.urgency }}\nsentiment: {{ $json.sentiment }}\nneeds_human_approval: {{ $json.needs_human_approval }}\nrecommended_action: {{ $json.recommended_action }}\nlast_user_message: {{ $json.last_user_message }}\nkb_context: {{ $json.kb_context }}\n\nBefore writing, silently decide:\n1. Is the customer frustrated, angry, or urgent?\n2. What is the safest promise I can make?\n3. Which branch should I follow?\n4. How can I make this sound like a real human support rep?\n\nOutput only the final reply."
            },
            {
              "role": "system",
              "content": "=You are a senior human customer support representative for NimbusDesk.\n\nYour job is to write ONE final Telegram reply to the customer based on the provided decision data.\n\nYou are not an AI assistant. You are not explaining the workflow. You are writing as a real support person.\n\nCORE STYLE\n- Sound natural, calm, and human.\n- Use short Telegram-friendly sentences.\n- Show empathy in the first line when the customer is frustrated.\n- Be specific to the customer's issue.\n- Do not sound like a generic template.\n- Do not over-apologize.\n- Do not use corporate phrases like “we value your patience” too often.\n- Do not say “I wanted to let you know.”\n- Do not say “your inquiry update request.”\n- Do not repeat the same sentence structure every time.\n\nEMOTION RULES\n- If sentiment is angry, start by acknowledging frustration directly.\n- If sentiment is negative, acknowledge the inconvenience clearly.\n- If urgency is high, sound serious and responsive.\n- If the customer asks for “refund right now,” “fix this now,” or sounds angry, do NOT sound casual.\n- For billing/refund/payment/account issues, never promise a refund, reversal, cancellation, or resolution.\n- Say the support team will review the details and update the customer here.\n\nBRANCH RULES\n\nreply_type = ticket_confirmation:\nCreate a warm confirmation.\nMention the ticket ID.\nMention the actual issue naturally.\nTell them the support team will review it.\nDo not promise the refund or resolution.\n\nreply_type = existing_ticket:\nDo not create a new ticket.\nTell them their existing ticket is already with the support team.\nMention the ticket ID.\nAcknowledge that they are asking for an update.\nDo not sound repetitive.\nDo not say “thank you for your patience” every time.\n\nreply_type = missing_info:\nAsk only for the missing fields.\nDo not say ticket is created.\nKeep it short and clear.\n\nreply_type = safe_reply:\nAnswer only from kb_context.\nIf kb_context is empty, say the team can check and follow up.\n\nABSOLUTE RULES\n- Never mention AI, bot, automation, workflow, backend, JSON, category, urgency, or sentiment.\n- Never promise refund, reversal, account change, deletion, cancellation, or exact resolution time.\n- Never say “resolved.”\n- Never ask for information already provided.\n- Never invent policy, price, SLA, refund rules, or support hours.\n- Never use “dear,” “buddy,” “kindly revert,” “ASAP,” or “hang tight.”\n- Output only the final Telegram message."
            }
          ]
        },
        "builtInTools": {},
        "options": {
          "maxTokens": 300,
          "textFormat": {
            "textOptions": {
              "type": "text"
            }
          },
          "temperature": "={{ 0.75 }}",
          "topP": 1
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.3,
      "position": [
        2288,
        240
      ],
      "id": "bf1562fd-5a3c-45c1-ab4e-c8e3f487b20c",
      "name": "AI - Reply Writer",
      "credentials": {
        "openAiApi": {
          "id": "6juJ2FE7TERex92K",
          "name": "OpenAI account 2"
        }
      }
    },
    {
      "parameters": {
        "content": "\n",
        "height": 704,
        "color": "#523C00"
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -464,
        -64
      ],
      "id": "c07e5a5b-6629-41ca-935a-332ad6d03455",
      "name": "Sticky Note1"
    }
  ],
  "pinData": {},
  "connections": {
    "Telegram Trigger - Customer Message": {
      "main": [
        [
          {
            "node": "Normalize Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Create Ticket": {
      "main": [
        [
          {
            "node": "Prepare Support Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Lookup User State": {
      "main": [
        [
          {
            "node": "Prepare Memory Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Memory Context": {
      "main": [
        [
          {
            "node": "AI - Triage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Upsert User State": {
      "main": [
        [
          {
            "node": "Switch - reply_type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Upsert User State - Mark Ticket Created": {
      "main": [
        [
          {
            "node": "Prepare Reply Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Message": {
      "main": [
        [
          {
            "node": "Google Sheets - Lookup User State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Triage": {
      "main": [
        [
          {
            "node": "Prepare Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Decision": {
      "main": [
        [
          {
            "node": "Google Sheets - Upsert User State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch - reply_type": {
      "main": [
        [
          {
            "node": "Google Sheets - Create Ticket",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Reply Context",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Reply Context",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Reply Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Reply Context": {
      "main": [
        [
          {
            "node": "AI - Reply Writer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram - Send Reply": {
      "main": [
        [
          {
            "node": "Google Sheets - Conversation Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Conversation Log": {
      "main": [
        []
      ]
    },
    "Prepare Support Email": {
      "main": [
        [
          {
            "node": "Gmail - Send Support Ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail - Send Support Ticket": {
      "main": [
        [
          {
            "node": "Google Sheets - Upsert User State - Mark Ticket Created",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Reply Writer": {
      "main": [
        [
          {
            "node": "Telegram - Send Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "aec3f775-e8a7-4ac1-a06e-3e20bdad625e",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "c28bde5122526a5c236bced52c68a8afe69f4c11db36584ddc15290564be04b6"
  },
  "nodeGroups": [],
  "id": "AG1kZEl3TSluAyuX",
  "tags": []
}