AutomationFlowsSlack & Telegram › Route Telegram Customer Complaints with Openai and Google Sheets

Route Telegram Customer Complaints with Openai and Google Sheets

ByRahul Joshi @rahul08 on n8n.io

This workflow handles customer order complaints submitted via Telegram by looking up order details in Google Sheets, using OpenAI to classify message sentiment, and routing each case to auto-approval, support lead review, warehouse investigation, or ops manager escalation, with…

Event trigger★★★★★ complexityAI-powered41 nodesTelegram TriggerGoogle SheetsTelegramOpenAIError TriggerSlack
Slack & Telegram Trigger: Event Nodes: 41 Complexity: ★★★★★ AI nodes: yes Added:
Route Telegram Customer Complaints with Openai and Google Sheets — n8n workflow card showing Telegram Trigger, Google Sheets, Telegram integration

This workflow corresponds to n8n.io template #17287 — we link there as the canonical source.

This workflow follows the Error Trigger → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "MGAUPYNPteFOKuOU",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Customer Complaint Resolution & Smart Escalation System",
  "tags": [],
  "nodes": [
    {
      "id": "c6110434-7570-4b29-abda-4d6e245e74c7",
      "name": "\ud83d\udccc Overview \u2013 How This Workflow Works",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -6112,
        4160
      ],
      "parameters": {
        "color": 2,
        "width": 1272,
        "height": 728,
        "content": "## \ud83d\udce6 ResolveOS AI \u2013 Wrong-Package Complaint Automation\n\n### How it works\nA customer sends a Telegram message with their order ID and complaint. The workflow looks up the order in Google Sheets, checks the customer's complaint history, classifies the message sentiment with GPT-4o-mini, and applies a rule engine to decide one of four routes: auto-approve a replacement (low-value wrong item, first offence), escalate to the support lead (high-value or angry customer), alert the warehouse team (damaged or missing item), or flag to the ops manager (repeat offender). Each route logs a record to the Complaints Log sheet and notifies the relevant person on Telegram. When a support lead approves or rejects via inline button, a second Telegram trigger fires, updates the sheet, and notifies both the customer and warehouse. After an auto-approval, the workflow waits 3 days and sends a feedback request.\n\n### Setup steps\n1. Connect **Telegram Bot API** to all Telegram nodes.\n2. Connect **OpenAI API** to the sentiment classification node.\n3. Connect **Google Sheets OAuth2** and create a sheet with two tabs: `Orders` and `Complaints Log` (see Credentials sticky for column names).\n4. Replace `YOUR_GOOGLE_SHEET_ID` in every Google Sheets node.\n5. Replace `YOUR_SUPPORT_LEAD_CHAT_ID`, `YOUR_WAREHOUSE_CHAT_ID`, and `YOUR_OPS_MANAGER_CHAT_ID` in the respective Telegram notify nodes.\n6. Connect **Slack OAuth2** and replace `YOUR_SLACK_CHANNEL_ID` in the error alert node.\n7. Activate both Telegram triggers."
      },
      "typeVersion": 1
    },
    {
      "id": "3802dbe3-b670-4015-8f77-e0c2b0674064",
      "name": "Section \u2013 Complaint Intake & AI Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4816,
        5024
      ],
      "parameters": {
        "color": 7,
        "width": 1968,
        "height": 572,
        "content": "## \ud83d\udce9 Complaint Intake & AI Analysis\nReceives the customer's Telegram message (format: `ORDER_ID | complaint text`), looks up the order, checks complaint history for repeat behaviour, and uses GPT-4o-mini to classify sentiment. All data is merged before the routing decision."
      },
      "typeVersion": 1
    },
    {
      "id": "44f90028-f1d5-47f4-81b6-b1aa9262bf50",
      "name": "Section \u2013 Rule Engine & Routing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2752,
        4880
      ],
      "parameters": {
        "color": 7,
        "width": 476,
        "height": 716,
        "content": "## \ud83d\udd00 Rule Engine\nCombines issue type, order value, customer sentiment, and repeat-offender flag to decide one of four routes: auto-approve, escalate to support lead, alert warehouse, or flag to ops manager."
      },
      "typeVersion": 1
    },
    {
      "id": "0d25ae60-b5f3-4858-9501-4ecc04e8a46c",
      "name": "Section \u2013 Auto-Approve Branch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2064,
        4224
      ],
      "parameters": {
        "color": 7,
        "width": 1280,
        "height": 492,
        "content": "## \u2705 Auto-Approve Branch\nFor low-value wrong-item complaints from first-time offenders. Instantly logs the resolution, sends the customer a replacement confirmation, then waits 3 days before sending a feedback check-in."
      },
      "typeVersion": 1
    },
    {
      "id": "0a6e06f4-9197-4f51-a9cb-0427a1538843",
      "name": "Section \u2013 Support Lead Escalation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2064,
        4800
      ],
      "parameters": {
        "color": 7,
        "width": 1196,
        "height": 492,
        "content": "## \ud83d\udd34 Support Lead Escalation\nHigh-value orders or angry/frustrated customers go here. Sends the support lead an inline-button Telegram message and logs the complaint as `pending_human_approval`."
      },
      "typeVersion": 1
    },
    {
      "id": "5c4675cf-fe4a-487c-953e-674ca54e2056",
      "name": "Section \u2013 Warehouse Branch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2048,
        5376
      ],
      "parameters": {
        "color": 7,
        "width": 1906,
        "height": 556,
        "content": "## \ud83c\udfed Warehouse Branch\nDamaged or missing items are flagged to the warehouse team with the packer and courier names for CCTV/packing-log review. The workflow then checks if the same packer has 3+ complaints this week and alerts ops if so."
      },
      "typeVersion": 1
    },
    {
      "id": "ae22a9a0-1928-4774-8484-5095fb84c844",
      "name": "Section \u2013 Ops Manager Branch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1856,
        6128
      ],
      "parameters": {
        "color": 7,
        "width": 1052,
        "height": 556,
        "content": "## \ud83d\udd01 Repeat Offender Branch\nCustomers with 3+ complaints this month are blocked from auto-resolution. The ops manager receives a full context alert and the case is logged as `flagged_repeat_offender` for manual review."
      },
      "typeVersion": 1
    },
    {
      "id": "ead99203-acfb-4789-920f-bfa15ea7ec48",
      "name": "Section \u2013 Support Lead Approval Callback",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4544,
        5744
      ],
      "parameters": {
        "color": 7,
        "width": 1636,
        "height": 812,
        "content": "## \ud83d\udc46 Support Lead Approval Callback\nA separate Telegram trigger listens for the support lead's inline-button tap. Approve updates the sheet, notifies the customer and warehouse. Reject logs the decision and tells the support lead to follow up manually."
      },
      "typeVersion": 1
    },
    {
      "id": "c162095f-acfb-4660-b644-6f462d00b7e7",
      "name": "Section \u2013 Error Handling",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4160,
        6672
      ],
      "parameters": {
        "color": 7,
        "width": 684,
        "height": 480,
        "content": "## \u26a0\ufe0f Error Handling\nA workflow-level error trigger posts an alert to Slack whenever any node fails. Update the channel ID to your ops or alerts channel before activating."
      },
      "typeVersion": 1
    },
    {
      "id": "80c3720d-7b87-47f4-bc48-3a8ad5c7c0b5",
      "name": "\ud83d\udd11 Credentials & Sheet Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        5344
      ],
      "parameters": {
        "color": 3,
        "width": 528,
        "height": 584,
        "content": "## \ud83d\udd11 Credentials Required\n- **Telegram Bot API** \u2014 all Telegram nodes\n- **OpenAI API** \u2014 sentiment classification\n- **Google Sheets OAuth2** \u2014 Orders + Complaints Log tabs\n- **Slack OAuth2** \u2014 error alerts\n\n`Orders`: order_id, customer_name, customer_phone, ordered_sku, packed_sku, packer_name, courier_name, order_value\n`Complaints Log`: timestamp, order_id, customer_phone, customer_name, issue_type, route, liability, packer_name, courier_name, status"
      },
      "typeVersion": 1
    },
    {
      "id": "e9bf8936-2c33-42cd-8472-6d9025161b39",
      "name": "Support Lead Approval Callback",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -4352,
        6192
      ],
      "parameters": {
        "updates": [
          "callback_query"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "ecae133d-17d7-4b26-835d-2e3ed9ae6a4c",
      "name": "IF Callback Is Approve",
      "type": "n8n-nodes-base.if",
      "position": [
        -4080,
        6192
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6914a865-dbc2-4f1d-a0bf-0f7046b94cd3",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json.callback_query.data }}",
              "rightValue": "approve_"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "11ce7dcd-c135-4615-9037-1f20844dfc01",
      "name": "Extract Order ID From Callback",
      "type": "n8n-nodes-base.code",
      "position": [
        -3824,
        6080
      ],
      "parameters": {
        "jsCode": "const cb = $json.callback_query.data; // approve_ORD10453 or reject_ORD10453\nconst orderId = cb.split('_').slice(1).join('_');\nreturn [{\n  json: {\n    order_id: orderId,\n    approver_chat_id: $json.callback_query.message.chat.id,\n    approver_message_id: $json.callback_query.message.message_id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "103e286e-3729-4a8c-b7bf-674af9a44c97",
      "name": "Update Row - Mark Approved",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -3552,
        6080
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "approved_by_support_lead.",
            "order_id": "={{ $json.order_id }}",
            "row_number": 0
          },
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "order_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "order_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "customer_phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "customer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "issue_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "route",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "liability",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "liability",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "packer_name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "packer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "courier_name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "courier_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "order_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "438cc839-c058-4a12-8b71-c33d5d45c8dc",
      "name": "Notify Customer - Escalated Resolution Approved",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -3216,
        5920
      ],
      "parameters": {
        "text": "=Good news! Your order issue has been reviewed and approved \u2014 a replacement/refund is on its way. Thanks for your patience! \ud83d\ude4f",
        "chatId": "={{ $('Extract Order ID From Callback').item.json.order_id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "4d8b174c-9fd9-46bb-93fe-86569afddfd5",
      "name": "Notify Warehouse - Flag Packer for Repeat Pattern",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -3232,
        6224
      ],
      "parameters": {
        "text": "=\u2705 Approved by Support Lead \u2014 order {{ $('Extract Order ID From Callback').item.json.order_id }}. Please log this packer's error for pattern tracking.",
        "chatId": "={{ $json.approver_chat_id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "2a0a51c8-6826-4eed-81b6-017d7c2d7a28",
      "name": "Notify Support Lead - Rejected Logged",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -3840,
        6352
      ],
      "parameters": {
        "text": "=Marked as rejected. No resolution sent to customer \u2014 please follow up manually.",
        "chatId": "={{ $json.callback_query.message.chat.id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "687bd2e4-eb91-4241-8fa9-3c2d514001e9",
      "name": "Customer Complaint Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -4592,
        5264
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "e1838274-8148-4f81-b1a2-d83183150001",
      "name": "Normalize Complaint Input",
      "type": "n8n-nodes-base.code",
      "position": [
        -4368,
        5264
      ],
      "parameters": {
        "jsCode": "const msg = $json.message || {};\nconst text = msg.text || '';\nconst parts = text.split('|');\nconst orderId = (parts[0] || '').trim();\nconst messageText = (parts.slice(1).join('|') || '').trim();\nconst fromUser = msg.from || {};\nconst customerName = [fromUser.first_name, fromUser.last_name].filter(Boolean).join(' ') || 'Unknown Customer';\n\nreturn [{\n  json: {\n    order_id: orderId,\n    customer_name: customerName,\n    customer_phone: '',\n    customer_chat_id: String(msg.chat ? msg.chat.id : ''),\n    message_text: messageText,\n    image_url: '',\n    received_at: new Date().toISOString(),\n    support_lead_chat_id: 'YOUR_SUPPORT_LEAD_CHAT_ID',\n    warehouse_chat_id: 'YOUR_WAREHOUSE_CHAT_ID',\n    ops_manager_chat_id: 'YOUR_OPS_MANAGER_CHAT_ID'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "50c6e329-27c1-4f35-9d83-101ce0b5ed7a",
      "name": "Lookup Order Details",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -4160,
        5264
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.order_id }}",
              "lookupColumn": "order_id"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Orders"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "1ded3118-6581-461b-99a2-3470e5668380",
      "name": "Get Customer Complaint History",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -3984,
        5264
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $('Normalize Complaint Input').item.json.customer_phone }}",
              "lookupColumn": "customer_phone"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5,
      "alwaysOutputData": true
    },
    {
      "id": "2b6f58f6-5f18-49ab-8422-d35c4b9fe0cf",
      "name": "Determine Issue Type and Repeat Offender",
      "type": "n8n-nodes-base.code",
      "position": [
        -3776,
        5264
      ],
      "parameters": {
        "jsCode": "const normalized = $('Normalize Complaint Input').first().json;\nconst orderRows = $('Lookup Order Details').all();\nconst order = orderRows.length ? orderRows[0].json : {};\nconst historyRows = $input.all();\n\nconst now = new Date();\nconst thisMonthCount = historyRows.filter(r => {\n  const d = new Date(r.json.timestamp || r.json.received_at || 0);\n  return d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth();\n}).length;\n\nconst text = (normalized.message_text || '').toLowerCase();\nconst orderedSku = order.ordered_sku || '';\nconst packedSku = order.packed_sku || '';\nconst skuMismatch = orderedSku && packedSku && orderedSku !== packedSku;\n\nlet issueType = 'other';\nif (/damaged|broken|crushed|missing|not received|empty box/.test(text)) {\n  issueType = 'damaged_missing';\n} else if (skuMismatch || /wrong item|different item|not what i ordered/.test(text)) {\n  issueType = 'wrong_item';\n}\n\nconst orderValue = Number(order.order_value || 0);\nconst isHighValue = orderValue > 500;\nconst isRepeatOffender = (thisMonthCount + 1) >= 3;\n\nlet liability = 'unknown';\nif (issueType === 'wrong_item') {\n  liability = 'packing';\n} else if (issueType === 'damaged_missing') {\n  liability = /courier|delivery guy|driver|transit/.test(text) ? 'courier' : 'packing';\n}\n\nreturn [{\n  json: {\n    ...normalized,\n    customer_name: order.customer_name || normalized.customer_name,\n    customer_phone: order.customer_phone || normalized.customer_phone,\n    ordered_sku: orderedSku,\n    packed_sku: packedSku,\n    packer_name: order.packer_name || 'unknown',\n    courier_name: order.courier_name || 'unknown',\n    order_value: orderValue,\n    issue_type: issueType,\n    is_high_value: isHighValue,\n    complaints_this_month: thisMonthCount + 1,\n    is_repeat_offender: isRepeatOffender,\n    liability: liability\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "751e242b-6ea8-4a1a-9cf5-e6e43ea7ff70",
      "name": "Determine Final Route",
      "type": "n8n-nodes-base.code",
      "position": [
        -3248,
        5264
      ],
      "parameters": {
        "jsCode": "const data = $('Determine Issue Type and Repeat Offender').first().json;\n\nlet sentiment = 'neutral';\ntry {\n  const raw = $input.first().json.message?.content || $input.first().json.content || $input.first().json.text || '{}';\n  const cleaned = String(raw).replace(/```json|```/g, '').trim();\n  const parsed = JSON.parse(cleaned);\n  sentiment = parsed.sentiment || 'neutral';\n} catch (e) {\n  sentiment = 'neutral';\n}\n\nlet route = 'escalate_support';\n\nif (data.is_repeat_offender) {\n  route = 'escalate_ops';\n} else if (sentiment === 'angry' || sentiment === 'frustrated') {\n  route = 'escalate_support';\n} else if (data.issue_type === 'damaged_missing') {\n  route = 'escalate_warehouse';\n} else if (data.issue_type === 'wrong_item' && !data.is_high_value) {\n  route = 'auto_approve';\n} else if (data.issue_type === 'wrong_item' && data.is_high_value) {\n  route = 'escalate_support';\n}\n\nreturn [{\n  json: {\n    ...data,\n    sentiment,\n    route\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1b4de231-65af-4269-87f8-342b3f72bcac",
      "name": "Rule Engine - Route Decision",
      "type": "n8n-nodes-base.switch",
      "position": [
        -2576,
        5232
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Auto Approve",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5dcfcd11-c49c-4ebd-b5c8-caa40285fbd8",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.route }}",
                    "rightValue": "auto_approve"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Escalate Support Lead",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5604ba83-1215-4512-bacd-407110b1ded8",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.route }}",
                    "rightValue": "escalate_support"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Escalate Warehouse",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "8bcb5da1-4ba8-49c7-b6ef-2e80e58fb4c6",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.route }}",
                    "rightValue": "escalate_warehouse"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Escalate Ops Manager",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f89f5108-69e8-4cd9-90aa-7a646c2252a2",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.route }}",
                    "rightValue": "escalate_ops"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "b6a1a9f4-6ffc-4d11-92b2-4c60a22fa64c",
      "name": "Log Auto-Approved Resolution",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1856,
        4416
      ],
      "parameters": {
        "columns": {
          "value": {
            "route": "={{ $json.route }}",
            "status": "auto_approved",
            "order_id": "={{ $json.order_id }}",
            "liability": "={{ $json.liability }}",
            "timestamp": "={{ $json.received_at }}",
            "issue_type": "={{ $json.issue_type }}",
            "packer_name": "={{ $json.packer_name }}",
            "courier_name": "={{ $json.courier_name }}",
            "customer_name": "={{ $json.customer_name }}",
            "customer_phone": "={{ $json.customer_phone }}"
          },
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "order_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "order_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issue_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "liability",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "liability",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "packer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "packer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "courier_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "courier_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "07db56aa-5e96-4796-888e-282b3a9c2c56",
      "name": "Send Customer Auto-Approval Confirmation",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1584,
        4416
      ],
      "parameters": {
        "text": "=Hi {{ $json.customer_name }}, sorry about the mix-up on order {{ $json.order_id }}! \u2705 We've auto-approved a free replacement \u2014 no need to wait for a human. Tracking details for the new item will follow shortly.",
        "chatId": "={{ $json.customer_chat_id }}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "01743530-965d-4883-95e6-635b05b018a3",
      "name": "Wait 3 Days for Feedback",
      "type": "n8n-nodes-base.wait",
      "position": [
        -1312,
        4416
      ],
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    },
    {
      "id": "4745e635-dbfa-499c-b6dc-a05cfc4ada98",
      "name": "Send Feedback Request",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1056,
        4416
      ],
      "parameters": {
        "text": "=Hi {{ $json.customer_name }}, quick check-in on order {{ $json.order_id }} \u2014 did the replacement arrive okay and match what you expected? Reply YES or NO \ud83d\ude42",
        "chatId": "={{ $json.customer_chat_id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "2008b650-ad32-40b6-af56-a6084ae34cda",
      "name": "Notify Support Lead - High Value or Angry",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1728,
        5024
      ],
      "parameters": {
        "text": "=\ud83d\udea8 High-value / sentiment escalation\nOrder: {{ $json.order_id }}\nCustomer: {{ $json.customer_name }} ({{ $json.customer_phone }})\nIssue: {{ $json.issue_type }} | Sentiment: {{ $json.sentiment }}\nOrdered SKU: {{ $json.ordered_sku }} | Packed SKU: {{ $json.packed_sku }}\nOrder value: \u20b9{{ $json.order_value }}\nPacker: {{ $json.packer_name }} | Courier: {{ $json.courier_name }}\nPhoto: {{ $json.image_url }}\n\nApprove replacement?",
        "chatId": "={{ $json.support_lead_chat_id }}",
        "replyMarkup": "inlineKeyboard",
        "inlineKeyboard": {
          "rows": [
            {
              "row": {
                "buttons": [
                  {
                    "text": "\u2705 Approve Replacement",
                    "additionalFields": {
                      "callback_data": "=approve_{{ $json.order_id }}"
                    }
                  },
                  {
                    "text": "\u274c Reject",
                    "additionalFields": {
                      "callback_data": "=reject_{{ $json.order_id }}"
                    }
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c00abaae-e095-4c6d-8dd0-331a94f78e76",
      "name": "Log Escalation - Support Lead",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1456,
        5024
      ],
      "parameters": {
        "columns": {
          "value": {
            "route": "={{ $json.route }}",
            "status": "pending_human_approval",
            "order_id": "={{ $json.order_id }}",
            "liability": "={{ $json.liability }}",
            "timestamp": "={{ $json.received_at }}",
            "issue_type": "={{ $json.issue_type }}",
            "packer_name": "={{ $json.packer_name }}",
            "courier_name": "={{ $json.courier_name }}",
            "customer_name": "={{ $json.customer_name }}",
            "customer_phone": "={{ $json.customer_phone }}"
          },
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "order_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "order_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issue_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "liability",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "liability",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "packer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "packer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "courier_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "courier_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "0c12a3ab-4c9c-43fc-ab21-0f025bf24e3a",
      "name": "Notify Warehouse Team - Damaged or Missing",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1808,
        5632
      ],
      "parameters": {
        "text": "=\ud83d\udce6 Damaged/missing item report\nOrder: {{ $json.order_id }}\nSKU that should have shipped: {{ $json.ordered_sku }}\nPacker: {{ $json.packer_name }} | Courier: {{ $json.courier_name }}\nPlease check CCTV/packing log and confirm liability (packing vs courier).\nCustomer photo: {{ $json.image_url }}",
        "chatId": "={{ $json.warehouse_chat_id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "e599bbf5-d673-4ac4-b79f-7d9459102844",
      "name": "Log Escalation - Warehouse",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1536,
        5632
      ],
      "parameters": {
        "columns": {
          "value": {
            "route": "={{ $json.route }}",
            "status": "pending_warehouse_check",
            "order_id": "={{ $json.order_id }}",
            "liability": "={{ $json.liability }}",
            "timestamp": "={{ $json.received_at }}",
            "issue_type": "={{ $json.issue_type }}",
            "packer_name": "={{ $json.packer_name }}",
            "courier_name": "={{ $json.courier_name }}",
            "customer_name": "={{ $json.customer_name }}",
            "customer_phone": "={{ $json.customer_phone }}"
          },
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "order_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "order_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issue_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "liability",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "liability",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "packer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "packer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "courier_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "courier_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "b9db01f7-fec9-42ab-ab0a-2d13a4ebe72d",
      "name": "Check Packer Pattern This Week",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1264,
        5632
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.packer_name }}",
              "lookupColumn": "packer_name"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "73609c5b-58f7-44a2-a8f4-f3f4dec9af98",
      "name": "Evaluate Packer Pattern Count",
      "type": "n8n-nodes-base.code",
      "position": [
        -1008,
        5632
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\nconst now = new Date();\nconst weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);\nconst recent = rows.filter(r => {\n  const d = new Date(r.json.timestamp || 0);\n  return d >= weekAgo && (r.json.issue_type === 'wrong_item' || r.json.issue_type === 'damaged_missing');\n});\nconst original = $('Log Escalation - Warehouse').first().json;\nreturn [{\n  json: {\n    ...original,\n    packer_complaints_this_week: recent.length,\n    packer_pattern_flag: recent.length >= 3\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "4a4eabcb-8316-49e0-a212-1ef740b0d4c2",
      "name": "IF Packer Pattern 3 Plus",
      "type": "n8n-nodes-base.if",
      "position": [
        -752,
        5632
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7ba30b8e-035f-4257-9fa2-568a682b21cb",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.packer_pattern_flag }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2e2cae13-31bf-478b-b0f3-f4a144a601aa",
      "name": "Alert Ops - Packer Quality Pattern",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -464,
        5600
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f Quality control flag: packer {{ $json.packer_name }} has {{ $json.packer_complaints_this_week }} wrong-item/damaged complaints this week. Recommend a QC check on their packing station.",
        "chatId": "={{ $json.ops_manager_chat_id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d792a50c-e719-49ce-bed1-4c6aacadd090",
      "name": "Notify Ops Manager - Repeat Offender",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1568,
        6400
      ],
      "parameters": {
        "text": "=\ud83d\udd01 Repeat offender flag \u2014 do NOT auto-resolve\nCustomer: {{ $json.customer_name }} ({{ $json.customer_phone }})\nOrder: {{ $json.order_id }} | Complaints this month: {{ $json.complaints_this_month }}\nIssue: {{ $json.issue_type }} | Sentiment: {{ $json.sentiment }}\nPlease review manually before any resolution.",
        "chatId": "={{ $json.ops_manager_chat_id }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "7dc6caea-f03a-4041-8ee2-65f6d0b63974",
      "name": "Log Escalation - Ops Manager",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1296,
        6400
      ],
      "parameters": {
        "columns": {
          "value": {
            "route": "={{ $json.route }}",
            "status": "flagged_repeat_offender",
            "order_id": "={{ $json.order_id }}",
            "liability": "={{ $json.liability }}",
            "timestamp": "={{ $json.received_at }}",
            "issue_type": "={{ $json.issue_type }}",
            "packer_name": "={{ $json.packer_name }}",
            "courier_name": "={{ $json.courier_name }}",
            "customer_name": "={{ $json.customer_name }}",
            "customer_phone": "={{ $json.customer_phone }}"
          },
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "order_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "order_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "customer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "customer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issue_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issue_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "liability",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "liability",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "packer_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "packer_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "courier_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "courier_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Complaints Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "d006398f-022c-4dc2-874a-2a9827670da7",
      "name": "Classify Message Sentiment",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -3568,
        5264
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {
          "maxTokens": 60,
          "temperature": 0.2
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You classify customer support message tone. Reply with ONLY valid JSON, no markdown, no extra text: {\"sentiment\": \"angry\" | \"frustrated\" | \"neutral\"}"
            },
            {
              "content": "={{ $json.message_text }}"
            }
          ]
        }
      },
      "typeVersion": 1.4
    },
    {
      "id": "ea83b35a-f034-468d-8f60-b7c3a4b87458",
      "name": "On Workflow Error",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -4032,
        6896
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a51600e8-4d44-4c93-a94f-921545b6a181",
      "name": "Slack \u2013 Post Workflow Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        -3776,
        6896
      ],
      "parameters": {
        "text": "=\ud83d\udea8 *ResolveOS Workflow Error*\n\n*Workflow:* {{ $workflow.name }}\n*Failed Node:* {{ $execution.lastNodeExecuted }}\n*Time:* {{ $now.format('MMM D, YYYY \u2013 HH:mm') }}\n*Execution ID:* {{ $execution.id }}\n\nPlease check the n8n execution log and follow up with the customer manually if needed.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "your-alerts-channel"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "91c616f7-429b-4432-b30d-10f888f8f482",
  "nodeGroups": [],
  "connections": {
    "On Workflow Error": {
      "main": [
        [
          {
            "node": "Slack \u2013 Post Workflow Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Order Details": {
      "main": [
        [
          {
            "node": "Get Customer Complaint History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Determine Final Route": {
      "main": [
        [
          {
            "node": "Rule Engine - Route Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Callback Is Approve": {
      "main": [
        [
          {
            "node": "Extract Order ID From Callback",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Support Lead - Rejected Logged",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Packer Pattern 3 Plus": {
      "main": [
        [
          {
            "node": "Alert Ops - Packer Quality Pattern",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 3 Days for Feedback": {
      "main": [
        [
          {
            "node": "Send Feedback Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Complaint Input": {
      "main": [
        [
          {
            "node": "Lookup Order Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Message Sentiment": {
      "main": [
        [
          {
            "node": "Determine Final Route",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Escalation - Warehouse": {
      "main": [
        [
          {
            "node": "Check Packer Pattern This Week",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Row - Mark Approved": {
      "main": [
        [
          {
            "node": "Notify Customer - Escalated Resolution Approved",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Warehouse - Flag Packer for Repeat Pattern",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Auto-Approved Resolution": {
      "main": [
        [
          {
            "node": "Send Customer Auto-Approval Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rule Engine - Route Decision": {
      "main": [
        [
          {
            "node": "Log Auto-Approved Resolution",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Support Lead - High Value or Angry",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Warehouse Team - Damaged or Missing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Ops Manager - Repeat Offender",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Packer Pattern Count": {
      "main": [
        [
          {
            "node": "IF Packer Pattern 3 Plus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Packer Pattern This Week": {
      "main": [
        [
          {
            "node": "Evaluate Packer Pattern Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Order ID From Callback": {
      "main": [
        [
          {
            "node": "Update Row - Mark Approved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Customer Complaint History": {
      "main": [
        [
          {
            "node": "Determine Issue Type and Repeat Offender",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Support Lead Approval Callback": {
      "main": [
        [
          {
            "node": "IF Callback Is Approve",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Customer Complaint Telegram Trigger": {
      "main": [
        [
          {
            "node": "Normalize Complaint Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Ops Manager - Repeat Offender": {
      "main": [
        [
          {
            "node": "Log Escalation - Ops Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Determine Issue Type and Repeat Offender": {
      "main": [
        [
          {
            "node": "Classify Message Sentiment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Customer Auto-Approval Confirmation": {
      "main": [
        [
          {
            "node": "Wait 3 Days for Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Support Lead - High Value or Angry": {
      "main": [
        [
          {
            "node": "Log Escalation - Support Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Warehouse Team - Damaged or Missing": {
      "main": [
        [
          {
            "node": "Log Escalation - Warehouse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow handles customer order complaints submitted via Telegram by looking up order details in Google Sheets, using OpenAI to classify message sentiment, and routing each case to auto-approval, support lead review, warehouse investigation, or ops manager escalation, with…

Source: https://n8n.io/workflows/17287/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

This workflow handles COD order confirmation and abandoned-cart recovery by combining webhooks, Google Sheets logging, OpenAI message generation, and Telegram messaging with inline buttons, plus Slack

Telegram Trigger, Google Sheets, Telegram +3
Slack & Telegram

This workflow runs a Telegram restaurant ordering flow that uses OpenAI to parse orders and suggest an upsell, sends a Razorpay payment link, confirms paid orders via a Razorpay webhook, logs orders a

Telegram Trigger, OpenAI, Telegram +3
Slack & Telegram

This workflow handles dental clinic patient conversations in Telegram, using OpenAI to answer treatment-plan and general questions, logging bookings and payment plans in Google Sheets, sending automat

Telegram Trigger, Google Sheets, Telegram +3
Slack & Telegram

This workflow lets customers order and refill prescriptions via Telegram by extracting medicines from prescription images with Google Gemini, checking and updating inventory in Google Sheets, and send

Telegram Trigger, Telegram, Google Gemini +3
Slack & Telegram

This workflow runs weekly to pull HR datasets from Google Sheets, calculate rule-based attrition risk signals, and enrich them with an OpenAI (GPT-4o-mini) risk assessment. It logs results back to Goo

Error Trigger, Slack, Google Sheets +3