轻量级支持台与Telegram和Postgres数据库跟踪
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 45 个节点。主要使用 If, Code, Switch, Postgres, Telegram 等节点。 基于Telegram和Postgres数据库跟踪的轻量级支持台
前置要求
- •PostgreSQL 数据库连接信息
- •Telegram Bot Token
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "9c8d0d4640139c59e2bc183c0a14df0fbc0573cb91e494f5db8144fe78fe28ca",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "0d7bebe5-8f7c-48d1-805a-927919fd842e",
"name": "01 Telegram 触发器:受理 + 状态",
"type": "n8n-nodes-base.telegramTrigger",
"notes": "Listens for Telegram bot messages. Routes commands like /start, /new, /status, /update, /list into the Switch node.",
"position": [
-352,
-48
],
"webhookId": "ce5e4331-643e-4f6f-b465-96e93b097863",
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "096e115e-a27c-486e-93ce-40c23bce1b3d",
"name": "02 切换:按命令路由",
"type": "n8n-nodes-base.switch",
"notes": "Splits incoming commands into different branches. Output keys = command names (/new, /status, etc.). Fallback = Invalid Command.",
"position": [
-96,
-80
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "/start",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ce357ab4-c67e-4bf7-b791-9f90b568aa28",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"message\"][\"text\"].split(\" \")[0].toLowerCase() }}",
"rightValue": "/start"
}
]
},
"renameOutput": true
},
{
"outputKey": "/status",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5c875ce6-1a63-42bc-b828-426e56fedd7d",
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json[\"message\"][\"text\"].split(\" \")[0].toLowerCase() }}",
"rightValue": "/status"
}
]
},
"renameOutput": true
},
{
"outputKey": "/new",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "db0d9d53-1fa2-4b95-b4ed-026ea97ac21f",
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json[\"message\"][\"text\"].split(\" \")[0].toLowerCase() }}",
"rightValue": "/new"
}
]
},
"renameOutput": true
},
{
"outputKey": "/update",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "54b2e9fb-1cd5-4634-a7e9-d29c936d0f9d",
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json[\"message\"][\"text\"].split(\" \")[0].toLowerCase() }}",
"rightValue": "/update"
}
]
},
"renameOutput": true
},
{
"outputKey": "/list",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1c4a4f1b-1f99-4a5d-93d3-48887d112dc2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"message\"][\"text\"].split(\" \")[0].toLowerCase() }}",
"rightValue": "/list"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"notesInFlow": true,
"typeVersion": 3.2
},
{
"id": "7cdd210c-6bba-4f38-86af-a15b3e6417ff",
"name": "03a 函数:规范化 + 哈希",
"type": "n8n-nodes-base.code",
"notes": "Parses ticket info from freeform Telegram text (Name, Email, Phone, Subject, Description). Generates correlation ID (UUID) and dedupe key (SHA-256 hash of email+subject).",
"position": [
208,
-160
],
"parameters": {
"language": "python",
"pythonCode": "import re\nimport hashlib\nimport uuid\n\n# Get the first incoming item\nitem = items[0]\n\n# Correct path to Telegram text\ntext = item[\"json\"].get(\"message\", {}).get(\"text\", \"\")\n\n# Defaults\nparsed = {\n \"requester_name\": \"Unknown\",\n \"requester_email\": \"unknown@example.com\",\n \"requester_phone\": \"N/A\",\n \"subject\": \"No subject\",\n \"description\": \"No description\",\n \"source\": \"telegram\",\n \"priority\": \"normal\",\n \"status\": \"new\", # added here instead of in query\n \"external_id\": None\n}\n\n# Regex patterns\npatterns = {\n \"requester_name\": r\"Name:\\s*(.+)\",\n \"requester_email\": r\"Email:\\s*(\\S+)\",\n \"requester_phone\": r\"Phone:\\s*(.+)\",\n \"subject\": r\"Subject:\\s*(.+)\",\n \"description\": r\"Description:\\s*(.+)\"\n}\n\nfor key, pattern in patterns.items():\n match = re.search(pattern, text, re.IGNORECASE | re.MULTILINE)\n if match:\n parsed[key] = match.group(1).strip()\n\n# Correlation ID\nparsed[\"correlation_id\"] = str(uuid.uuid4())\n\n# Build dedupe key\ndedupe_source = f\"{parsed['requester_email']}|{parsed['subject']}\"\nparsed[\"dedupe_key\"] = hashlib.sha256(dedupe_source.encode()).hexdigest()\n\n# External ID from Telegram chat\nchat_id = item[\"json\"].get(\"message\", {}).get(\"chat\", {}).get(\"id\")\nparsed[\"external_id\"] = str(chat_id) if chat_id else \"N/A\"\n\n# Output in correct n8n format\nreturn [{\"json\": parsed}]\n"
},
"typeVersion": 2
},
{
"id": "1c6e1fe9-f919-4614-a0e4-9c7a875ce7d0",
"name": "04a 数据库:更新插入工单",
"type": "n8n-nodes-base.postgres",
"notes": "Executes stored Postgres function upsert_ticket. Inserts or updates a ticket record with parsed fields. Requires function to exist in DB. \ncorrelation_id, source, external_id, requester_*, subject, description, status, priority, dedupe_key\nOutput: ticket ID and correlation ID",
"position": [
528,
-160
],
"parameters": {
"query": "SELECT id, correlation_id, chat_id\nFROM upsert_ticket(\n $1::uuid,\n $2::text,\n $3::text,\n $4::text,\n $5::text,\n $6::text,\n $7::text,\n $8::text,\n $9::text,\n $10::text,\n $11::text,\n $12::text\n);\n",
"options": {
"queryReplacement": "={{$json.correlation_id}}\n\n{{$json.source}}\n\n{{$json.external_id}}\n\n{{$json.requester_name}}\n\n{{$json.requester_email}}\n\n{{$json.requester_phone}}\n\n{{$json.subject}}\n\n{{$json.description}}\n\n{{$json.status}}\n\n{{$json.priority}}\n\n{{$json.dedupe_key}}\n\n{{ $json.external_id }}",
"replaceEmptyStrings": true
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"notesInFlow": true,
"typeVersion": 2.6
},
{
"id": "4f742ec0-aca7-4f7b-923c-4b02babef11b",
"name": "05a Telegram 确认",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
880,
-160
],
"webhookId": "f2d3d095-31e4-4972-9047-5a6350672e43",
"parameters": {
"text": "=Ticket received ✅\nCorrelation ID: <code>{{ $json.correlation_id }}</code>\nSave this ID to check status later.\n",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "ad13dc98-c69f-4d97-801d-2076f77897f4",
"name": "03b 函数:解析状态命令",
"type": "n8n-nodes-base.code",
"position": [
192,
-592
],
"parameters": {
"language": "python",
"pythonCode": "import re\n\nout_items = []\n\nfor item in items:\n text = item[\"json\"].get(\"message\", {}).get(\"text\", \"\").strip()\n parts = text.split(maxsplit=1)\n\n if len(parts) == 2:\n correlation_id = parts[1].strip()\n # quick regex UUID check\n if not re.match(r'^[0-9a-fA-F-]{36}$', correlation_id):\n correlation_id = None\n else:\n correlation_id = None\n\n out_items.append({\n \"json\": {\n \"correlation_id\": correlation_id,\n \"chat_id\": item[\"json\"][\"message\"][\"chat\"][\"id\"]\n }\n })\n\nreturn out_items\n"
},
"typeVersion": 2
},
{
"id": "0892a7ae-2f00-4f66-89f1-05ed68d941be",
"name": "04b 数据库:获取工单状态",
"type": "n8n-nodes-base.postgres",
"notes": "Fetches ticket info by correlation ID. Returns subject, status, timestamps. Handles missing tickets through the downstream IF node.",
"position": [
976,
-960
],
"parameters": {
"query": "SELECT subject, status, created_at, updated_at, chat_id\nFROM tickets\nWHERE correlation_id = $1::uuid;\n",
"options": {
"queryReplacement": "={{$json.correlation_id}}"
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"notesInFlow": true,
"retryOnFail": true,
"typeVersion": 2.6,
"alwaysOutputData": true
},
{
"id": "b2248f84-10dc-464c-a611-6e4b924932c9",
"name": "05b Telegram:状态回复",
"type": "n8n-nodes-base.telegram",
"position": [
2352,
-512
],
"webhookId": "bae8bec4-4af5-4bf9-bba6-218b8bd5b0f8",
"parameters": {
"text": "=✅ Ticket ID: {{ $json.chat_id }}\n📄 Ticket: {{ $json.subject }}\n📌 Status: {{ $json.status }}\n🕒 Created: {{ new Date($json.created_at).toLocaleString(\"en-GB\", { dateStyle: \"medium\", timeStyle: \"short\" }) }}\n🔄 Last Updated: {{ new Date($json.updated_at).toLocaleString(\"en-GB\", { dateStyle: \"medium\", timeStyle: \"short\" }) }}\n\n",
"chatId": "={{ $('02 Switch: Route by Command').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "cf87371a-3909-434e-88b3-42f6a4b80194",
"name": "03b1 如果:有关联 ID",
"type": "n8n-nodes-base.if",
"position": [
656,
-944
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3a901b12-fe84-4f01-993a-185a2753eb0e",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.correlation_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cbae7eab-6cb1-46f6-a2ea-58f0a5115929",
"name": "05b Telegram:状态回复(错误)",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
976,
-688
],
"webhookId": "4095be65-c09f-4d65-8800-8f8d9e5b46a4",
"parameters": {
"text": "=❌ Please provide a correlation ID.\nFormat: /status correlation_id\n",
"chatId": "={{$json.chat_id}}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "997d1d5f-ad28-4a2f-90f6-bdcc4c3e02fb",
"name": "Telegram:无效命令",
"type": "n8n-nodes-base.telegram",
"position": [
192,
736
],
"webhookId": "84089957-fe6b-432b-8828-ccd7930ce954",
"parameters": {
"text": "=⚠️ I didn’t understand that request.\nTry /new or /status <ID>.",
"chatId": "={{ $json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "aef8342f-17b0-45f5-b8ae-823b50ab5ccf",
"name": "03c 函数:解析更新命令",
"type": "n8n-nodes-base.code",
"position": [
512,
160
],
"parameters": {
"language": "python",
"pythonCode": "import re\n\nout_items = []\n\nfor item in items:\n text = item[\"json\"].get(\"message\", {}).get(\"text\", \"\").strip()\n parts = text.split(maxsplit=2)\n\n if len(parts) == 3:\n correlation_id, new_status = parts[1], parts[2].lower()\n if not re.match(r'^[0-9a-fA-F-]{36}$', correlation_id):\n correlation_id = None\n else:\n correlation_id, new_status = None, None\n\n out_items.append({\n \"json\": {\n \"correlation_id\": correlation_id,\n \"new_status\": new_status,\n \"chat_id\": item[\"json\"][\"message\"][\"chat\"][\"id\"]\n }\n })\n\nreturn out_items\n"
},
"typeVersion": 2
},
{
"id": "def5eb31-46b0-4db1-92d0-40dedbb62e4e",
"name": "03c1 如果:有关联 ID",
"type": "n8n-nodes-base.if",
"position": [
1216,
-64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "49a8e0db-73d3-4615-add4-c21fe8eb2fb4",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.correlation_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "8167b85a-e6b9-4b6e-a26b-88f2760bd0f9",
"name": "发送文本消息",
"type": "n8n-nodes-base.telegram",
"position": [
1552,
224
],
"webhookId": "168df2e1-e83a-4ba9-b679-072bd8f51df8",
"parameters": {
"text": "=❌ Invalid or missing correlation ID. Format: /update <ID> <status>.",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "9acad108-3f50-414c-8b64-a69fc3f6c344",
"name": "03c2 如果:有效状态",
"type": "n8n-nodes-base.if",
"position": [
1568,
-80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "9ee9632a-361a-4cd3-a842-8e839ae84c2d",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"new_status\"] }}",
"rightValue": "new"
},
{
"id": "5e821125-60f9-45ce-b803-f50a5a3b0776",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"new_status\"] }}",
"rightValue": "in_progress"
},
{
"id": "8205c0d2-293f-43bc-aaec-2200f801b851",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"new_status\"] }}",
"rightValue": "resolved"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "25588539-1ec7-46c8-8835-51baa7b35ba9",
"name": "05c Telegram:无效状态",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
2352,
400
],
"webhookId": "477de1f0-cea0-4b5e-80e8-283af9452d4a",
"parameters": {
"text": "=⚠️ Invalid status. Allowed values: new, in_progress, resolved.",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "681309cf-a699-435c-8896-1a00c35c3bc6",
"name": "04c 数据库:更新工单状态",
"type": "n8n-nodes-base.postgres",
"notes": "Updates ticket status by correlation ID. Also inserts audit row and notifies ticket owner. Requires tickets table and audit schema.",
"position": [
2304,
128
],
"parameters": {
"query": "UPDATE tickets\nSET status = $2, updated_at = NOW()\nWHERE correlation_id = $1::uuid\nRETURNING id, status, updated_at, correlation_id;\n",
"options": {
"queryReplacement": "={{$json.correlation_id}},{{$json.new_status}}"
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"notesInFlow": true,
"typeVersion": 2.6
},
{
"id": "74e0d370-d999-43b6-8628-1fe48602c875",
"name": "03c0 如果:是操作员",
"type": "n8n-nodes-base.if",
"position": [
816,
160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "02a8b086-3e20-4576-a746-9e0bde67aba4",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"chat_id\"] }}",
"rightValue": "YOUR_OPERATOR_ID"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "6d4e5147-1b94-42b7-b727-9478c56496ab",
"name": "05c0 Telegram:未经授权的更新尝试",
"type": "n8n-nodes-base.telegram",
"position": [
1232,
352
],
"webhookId": "c0905e30-f115-4e85-9b24-ab26e3954ad3",
"parameters": {
"text": "=❌ You don’t have permission to update tickets.",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "680d87b3-88ff-48b8-833c-b5b322e86bf5",
"name": "04c1 数据库:获取工单所有者",
"type": "n8n-nodes-base.postgres",
"position": [
2816,
128
],
"parameters": {
"query": "SELECT chat_id, correlation_id, status, subject\nFROM tickets\nWHERE correlation_id = $1::uuid;",
"options": {
"queryReplacement": "={{ $('04c DB: Update Ticket Status').item.json.correlation_id }}"
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"typeVersion": 2.6
},
{
"id": "0d248692-2d2f-4f83-8372-62dc3f119400",
"name": "04b1 如果:工单属于用户",
"type": "n8n-nodes-base.if",
"position": [
1984,
-496
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "19a37b2c-e9ae-4a6c-9e6d-47f3fa7e5e69",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"chat_id\"] }}",
"rightValue": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.chat.id }}"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "c3ac8c89-8578-4415-90f6-ed2e8eed787a",
"name": "05b1 Telegram:未经授权的状态检查",
"type": "n8n-nodes-base.telegram",
"position": [
2368,
-224
],
"webhookId": "0fa252cb-177d-4e95-8456-34753477d976",
"parameters": {
"text": "=❌ You do not have access to this ticket.\nOnly the ticket creator can view its status.",
"chatId": "={{ $('02 Switch: Route by Command').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "9acff907-71f9-464b-b575-95238009bc69",
"name": "04c1a 如果:已解决或进行中",
"type": "n8n-nodes-base.if",
"position": [
3168,
32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "115bb477-3dfa-4d9b-8e4b-cd2ef15439e1",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"status\"] }}",
"rightValue": "resolved"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1e6afb7d-537a-4aea-8762-d2c75c42d2f0",
"name": "05c1a Telegram:通知已解决",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
3536,
-80
],
"webhookId": "834b2795-7e52-4264-b787-7280bf60de36",
"parameters": {
"text": "=🎉 Good news! Your ticket ({{ $json.correlation_id }}) has been resolved. \nYou can check details anytime with: \n/status {{ $json.correlation_id }}",
"chatId": "={{ $json.chat_id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"retryOnFail": true,
"typeVersion": 1.2
},
{
"id": "99688c3d-8bd7-4b8c-9861-23fb3d322581",
"name": "05c1b Telegram:通知进行中",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
3536,
160
],
"webhookId": "560dda9b-b8e5-4e5b-9705-4d6ed17ce50d",
"parameters": {
"text": "=🔄 Your ticket ({{ $json.correlation_id }}) is now being worked on. \nWe’ll notify you once it’s resolved.",
"chatId": "={{ $json.chat_id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"retryOnFail": true,
"typeVersion": 1.2
},
{
"id": "b54c2084-2bfd-40c0-b07c-8c7d9b35362f",
"name": "05c Telegram:更新确认",
"type": "n8n-nodes-base.telegram",
"notes": "Sends user-facing messages back to Telegram. Content depends on workflow branch (acknowledgment, errors, updates).",
"position": [
3088,
320
],
"webhookId": "2e047d36-651f-4c1e-9970-8adf7029c70c",
"parameters": {
"text": "=✅ <b>Ticket {{ $json.correlation_id }}</b> updated!\n📌 <b>New Status:</b> {{ $json[\"status\"] }}\n⏰ <b>Updated At:</b> {{ new Date($(\"04c DB: Update Ticket Status\").item.json.updated_at).toLocaleString() }}\n",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"retryOnFail": true,
"typeVersion": 1.2
},
{
"id": "f8c20998-f5c0-4223-afaa-4760712aa2d1",
"name": "04b0 如果:数据库查找失败?",
"type": "n8n-nodes-base.if",
"position": [
1728,
-736
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f367a262-4b55-40ad-a0ef-711ac9ebfa10",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ !!$json.error }}",
"rightValue": "true"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "6fa0c0d8-1975-47c9-bb28-82bc528d8c1b",
"name": "05b0 Telegram:状态数据库错误",
"type": "n8n-nodes-base.telegram",
"position": [
2352,
-752
],
"webhookId": "96e6b1fa-9500-4e81-8433-ec87963af06b",
"parameters": {
"text": "=❌ Sorry, I couldn’t fetch your ticket right now. Please try again in a minute.",
"chatId": "={{ $('02 Switch: Route by Command').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "dda44929-b58d-42a8-9f89-307489323c97",
"name": "05c0 如果:操作员回复失败?",
"type": "n8n-nodes-base.if",
"position": [
3408,
320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4a912629-cc2e-43b0-9ee1-cda03feda4b0",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ !!$json.error }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "2e6fde8d-6bb7-421c-8fbd-dc10d672be2b",
"name": "Telegram:管理员警报 — 操作员回复失败",
"type": "n8n-nodes-base.telegram",
"position": [
3712,
304
],
"webhookId": "8ae7a0d4-71f7-4717-ad1b-a1355c4cd4ae",
"parameters": {
"text": "=⚠️ Operator reply could not be delivered. \nTicket: {{ $('04c DB: Update Ticket Status').item.json.correlation_id }} \nStatus: {{ $('04c DB: Update Ticket Status').item.json.status }} \nOperator: {{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"chatId": "={{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "068e4ac0-c802-4bb7-a0fa-4d81c4169936",
"name": "通知失败?",
"type": "n8n-nodes-base.if",
"position": [
4000,
32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4eb644e5-1340-492e-96e7-66198d2d72ad",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ !!$json.error }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "73c0c8b5-2385-495e-b341-a0e95faae5f0",
"name": "执行 SQL 查询",
"type": "n8n-nodes-base.postgres",
"position": [
4320,
16
],
"parameters": {
"query": "INSERT INTO workflow_errors\n (workflow_id, workflow_name, execution_id, last_node_executed, error_message, json_payload)\nVALUES\n ($1, $2, $3, $4, $5, $6::jsonb);",
"options": {
"queryReplacement": "={{ $workflow.id }},{{ $workflow.name }},{{ $execution.id }},NotifyUser,{{ $json.error?.message || 'unknown' }},{{ JSON.stringify($json) }}"
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"typeVersion": 2.6
},
{
"id": "0f0761c5-6a16-4fcc-94b3-9a8a37ff047b",
"name": "04c2 数据库:插入审核行",
"type": "n8n-nodes-base.postgres",
"position": [
2560,
128
],
"parameters": {
"query": "INSERT INTO ticket_audit\n (ticket_id, correlation_id, action, new_status, actor_chat_id)\nVALUES\n ($1, $2, 'update', $3, $4);\n",
"options": {
"queryReplacement": "={{ $json.id }},\n{{ $json.correlation_id }},\n{{ $json.status }},\n{{ $('01 Telegram Trigger: Intake + Status').item.json.message.from.id }}"
},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"typeVersion": 2.6
},
{
"id": "ff81de50-249c-49fe-a014-78e703b0e005",
"name": "04b1 如果:未找到工单",
"type": "n8n-nodes-base.if",
"position": [
1328,
-960
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1a87141a-6e78-4222-9523-00795be95f6f",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json[\"subject\"] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "657b78f7-82d6-4dfa-8514-63d99899d91c",
"name": "发送短信1",
"type": "n8n-nodes-base.telegram",
"position": [
1712,
-976
],
"webhookId": "cc28681b-50ca-45f5-a024-bef21cb8ae36",
"parameters": {
"text": "=❌ No ticket found with that ID.\nDouble-check your ID or create a new ticket with /new",
"chatId": "={{ $('02 Switch: Route by Command').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "427c8ad1-e42f-4454-b54d-513df32d111f",
"name": "03b 如果:具有有效的关联 ID 格式",
"type": "n8n-nodes-base.if",
"position": [
496,
-592
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0bfef915-ea45-4b6d-bf12-8999b67b8044",
"operator": {
"type": "string",
"operation": "regex"
},
"leftValue": "={{$json.correlation_id}}",
"rightValue": "=^[0-9a-fA-F-]{36}$"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "77001b07-a1e4-4e9c-b015-e3626b10f43a",
"name": "发送文本消息2",
"type": "n8n-nodes-base.telegram",
"position": [
880,
-400
],
"webhookId": "2291928b-6bdc-4071-84f6-f8d84484198e",
"parameters": {
"text": "=⚠️ Invalid ticket ID format. Please provide a valid correlation ID (UUID).",
"chatId": "={{$json.chat_id}}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "1bc21cd7-0689-43d3-8cda-cb5a153526f4",
"name": "欢迎消息",
"type": "n8n-nodes-base.telegram",
"position": [
160,
-992
],
"webhookId": "b7ac58ed-e8d7-48e8-b9a1-3a52e1376b2c",
"parameters": {
"text": "=👋 <b>Welcome to the Support Bot</b> \n\nYou can create and manage tickets right here: \n\n• <b>/new</b> — Open a new support ticket \n• <b>/update <ID> <status></b> — Update your ticket’s status \n• <b>/status <ID></b> — Check the current status of a ticket \n\n💡 Save your <b>Ticket ID</b> when you create one — you’ll need it for updates. ✅\n",
"chatId": "={{ $json.message.from.id }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "c5a5954e-ec31-40f0-87fe-4ef507a081e3",
"name": "发送文本消息3",
"type": "n8n-nodes-base.telegram",
"position": [
1216,
944
],
"webhookId": "42cc248a-3229-49e4-a21a-2c2ed5059a49",
"parameters": {
"text": "=❌ <b>You are not authorized to use this command.</b>",
"chatId": "={{ $json.message.from.id }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "4f391512-66b6-4239-a7ee-fba38a6ec273",
"name": "检查管理员",
"type": "n8n-nodes-base.if",
"position": [
704,
544
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ce4f2418-7a43-44b5-845e-8abf8d0108b2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{$json[\"message\"][\"from\"][\"id\"]}}",
"rightValue": "YOUR_ADMIN_ID"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "f80cf5ce-d6eb-4795-9dc2-577442c05f72",
"name": "数据库:列出工单",
"type": "n8n-nodes-base.postgres",
"position": [
1216,
672
],
"parameters": {
"query": "SELECT correlation_id, subject, status, created_at\nFROM tickets\nORDER BY created_at DESC\nLIMIT 10;",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "DeyLRt5YrGqjUrds",
"name": "Postgres account"
}
},
"typeVersion": 2.6
},
{
"id": "4e2e1d2d-de49-4850-9a4a-e63ff069891e",
"name": "发送文本消息4",
"type": "n8n-nodes-base.telegram",
"position": [
1632,
672
],
"webhookId": "93444267-52aa-4b71-bb7a-ade43f15f6ad",
"parameters": {
"text": "={{ $json.text }}",
"chatId": "={{ $json.chat_id }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "PEoTj5wxpFTeQVpI",
"name": "Ticket Intake"
}
},
"typeVersion": 1.2
},
{
"id": "51eb9b7c-f7cb-4ce4-abb2-d482ccb0850b",
"name": "JavaScript 代码",
"type": "n8n-nodes-base.code",
"position": [
1424,
672
],
"parameters": {
"jsCode": "const tickets = items;\n\nlet message = \"📋 <b>Latest Tickets</b>\\n\\n\";\n\ntickets.forEach((row, i) => {\n message += `${i+1}. <b>ID:</b> ${row.json.correlation_id}\\n`;\n message += ` <b>Status:</b> ${row.json.status}\\n`;\n message += ` <i>${row.json.subject || \"No subject\"}</i>\\n`;\n message += ` Created: ${row.json.created_at}\\n\\n`;\n});\n\n// pull original chat_id from the trigger\nconst chatId = $(\"01 Telegram Trigger: Intake + Status\").item.json.message.from.id;\n\nreturn [{ json: { text: message, chat_id: chatId } }];\n"
},
"typeVersion": 2
},
{
"id": "8baac22d-8d39-4516-85e0-610b1c03346e",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1904,
-368
],
"parameters": {
"color": 5,
"width": 736,
"height": 1104,
"content": "# 🛠 设置要求"
},
"typeVersion": 1
},
{
"id": "e72863ee-979a-46c4-90dd-98572aa027d3",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1120,
-368
],
"parameters": {
"width": 688,
"height": 1104,
"content": "# 📌 函数:upsert_ticket"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Check Admin": {
"main": [
[
{
"node": "DB: List Tickets",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a text message3",
"type": "main",
"index": 0
}
]
]
},
"Notify Failed?": {
"main": [
[
{
"node": "Execute a SQL query",
"type": "main",
"index": 0
}
]
]
},
"DB: List Tickets": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Send a text message4",
"type": "main",
"index": 0
}
]
]
},
"03c0 IF: Is Operator": {
"main": [
[
{
"node": "03c1 IF: Has Correlation ID",
"type": "main",
"index": 0
}
],
[
{
"node": "05c0 Telegram: Unauthorized Update Attempt",
"type": "main",
"index": 0
}
]
]
},
"Send a text message3": {
"main": [
[]
]
},
"03c2 IF: Valid Status": {
"main": [
[
{
"node": "04c DB: Update Ticket Status",
"type": "main",
"index": 0
}
],
[
{
"node": "05c Telegram: Invalid Status",
"type": "main",
"index": 0
}
]
]
},
"04a DB: Upsert Ticket": {
"main": [
[
{
"node": "05a Telegram Ack",
"type": "main",
"index": 0
}
]
]
},
"03a FN: Normalize + Hash": {
"main": [
[
{
"node": "04a DB: Upsert Ticket",
"type": "main",
"index": 0
}
]
]
},
"04b1 IF: No Ticket Found": {
"main": [
[
{
"node": "Send a text message1",
"type": "main",
"index": 0
}
],
[
{
"node": "04b0 IF: DB Lookup Failed?",
"type": "main",
"index": 0
}
]
]
},
"04b DB: Get Ticket Status": {
"main": [
[
{
"node": "04b1 IF: No Ticket Found",
"type": "main",
"index": 0
}
]
]
},
"04c1 DB: Get Ticket Owner": {
"main": [
[
{
"node": "04c1a IF: Resolved or In Progress",
"type": "main",
"index": 0
},
{
"node": "05c Telegram: Update Confirmation",
"type": "main",
"index": 0
}
]
]
},
"04c2 DB: Insert Audit Row": {
"main": [
[
{
"node": "04c1 DB: Get Ticket Owner",
"type": "main",
"index": 0
}
]
]
},
"04b0 IF: DB Lookup Failed?": {
"main": [
[
{
"node": "05b0 Telegram: Status DB Error",
"type": "main",
"index": 0
}
],
[
{
"node": "04b1 IF: Ticket Belongs To User",
"type": "main",
"index": 0
}
]
]
},
"02 Switch: Route by Command": {
"main": [
[
{
"node": "Welcome Message",
"type": "main",
"index": 0
}
],
[
{
"node": "03b FN: Parse Status Command",
"type": "main",
"index": 0
}
],
[
{
"node": "03a FN: Normalize + Hash",
"type": "main",
"index": 0
}
],
[
{
"node": "03c FN: Parse Update Command",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Admin",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram: Invalid Command",
"type": "main",
"index": 0
}
]
]
},
"03b1 IF: Has Correlation ID": {
"main": [
[
{
"node": "04b DB: Get Ticket Status",
"type": "main",
"index": 0
}
],
[
{
"node": "05b Telegram: Status Reply (Error)",
"type": "main",
"index": 0
}
]
]
},
"03c1 IF: Has Correlation ID": {
"main": [
[
{
"node": "03c2 IF: Valid Status",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
},
"03b FN: Parse Status Command": {
"main": [
[
{
"node": "03b IF: Has Valid Correlation ID Format",
"type": "main",
"index": 0
}
]
]
},
"03c FN: Parse Update Command": {
"main": [
[
{
"node": "03c0 IF: Is Operator",
"type": "main",
"index": 0
}
]
]
},
"04c DB: Update Ticket Status": {
"main": [
[
{
"node": "04c2 DB: Insert Audit Row",
"type": "main",
"index": 0
}
]
]
},
"04b1 IF: Ticket Belongs To User": {
"main": [
[
{
"node": "05b Telegram: Status Reply",
"type": "main",
"index": 0
}
],
[
{
"node": "05b1 Telegram: Unauthorized Status Check",
"type": "main",
"index": 0
}
]
]
},
"05c0 IF: Operator Reply Failed?": {
"main": [
[
{
"node": "Telegram: Admin Alert — Operator Reply Failed",
"type": "main",
"index": 0
}
]
]
},
"05c1a Telegram: Notify Resolved": {
"main": [
[
{
"node": "Notify Failed?",
"type": "main",
"index": 0
}
]
]
},
"04c1a IF: Resolved or In Progress": {
"main": [
[
{
"node": "05c1a Telegram: Notify Resolved",
"type": "main",
"index": 0
}
],
[
{
"node": "05c1b Telegram: Notify In Progress",
"type": "main",
"index": 0
}
]
]
},
"05c Telegram: Update Confirmation": {
"main": [
[
{
"node": "05c0 IF: Operator Reply Failed?",
"type": "main",
"index": 0
}
]
]
},
"05c1b Telegram: Notify In Progress": {
"main": [
[
{
"node": "Notify Failed?",
"type": "main",
"index": 0
}
]
]
},
"01 Telegram Trigger: Intake + Status": {
"main": [
[
{
"node": "02 Switch: Route by Command",
"type": "main",
"index": 0
}
]
]
},
"03b IF: Has Valid Correlation ID Format": {
"main": [
[
{
"node": "03b1 IF: Has Correlation ID",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a text message2",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
我的工作流
使用Postgres和Telegram创建安全的人工审批流程
If
Code
Switch
+4
26 节点Mohammad
内容创作
完整的 B2B 销售流程:Apollo 潜在客户生成、Mailgun 外展和 AI 回复管理
完整的 B2B 销售流程:Apollo 潜在客户生成、Mailgun 外展和 AI 回复管理
If
Set
Code
+26
116 节点Paul
内容创作
我的工作流
卡路里追踪与饮食记录(Telegram、Gemini AI和数据表)
If
Set
Code
+13
73 节点Gerald Denor
内容创作
LinkedIn 自动化
使用Gemini AI和审批流程将Telegram消息转换为专业LinkedIn帖子
If
Set
Code
+13
54 节点Sateesh
内容创作
通过 Telegram 使用 Pollinations 生成图像和 Gemini 2.5 生成博客文章
通过 Telegram 使用 Pollinations 生成图像和 Gemini 2.5 生成博客文章
If
Set
Code
+9
34 节点Fahmi Oktafian
内容创作
美甲沙龙:主代理V2 Telegram版
集成Telegram、Claude和GPT5-mini的多智能体沙龙预约管理系统
If
Set
Code
+19
67 节点Denis
内容创作
工作流信息
难度等级
高级
节点数量45
分类2
节点类型7
作者
Mohammad
@mohammad-1378Automation consultant specializing in n8n workflows that save businesses time and reduce costs. Experienced in designing ticketing systems, email parsers, and integrations with Postgres, Telegram, and APIs. I publish workflows to help teams streamline operations and build internal efficiency.
外部链接
在 n8n.io 查看 →
分享此工作流