This workflow follows the Execute Workflow Trigger → Telegram 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 →
{
"name": "Tool - generate_excel_summary (V3)",
"nodes": [
{
"parameters": {
"workflowInputs": {
"values": [
{
"name": "chat_id"
},
{
"name": "items"
},
{
"name": "usage_count"
},
{
"name": "usage_limit"
}
]
}
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.2,
"position": [
1296,
112
],
"id": "3534320f-031b-4519-b9dd-8698dbcbe557",
"name": "When Executed by Another Workflow"
},
{
"parameters": {
"jsCode": "// \u4eceTrigger\u62ff\u5230AI Agent\u4f20\u6765\u7684\u5546\u54c1\u6e05\u5355JSON\u5b57\u7b26\u4e32,\u89e3\u6790\u6210\u7269\u4ef6\u9635\u5217\nconst items = JSON.parse($json.items);\nconst chatId = $json.chat_id;\n\n// \u5224\u65adspec\u3001stock_qty\u8fd92\u4e2a\"\u9009\u586b\"\u6b04\u4f4d,\u662f\u4e0d\u662f\u5168\u90e8\u54c1\u9879\u90fd\u6ca1\u586b\n// cost_price\u4e0d\u5728\u8fd9\u4e2a\u5224\u65ad\u8303\u56f4\u5185\u2014\u2014\u5b83\u6c38\u8fdc\u4fdd\u7559\u680f\u4f4d,\u6ca1\u503c\u5c31\u81ea\u52a8\u88650\nconst hasAnyValue = (key) => items.some(item =>\n item[key] !== null && item[key] !== undefined && item[key] !== ''\n);\n\nconst hasSpec = hasAnyValue('spec');\nconst hasStockQty = hasAnyValue('stock_qty');\n\n// \u524d\u6bb5\u6b04\u4f4d\u6e05\u5355,\u987a\u5e8f\u5b8c\u5168\u7167\u5b98\u65b9\u5546\u54c1\u5bfc\u5165\u6a21\u677f\u8d70\n// \u6761\u7801/\u6269\u5c55\u6761\u7801/\u8d77\u552e\u91cf/\u4e3b\u5355\u4f4d\u8fd94\u680f\u4e0d\u5728items schema\u7ba1\u7684\u8303\u56f4\u5185,\n// \u56fa\u5b9a\u5f53\u7a7a\u767d\u5360\u4f4d\u680f\u7559\u7740,\u4fdd\u6301\u6a21\u677f\u539f\u6709\u680f\u4f4d\u4e0d\u7f3a\u6f0f\nconst frontColumns = [\n { key: 'name', header: '\u540d\u79f0\uff08\u5fc5\u586b\uff09' },\n { key: 'category', header: '\u5206\u7c7b\uff08\u5fc5\u586b\uff09' },\n { key: '_placeholder', header: '\u6761\u7801' },\n { key: '_placeholder', header: '\u6269\u5c55\u6761\u7801' },\n ...(hasSpec ? [{ key: 'spec', header: '\u89c4\u683c' }] : []),\n { key: '_placeholder', header: '\u8d77\u552e\u91cf' },\n { key: '_placeholder', header: '\u4e3b\u5355\u4f4d' },\n ...(hasStockQty ? [{ key: 'stock_qty', header: '\u5e93\u5b58\u91cf' }] : []),\n { key: 'cost_price', header: '\u8fdb\u8d27\u4ef7\uff08\u5fc5\u586b\uff09' },\n { key: 'sell_price', header: '\u9500\u552e\u4ef7\uff08\u5fc5\u586b\uff09' },\n];\n\n// \u540e\u6bb525\u680f,\u7167\u5b98\u65b9\u6a21\u677f\u539f\u6837\u5217\u51fa,\u5404\u81ea\u914d\u4e00\u4e2aitem\u680f\u4f4dkey\u2014\u2014\n// \u76ee\u524ditems\u4ece\u6765\u4e0d\u4f1a\u5e26\u8fd9\u4e9bkey,\u6240\u4ee5\u73b0\u5728\u4f1a\u5168\u90e8\u88ab\u4e0b\u9762\u7684\u8fc7\u6ee4\u5668\u7701\u7565\u6389;\n// \u672a\u6765\u5982\u679cAI\u5f00\u59cb\u5224\u65ad\u8981\u4e0d\u8981\u81ea\u52a8\u586b\u8fd9\u4e9b\u9009\u586b\u680f\u4f4d\u3001item\u5e26\u4e0a\u5bf9\u5e94\u7684\u503c,\n// \u8fd9\u91cc\u4f1a\u81ea\u52a8\u4fa6\u6d4b\u5230\u3001\u81ea\u52a8\u628a\u90a3\u4e00\u680f\u52a0\u56de\u6765,\u4e0d\u7528\u518d\u6539\u4ee3\u7801\nconst trailingColumns = [\n { key: 'margin_rate', header: '\u6bdb\u5229\u7387' },\n { key: 'wholesale_price', header: '\u6279\u53d1\u4ef7' },\n { key: 'member_price', header: '\u4f1a\u5458\u4ef7' },\n { key: 'member_discount', header: '\u4f1a\u5458\u6298\u6263' },\n { key: 'point_item', header: '\u79ef\u5206\u5546\u54c1' },\n { key: 'stock_max', header: '\u5e93\u5b58\u4e0a\u9650' },\n { key: 'stock_min', header: '\u5e93\u5b58\u4e0b\u9650' },\n { key: 'location', header: '\u5e93\u4f4d' },\n { key: 'brand', header: '\u54c1\u724c' },\n { key: 'supplier', header: '\u4f9b\u8d27\u5546' },\n { key: 'production_date', header: '\u751f\u4ea7\u65e5\u671f' },\n { key: 'shelf_life', header: '\u4fdd\u8d28\u671f' },\n { key: 'pinyin_code', header: '\u62fc\u97f3\u7801' },\n { key: 'label_print', header: '\u6807\u7b7e\u6253\u5370' },\n { key: 'custom2', header: '\u81ea\u5b9a\u4e492' },\n { key: 'custom3', header: '\u81ea\u5b9a\u4e493' },\n { key: 'weight', header: '\u91cd\u91cf' },\n { key: 'is_weighed', header: '\u662f\u5426\u79f0\u91cd' },\n { key: 'is_scale_synced', header: '\u662f\u5426\u4f20\u79e4' },\n { key: 'is_countable', header: '\u662f\u5426\u8ba1\u6570\u5546\u54c1' },\n { key: 'scale_code', header: '\u79f0\u7f16\u7801' },\n { key: 'item_status', header: '\u5546\u54c1\u72b6\u6001' },\n { key: 'item_description', header: '\u5546\u54c1\u63cf\u8ff0' },\n { key: 'no_stock_count', header: '\u4e0d\u8ba1\u5e93\u5b58' },\n { key: 'creation_date', header: '\u521b\u5efa\u65e5\u671f' }\n];\n\n// \u6574\u6392\u90fd\u662fnull/\u7a7a\u5b57\u7b26\u4e32\u7684trailing\u680f\u4f4d,\u4e0d\u751f\u6210\u5230Excel\u91cc\nconst activeTrailingColumns = trailingColumns.filter(col => hasAnyValue(col.key));\n\nconst ExcelJS = require('exceljs');\nconst workbook = new ExcelJS.Workbook();\nconst ws = workbook.addWorksheet('Sheet1');\n\nlet colIndex = 1;\nfrontColumns.forEach(col => {\n ws.getCell(1, colIndex).value = col.header;\n colIndex++;\n});\nactiveTrailingColumns.forEach(col => {\n ws.getCell(1, colIndex).value = col.header;\n colIndex++;\n});\n\n// \u5199\u6bcf\u4e00\u884c\u5546\u54c1\u6570\u636e\n// cost_price\u7528 Number(val) || 0,val\u5982\u679c\u662fundefined/null/\u7a7a\u5b57\u7b26\u4e32,\n// \u8fd0\u7b97\u7ed3\u679c\u90fd\u4f1a\u662f0,\u6b63\u597d\u8fbe\u5230\"\u7528\u6237\u6ca1\u7ed9\u5c31\u81ea\u52a8\u88650\"\u7684\u6548\u679c\nitems.forEach((item, rowIdx) => {\n const r = rowIdx + 2;\n let c = 1;\n frontColumns.forEach(col => {\n if (col.key === '_placeholder') {\n c++;\n return;\n }\n let val = item[col.key];\n if (col.key === 'sell_price' || col.key === 'cost_price') {\n ws.getCell(r, c).value = Number(val) || 0;\n ws.getCell(r, c).numFmt = '0.00';\n } else if (col.key === 'stock_qty') {\n ws.getCell(r, c).value = val ?? 0;\n } else {\n ws.getCell(r, c).value = val || '';\n }\n c++;\n });\n activeTrailingColumns.forEach(col => {\n const val = item[col.key];\n ws.getCell(r, c).value = (val !== null && val !== undefined) ? val : '';\n c++;\n });\n});\n\nconst buffer = await workbook.xlsx.writeBuffer();\nconst base64 = buffer.toString('base64');\n\n// \u6863\u540d\u7528\u5e74\u6708\u65e5\u65f6\u5206\u79d2\u5f53\u65f6\u95f4\u6233,\u907f\u514d\u649e\u540d\nconst now = new Date();\nconst pad = (n) => String(n).padStart(2, '0');\nconst timestamp = `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;\n\nreturn [{\n json: {\n chat_id: chatId,\n itemCount: items.length,\n usage_count: $json.usage_count,\n usage_limit: $json.usage_limit\n },\n binary: {\n file: {\n data: base64,\n mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n fileName: `menu_import_${timestamp}.xlsx`\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1616,
112
],
"id": "8c2df2b5-fbd7-4d9a-9eff-015591d3f795",
"name": "\u751f\u6210\u5546\u54c1\u5bfc\u5165\u8868"
},
{
"parameters": {
"operation": "sendDocument",
"chatId": "={{ $json.chat_id }}",
"binaryData": true,
"binaryPropertyName": "file",
"additionalFields": {
"caption": "=\u2705 \u5df2\u7ecf\u4e3a\u60a8\u6574\u7406\u597d\u83dc\u5355,\u5e76\u751f\u6210\u4e86\u5bf9\u5e94\u7684\u5bfc\u5165\u6587\u4ef6\u3002\u672c\u6b21\u6574\u7406\u5171\u5305\u542b {{ $json.itemCount }} \u4e2a\u5546\u54c1,\u8bf7\u95ee\u8fd8\u9700\u8981\u6dfb\u52a0\u5176\u4ed6\u5546\u54c1\u5417\uff1f\u6216\u8005\u9700\u8981\u6211\u4e3a\u60a8\u751f\u6210POS\u5bfc\u5165\u6a21\u677f\u5417\uff1f\n\n\ud83d\udcca \u4eca\u65e5AI\u5904\u7406\u6b21\u6570\uff1a{{ $json.usage_count }}/{{ $json.usage_limit }}",
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1824,
112
],
"id": "1447a4bb-b992-4f7a-9c58-9973be39fbd3",
"name": "Send a document",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('\u751f\u6210\u5546\u54c1\u5bfc\u5165\u8868').item.json.chat_id }}",
"text": "\u8fd9\u6b21\u7684\u8bc6\u522b\u6548\u679c\u600e\u4e48\u6837\uff1f\u6709\u4ec0\u4e48\u60f3\u8ba9\u6211\u6539\u8fdb\u7684\u53ef\u4ee5\u76f4\u63a5\u6253\u5b57\u544a\u8bc9\u6211 \ud83d\ude4f",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "\u2b50",
"additionalFields": {
"callback_data": "rate_1"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u2b50\u2b50",
"additionalFields": {
"callback_data": "rate_2"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u2b50\u2b50\u2b50",
"additionalFields": {
"callback_data": "rate_3"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u2b50\u2b50\u2b50\u2b50",
"additionalFields": {
"callback_data": "rate_4"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u2b50\u2b50\u2b50\u2b50\u2b50",
"additionalFields": {
"callback_data": "rate_5"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\ud83d\udd27 \u9700\u8981\u4fee\u6539",
"additionalFields": {
"callback_data": "modify"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u2705 \u7ed3\u675f\u8fd0\u884c",
"additionalFields": {
"callback_data": "end_modify"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2032,
112
],
"id": "1d403650-46ad-4f42-92a7-048f87b8a777",
"name": "Send a text message",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"When Executed by Another Workflow": {
"main": [
[
{
"node": "\u751f\u6210\u5546\u54c1\u5bfc\u5165\u8868",
"type": "main",
"index": 0
}
]
]
},
"\u751f\u6210\u5546\u54c1\u5bfc\u5165\u8868": {
"main": [
[
{
"node": "Send a document",
"type": "main",
"index": 0
}
]
]
},
"Send a document": {
"main": [
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "7af51ab1-9e1c-4cd9-88c7-7bc4ef8fcd17",
"nodeGroups": [],
"id": "5m7xS062vlea0Cv3",
"tags": [
{
"updatedAt": "2026-07-27T07:50:01.682Z",
"createdAt": "2026-07-27T07:50:01.682Z",
"id": "oulTjbe8ViVdh1V7",
"name": "AUTO-P1-V3"
},
{
"updatedAt": "2026-07-20T07:40:54.445Z",
"createdAt": "2026-07-20T07:40:54.445Z",
"id": "sBao71AvdSJ3hx2O",
"name": "3FS"
}
]
}
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.
telegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Tool - generate_excel_summary (V3). Uses executeWorkflowTrigger, telegram. Event-driven trigger; 4 nodes.
Source: https://github.com/Heng1028/pos-telegrambot-v3/blob/main/tool-generate-excel-summary.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
06 - Email Sender. Uses executeWorkflowTrigger, sqlite, googlePaLmChatModel, telegram. Event-driven trigger; 8 nodes.
This comprehensive N8N automation template revolutionizes content creation by delivering a complete end-to-end solution for AI-powered blog generation. Transform simple ideas into fully SEO-optimized,
Template was created in n8n v1.90.2 Execute Sub-workflow Trigger node Chat Trigger node Redis node Postgres node Telegram node HTTP Request node If node, Code node, Edit Fields (Set) Execute Sub-workf
SRT Translator. Uses formTrigger, executeWorkflowTrigger, form, telegramTrigger. Event-driven trigger; 34 nodes.
Menu-Handler. Uses telegramTrigger, chatTrigger, executeWorkflowTrigger, chainLlm. Event-driven trigger; 28 nodes.