AutomationFlowsSlack & Telegram › Telegram Order Staging Handler

Telegram Order Staging Handler

Telegram Order Staging Handler. Uses redis, httpRequest, telegram. Webhook trigger; 17 nodes.

Webhook trigger★★★★☆ complexity17 nodesRedisHTTP RequestTelegram
Slack & Telegram Trigger: Webhook Nodes: 17 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Redis 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
{
  "name": "Telegram Order Staging Handler",
  "tags": [
    "staging",
    "telegram",
    "order"
  ],
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "telegram-order-staging",
        "responseMode": "lastNode",
        "options": {}
      },
      "id": "tg-order-trigger",
      "name": "Telegram Order Staging Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// HMAC-SHA256 verification for staging Telegram webhook\n// Verifies x-signature header against HMAC_SECRET_STAGING env var\n\nconst crypto = require('crypto');\nconst signature = $input.item.json.headers?.['x-signature'] || $input.item.json.headers?.['x-telegram-signature'] || '';\nconst hmacSecret = process.env.HMAC_SECRET_STAGING;\nconst body = JSON.stringify($input.item.json.body || $input.item.json);\n\nif (!hmacSecret) {\n  // No secret configured - skip verification in dev mode\n  return { json: { ...$input.item.json, hmac_verified: true, skip_verify: true } };\n}\n\nconst expectedSignature = 'sha256=' + crypto.createHmac('sha256', hmacSecret).update(body).digest('hex');\n\n// Use timingSafeEqual only if both strings have the same length\nconst isValid = signature.length === expectedSignature.length && \n  crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));\n\nif (!isValid && signature) {\n  throw new Error('HMAC verification failed - invalid signature');\n}\n\nreturn { json: { ...$input.item.json, hmac_verified: true } };"
      },
      "id": "hmac-verify",
      "name": "Verify HMAC Signature",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        470,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse Telegram message for order handling\n\nconst body = $input.item.json.body || $input.item.json;\nconst message = body.message || {};\nconst text = (message.text || '').toLowerCase().trim();\nconst chatId = message.chat?.id?.toString() || '';\nconst firstName = message.chat?.first_name || 'there';\nconst updateId = body.update_id?.toString() || '';\n\n// Order-related keywords\nconst orderKeywords = ['order', 'buy', 'purchase', 'get proxy', 'want proxy', 'isp', 'residential', 'mobile', 'datacenter'];\nconst trialKeywords = ['free trial', 'trial', 'free plan', 'try free'];\nconst statusKeywords = ['status', 'check', 'track', 'where is', 'my order'];\nconst helpKeywords = ['help', 'menu', 'start', 'hello', 'hi', 'hello'];\n\nconst isOrder = orderKeywords.some(k => text.includes(k));\nconst isTrial = trialKeywords.some(k => text.includes(k));\nconst isStatus = statusKeywords.some(k => text.includes(k));\nconst isHelp = helpKeywords.some(k => text.includes(k));\n\nconst intent = isOrder ? 'order' : isTrial ? 'free_trial' : isStatus ? 'status' : isHelp ? 'help' : 'unknown';\n\nreturn {\n  json: {\n    channel: 'telegram',\n    chat_id: chatId,\n    user_id: chatId,\n    first_name: firstName,\n    message: text,\n    message_raw: message,\n    update_id: updateId,\n    intent,\n    is_order: isOrder,\n    is_trial: isTrial,\n    is_status: isStatus,\n    is_help: isHelp\n  }\n};"
      },
      "id": "parse-msg",
      "name": "Parse Telegram Message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        690,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Prepare idempotency key with staging prefix\n// Uses staging: prefix to avoid collision with prod\n\nconst updateId = $input.item.json.update_id || '';\nconst chatId = $input.item.json.chat_id || '';\nconst idempotencyKey = `staging:idempotency:telegram:${updateId || chatId}`;\n\nreturn {\n  json: {\n    ...$input.item.json,\n    idempotency_key: idempotencyKey\n  }\n};"
      },
      "id": "prep-idemp",
      "name": "Prepare Idempotency Key",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        910,
        300
      ]
    },
    {
      "parameters": {
        "rule": "set",
        "key": "{{$json.idempotency_key}}",
        "value": "1",
        "options": {
          "ttl": 86400,
          "setNX": true
        }
      },
      "id": "idemp-check",
      "name": "Idempotency Redis Check",
      "type": "n8n-nodes-base.redis",
      "typeVersion": 1,
      "position": [
        1130,
        300
      ],
      "notes": "Check if message already processed with staging: prefix"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false
          },
          "conditions": [
            {
              "id": "cond-need-process",
              "leftValue": "={{$json[\"set\"]}}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ]
        },
        "options": {}
      },
      "id": "if-process",
      "name": "If New Message",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1350,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.minimax.chat/v1/chat/completions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{$env.MINIMAX_API_KEY}}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "model",
              "value": "MiniMax-M2"
            },
            {
              "name": "messages",
              "value": [
                {
                  "role": "system",
                  "content": "You are Styxproxy, a Telegram proxy reseller assistant. Parse customer messages and extract intent. Available intents: order, renewal, status, help, free_trial, recovery, how_to_use, check_data, referral_share, unknown. For orders, extract: proxy_type (isp/residential/mobile/datacenter), duration, quantity. Respond with JSON: { intent, entities: { proxy_type, duration, quantity }, original_message }"
                },
                {
                  "role": "user",
                  "content": "={{$json.message}}"
                }
              ]
            }
          ]
        },
        "options": {
          "timeout": 10000
        }
      },
      "id": "llm-parse",
      "name": "MiniMax LLM Parser",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1570,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse LLM response\n\nlet content = $input.item.json.choices?.[0]?.message?.content || '';\nlet parsed = { intent: 'unknown', entities: {} };\n\ntry {\n  if (typeof content === 'string') {\n    content = content.replace(/^```json\\n?/, '').replace(/\\n?```$/, '');\n    parsed = JSON.parse(content);\n  }\n} catch (e) {\n  // Use keyword fallback\n  const msg = ($input.item.json.message || '').toLowerCase();\n  parsed = {\n    intent: msg.includes('order') || msg.includes('buy') ? 'order' : \n           msg.includes('trial') ? 'free_trial' : \n           msg.includes('status') ? 'status' : \n           msg.includes('help') ? 'help' : 'unknown',\n    entities: {}\n  };\n}\n\nreturn {\n  json: {\n    ...$input.item.json,\n    intent: parsed.intent || 'unknown',\n    entities: parsed.entities || {},\n    llm_raw: content\n  }\n};"
      },
      "id": "parse-llm",
      "name": "Parse LLM Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1790,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Intent switch - route based on LLM-parsed intent\n\nconst intent = $input.item.json.intent;\n\nreturn {\n  json: {\n    ...$input.item.json,\n    intent_routed: intent\n  }\n};"
      },
      "id": "route-intent",
      "name": "Intent Switch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2010,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "cond-order",
              "leftValue": "={{$json.intent_routed}}",
              "rightValue": "order",
              "operation": "equals"
            }
          ]
        },
        "options": {}
      },
      "id": "if-order",
      "name": "If Order Intent",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2230,
        150
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "cond-help",
              "leftValue": "={{$json.intent_routed}}",
              "rightValue": "help",
              "operation": "equals"
            }
          ]
        },
        "options": {}
      },
      "id": "if-help",
      "name": "If Help Intent",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2230,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "cond-trial",
              "leftValue": "={{$json.intent_routed}}",
              "rightValue": "free_trial",
              "operation": "equals"
            }
          ]
        },
        "options": {}
      },
      "id": "if-trial",
      "name": "If Trial Intent",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2230,
        450
      ]
    },
    {
      "parameters": {
        "jsCode": "// Generate order menu for Telegram\nconst message = `\ud83d\uded2 **Order Proxy**\n\nChoose your proxy type:\n\n\ud83d\udce1 **ISP Proxy** - \u20a66,500/month\n   \u2022 Static IP, Nigeria\n   \u2022 Fast speed\n\n\ud83c\udfe0 **Residential Proxy** - \u20a61,950/GB\n   \u2022 Rotating IPs\n   \u2022 High anonymity\n\n\ud83d\udcf1 **Mobile Proxy** - \u20a62,500/GB\n   \u2022 4G/5G IPs\n   \u2022 Carrier-level\n\n\ud83d\udda5\ufe0f **Datacenter Proxy** - \u20a64,000/month\n   \u2022 Fast, reliable\n\nReply with:\n\u2022 \"ISP\" for ISP proxy\n\u2022 \"Residential\" for residential\n\u2022 \"Mobile\" for mobile\n\u2022 \"Datacenter\" for datacenter\n\nOr say \"menu\" to go back.`;\n\nreturn { json: { ...$input.item.json, reply_message: message } };"
      },
      "id": "gen-order-menu",
      "name": "Generate Order Menu",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2450,
        50
      ]
    },
    {
      "parameters": {
        "jsCode": "// Generate help menu\nconst message = `\ud83c\uddf3\ud83c\uddec **Styxproxy Proxy**\n\nI can help you with:\n\n\ud83d\uded2 **Order** \u2014 ISP, Residential, Mobile, Datacenter\n\ud83d\udcb3 **Check Status** \u2014 Track your order\n\ud83d\udcb0 **Pricing** \u2014 See all plans\n\u2753 **Help** \u2014 How to get started\n\ud83d\udd17 **Free Trial** \u2014 Get a free proxy\n\nWhat would you like to do?`;\n\nreturn { json: { ...$input.item.json, reply_message: message } };"
      },
      "id": "gen-help",
      "name": "Generate Help Message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2450,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Generate trial info\nconst message = `\ud83c\udf81 **Free Trial**\n\nGet a free proxy to test our service!\n\n**How it works:**\n1. Complete a short survey\n2. Earn 2 hours per survey\n3. Do up to 12 surveys = 24 hours free!\n\n**To start:**\nClick the survey link, complete it, then come back and say \"done\"\n\n**Note:** Free trial proxies are shared and for testing only.\n\nReady to start? Say \"I want trial\" or click the survey link.`;\n\nreturn { json: { ...$input.item.json, reply_message: message } };"
      },
      "id": "gen-trial",
      "name": "Generate Trial Message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2450,
        550
      ]
    },
    {
      "parameters": {
        "chatId": "={{$json.chat_id}}",
        "message": "={{$json.reply_message}}",
        "options": {}
      },
      "id": "telegram-reply",
      "name": "Reply via Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        2670,
        300
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Uses TELEGRAM_BOT_TOKEN_STAGING env var - NOT prod token"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"status\":\"ok\"}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "respond-200",
      "name": "Respond 200 OK",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        2890,
        300
      ]
    }
  ],
  "connections": {
    "Telegram Order Staging Trigger": {
      "main": [
        [
          {
            "node": "Verify HMAC Signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify HMAC Signature": {
      "main": [
        [
          {
            "node": "Parse Telegram Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Telegram Message": {
      "main": [
        [
          {
            "node": "Prepare Idempotency Key",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Idempotency Key": {
      "main": [
        [
          {
            "node": "Idempotency Redis Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Idempotency Redis Check": {
      "main": [
        [
          {
            "node": "If New Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If New Message": {
      "main": [
        [
          {
            "node": "MiniMax LLM Parser",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 200 OK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MiniMax LLM Parser": {
      "main": [
        [
          {
            "node": "Parse LLM Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse LLM Response": {
      "main": [
        [
          {
            "node": "Intent Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Intent Switch": {
      "main": [
        [
          {
            "node": "If Order Intent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If Help Intent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If Trial Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Order Intent": {
      "main": [
        [
          {
            "node": "Generate Order Menu",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Help Intent": {
      "main": [
        [
          {
            "node": "Generate Help Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Trial Intent": {
      "main": [
        [
          {
            "node": "Generate Trial Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Order Menu": {
      "main": [
        [
          {
            "node": "Reply via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Help Message": {
      "main": [
        [
          {
            "node": "Reply via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Trial Message": {
      "main": [
        [
          {
            "node": "Reply via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reply via Telegram": {
      "main": [
        [
          {
            "node": "Respond 200 OK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

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

Telegram Order Staging Handler. Uses redis, httpRequest, telegram. Webhook trigger; 17 nodes.

Source: https://github.com/sonnyagent30-beep/Styxproxy/blob/878d93ddb0424068ef90bf013fa3a31461b471a6/.n8n/workflows/staging/02-telegram-order-staging.json — 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

[](https://www.linkedin.com/in/mosaab-yassir-lafrimi/)[](https://t.me/joevenner)

HTTP Request, Redis, S3 +1
Slack & Telegram

Shared Checkout Staging Handler. Uses redis, httpRequest, telegram. Webhook trigger; 20 nodes.

Redis, HTTP Request, Telegram
Slack & Telegram

Channel Intent Router (Template). Uses redis, httpRequest, telegram. Webhook trigger; 16 nodes.

Redis, HTTP Request, Telegram
Slack & Telegram

WF_UNIFIED_LEGAL_AUTOMATION. Uses googleSheets, httpRequest, telegram, telegramTrigger. Webhook trigger; 53 nodes.

Google Sheets, HTTP Request, Telegram +1
Slack & Telegram

qualiopi. Uses airtable, telegram, emailSend, httpRequest. Webhook trigger; 51 nodes.

Airtable, Telegram, Email Send +3