This workflow corresponds to n8n.io template #14550 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets Tool 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ad0e705c-dfd7-4861-adce-2e11c8304e51",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
1440,
208
],
"parameters": {
"updates": [
"message",
"callback_query"
],
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "d71f44ac-57f2-44f1-a173-89af6081261e",
"name": "Extract Message",
"type": "n8n-nodes-base.code",
"position": [
1664,
208
],
"parameters": {
"jsCode": "const u = $input.first().json;\nlet chatId, text, firstName;\n\nif (u.callback_query) {\n chatId = String(u.callback_query.message.chat.id);\n text = u.callback_query.data;\n firstName = u.callback_query.from.first_name || 'there';\n} else if (u.message) {\n chatId = String(u.message.chat.id);\n text = u.message.text || '';\n firstName = u.message.from.first_name || 'there';\n} else {\n return [];\n}\n\nreturn [{ json: { chatId, text: text.trim(), firstName, sessionKey: chatId } }];"
},
"typeVersion": 2
},
{
"id": "d1362c39-149c-4ff0-b246-91b9b07363a3",
"name": "Is /start?",
"type": "n8n-nodes-base.if",
"position": [
1936,
208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.text }}",
"rightValue": "/start"
}
]
}
},
"typeVersion": 2
},
{
"id": "93aa7968-7ddc-413c-a275-33f0ff3dc058",
"name": "Send Welcome Menu",
"type": "n8n-nodes-base.telegram",
"position": [
2320,
192
],
"parameters": {
"text": "={{ '\ud83d\udc4b Hello *' + $json.firstName + '*! Welcome to our Support Bot.\\n\\nHow can I help you today?' }}",
"chatId": "={{ $json.chatId }}",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "\ud83d\udce6 Track My Order",
"additionalFields": {
"callback_data": "Track my order"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\u274c Cancel My Order",
"additionalFields": {
"callback_data": "I want to cancel my order"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\ud83c\udfab Talk to Support",
"additionalFields": {
"callback_data": "I need to talk to support"
}
}
]
}
}
]
},
"additionalFields": {
"parse_mode": "Markdown"
}
},
"typeVersion": 1.2
},
{
"id": "a463b4b0-38f9-4cc6-846c-8b093b5f28bb",
"name": "Customer Support AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2304,
352
],
"parameters": {
"text": "={{ $json.text }}",
"options": {
"systemMessage": "You are a friendly e-commerce customer support bot. The customer's name is {{ $('Extract Message').first().json.firstName }} and their Telegram chat ID is {{ $('Extract Message').first().json.chatId }}.\n\nYou have 3 tools available:\n- **Tool: Read Orders Sheet** \u2014 reads ALL order rows. Use to find an order by order_id or email.\n- **Tool: Update Order Status** \u2014 updates an order's Status column. Use to cancel orders.\n- **Tool: Create Support Ticket** \u2014 appends a new ticket row to the support sheet.\n\n---\n\n## HOW TO HANDLE EACH INTENT\n\n### \"Track my order\" / \"order status\":\n1. Ask: \"Please provide your Order ID or email address.\"\n2. Call **Tool: Read Orders Sheet** \u2014 it returns all rows.\n3. Filter rows to find where order_id or email matches what the user gave.\n4. Reply with:\n```\n\ud83d\udce6 *Order Details*\n\n\ud83c\udd94 Order ID: [order_id]\n\ud83d\udc64 Customer: [customer_name]\n\ud83d\udecd Product: [product]\n\u23f3 Status: [Status]\n\ud83d\udcc5 Date: [date]\n```\nIf not found: \"\u274c No order found. Please check your Order ID or email.\"\n\n### \"Cancel my order\":\n1. Ask for Order ID or email if not provided.\n2. Call **Tool: Read Orders Sheet** to find the order.\n3. Check the Status:\n - \"Shipped\" \u2192 \"\u26a0\ufe0f Cannot cancel \u2014 order already shipped. Please contact support.\"\n - \"Cancelled\" \u2192 \"\u2139\ufe0f This order is already cancelled.\"\n - Any other status \u2192 Ask: \"\u26a0\ufe0f Are you sure you want to cancel Order [order_id] (Status: [Status])? Reply YES to confirm or NO to keep it.\"\n4. On YES: Call **Tool: Update Order Status** with order_id and Status = \"Cancelled\". Then reply: \"\u2705 Order [order_id] has been cancelled successfully.\"\n5. On NO: \"\ud83d\udc4d No problem! Your order has not been cancelled.\"\n\n### \"Talk to support\" / \"I have an issue\":\n1. Ask for: Name, and their query/issue. Also ask for Order ID if relevant.\n2. Once you have name + query, call **Tool: Create Support Ticket**.\n3. After the tool call, YOU MUST reply with this message (replace the values):\n \"\ud83c\udfab *Support Ticket Created!*\n\n\u2705 Thank you, [name]!\n\n\ud83d\udccb *Your issue:* [one sentence summary]\n\ud83c\udff7 *Category:* [Payment/Shipping/Product Issue/Other]\n\n\ud83c\udf9f *Ticket ID:* [the ticket_id you used]\n\nOur team will contact you soon. Type /start to go back to the menu.\"\n\n---\n\n## CRITICAL RULES\n- After calling any tool, ALWAYS send a text reply to the user. Never end without a message.\n- Never say \"I have submitted\" without also telling the user their ticket ID.\n- Keep replies concise and friendly.\n- Use Markdown formatting (*bold*, _italic_).\n- If user greets or types something unclear, list the 3 options they can choose from."
},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "6466f250-47a7-40c0-b68d-f17d9391d24b",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2112,
576
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "ac476401-85a7-4ba8-adb4-b7910e063655",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2240,
576
],
"parameters": {
"sessionKey": "={{ $('Extract Message').first().json.sessionKey }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "70fd7444-f981-4e25-93b2-815dbcf58107",
"name": "Tool: Read Orders Sheet",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
2368,
576
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Yw7vq8iZ3geCCEyst-JpAwfICX1zxUtF0et71muqiT0",
"cachedResultName": "order data"
},
"descriptionType": "manual",
"toolDescription": "Reads ALL rows from the orders Google Sheet. Returns all order data including order_id, customer_name, email, product, Status, date. Use this whenever you need to look up an order by order_id or email address."
},
"typeVersion": 4.5
},
{
"id": "fb84c717-cf3c-4517-bbc2-776124f3b985",
"name": "Tool: Update Order Status",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
2496,
576
],
"parameters": {
"columns": {
"value": {
"Status": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Status', 'The new status. Use Cancelled to cancel an order.', 'string') }}",
"order_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('order_id', 'The order ID to update', 'string') }}"
},
"schema": [
{
"id": "order_id",
"type": "string",
"display": true,
"required": false,
"displayName": "order_id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"order_id"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Yw7vq8iZ3geCCEyst-JpAwfICX1zxUtF0et71muqiT0",
"cachedResultName": "order data"
},
"descriptionType": "manual",
"toolDescription": "Updates the Status of an order in the orders sheet. Use this to cancel an order after user confirms. Provide the order_id and set Status to 'Cancelled'."
},
"typeVersion": 4.5
},
{
"id": "96b463c5-be0b-43f4-9203-7e9c87c7ca70",
"name": "Tool: Create Support Ticket",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
2624,
576
],
"parameters": {
"columns": {
"value": {
"name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('name', 'Customer full name', 'string') }}",
"query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('query', 'Full customer query text', 'string') }}",
"status": "Pending",
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('summary', 'One sentence summary of the issue', 'string') }}",
"category": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('category', 'Issue category: Payment, Shipping, Product Issue, or Other', 'string') }}",
"order_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('order_id', 'Related order ID if any, otherwise empty string', 'string') }}",
"ticket_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('ticket_id', 'Unique ticket ID in format TKT-XXXX where XXXX is 4 random digits', 'string') }}",
"created_at": "={{ new Date().toISOString() }}",
"telegram_id": "={{ $('Extract Message').first().json.chatId }}"
},
"schema": [
{
"id": "ticket_id",
"type": "string",
"display": true,
"required": false,
"displayName": "ticket_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "name",
"type": "string",
"display": true,
"required": false,
"displayName": "name",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "order_id",
"type": "string",
"display": true,
"required": false,
"displayName": "order_id",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "query",
"type": "string",
"display": true,
"required": false,
"displayName": "query",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "summary",
"type": "string",
"display": true,
"required": false,
"displayName": "summary",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "category",
"type": "string",
"display": true,
"required": false,
"displayName": "category",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "created_at",
"type": "string",
"display": true,
"required": false,
"displayName": "created_at",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "telegram_id",
"type": "string",
"display": true,
"required": false,
"displayName": "telegram_id",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1RNXRi_WaJbyYnIFOM8YJePUbN-hfEXis0dpbWXGfLmw",
"cachedResultName": "support data"
},
"descriptionType": "manual",
"toolDescription": "Creates a new support ticket by appending a row to the support sheet. Use this after collecting customer name and query. Generate a unique ticket_id like TKT-XXXX (random 4 digits). Fill summary with a 1-sentence description. Set category to one of: Payment, Shipping, Product Issue, Other. Set status to Pending."
},
"typeVersion": 4.5
},
{
"id": "24d58366-367c-4201-beb8-511fcb720e41",
"name": "Prepare Reply",
"type": "n8n-nodes-base.code",
"position": [
2816,
352
],
"parameters": {
"jsCode": "const output = $input.first().json.output || '';\nconst chatId = $('Extract Message').first().json.chatId;\n\nif (!output || output.trim() === '') {\n return [{ json: { chatId, text: \"\u2705 Done! Is there anything else I can help you with? Type /start to see the main menu.\" } }];\n}\n\nreturn [{ json: { chatId, text: output } }];"
},
"typeVersion": 2
},
{
"id": "9e5b19b6-b4f0-470d-b872-48374cdd2434",
"name": "Send Telegram Reply",
"type": "n8n-nodes-base.telegram",
"position": [
3056,
352
],
"parameters": {
"text": "={{ $json.text }}",
"chatId": "={{ $json.chatId }}",
"additionalFields": {
"parse_mode": "Markdown",
"appendAttribution": false
}
},
"typeVersion": 1.2
},
{
"id": "3f475bb5-82e0-4a52-9e97-5c59a210e453",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1072,
192
],
"parameters": {
"color": 7,
"width": 316,
"height": 148,
"content": "### \u2699\ufe0f Setup Required\n1. Add your **Telegram Bot** credential\n2. Add **Google Gemini API** credential\n3. Add **Google Sheets OAuth2** credential\n4. Update Sheet IDs if needed\n5. Activate workflow and register webhook"
},
"typeVersion": 1
},
{
"id": "a46ef2d4-0b40-4437-adcc-1814ddb1679f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
48
],
"parameters": {
"width": 524,
"height": 324,
"content": "### \ud83e\udd16 Telegram AI Support Bot\n\nThis workflow manages customer interactions via Telegram, using an AI Agent to handle order tracking, cancellations, and support tickets automatically.\n\n"
},
"typeVersion": 1
},
{
"id": "65cfab64-0aa0-4860-8a22-0b9b04801676",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1616,
0
],
"parameters": {
"color": 5,
"width": 220,
"height": 372,
"content": "### Step-1: Inbound & Extraction\n\n\nReceives messages or button clicks and cleans the data (Chat ID, Name, Text) for the rest of the flow."
},
"typeVersion": 1
},
{
"id": "ce43f23f-c3ef-4dd4-888c-9e2ebd64cb2e",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1888,
0
],
"parameters": {
"color": 5,
"width": 236,
"height": 372,
"content": "### Steo-2: Logic Router\n\nChecks if the user typed **/start**.\n\n- **True:** Shows the main menu buttons.\n- **False:** Passes the query to the AI Agent.\n"
},
"typeVersion": 1
},
{
"id": "647bf8f3-ade2-41f2-9519-cc813b222213",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2176,
0
],
"parameters": {
"color": 5,
"width": 492,
"height": 516,
"content": "### Step-3: AI Agent & Google Sheets Tools\n\nThe **Gemini-powered Agent** uses context and memory to decide which tool to use:\n- **Read Orders:** To track status.\n- **Update Orders:** To handle cancellations.\n- **Create Ticket:** To log issues in the support sheet.\""
},
"typeVersion": 1
},
{
"id": "8524c032-e401-400f-95ee-ba06975e298a",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2736,
192
],
"parameters": {
"color": 5,
"width": 524,
"height": 324,
"content": "### Step-4: Response Delivery\n\n\nFormats the AI output into a user-friendly message and sends it back to Telegram."
},
"typeVersion": 1
}
],
"connections": {
"Is /start?": {
"main": [
[
{
"node": "Send Welcome Menu",
"type": "main",
"index": 0
}
],
[
{
"node": "Customer Support AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Prepare Reply": {
"main": [
[
{
"node": "Send Telegram Reply",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "Customer Support AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Extract Message": {
"main": [
[
{
"node": "Is /start?",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Extract Message",
"type": "main",
"index": 0
}
]
]
},
"Tool: Read Orders Sheet": {
"ai_tool": [
[
{
"node": "Customer Support AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Customer Support AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Customer Support AI Agent": {
"main": [
[
{
"node": "Prepare Reply",
"type": "main",
"index": 0
}
]
]
},
"Tool: Update Order Status": {
"ai_tool": [
[
{
"node": "Customer Support AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Tool: Create Support Ticket": {
"ai_tool": [
[
{
"node": "Customer Support AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
An AI-powered Telegram bot that automates customer support for e-commerce stores — handling order tracking, order cancellations, and support ticket creation, all without human intervention.
Source: https://n8n.io/workflows/14550/ — 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.
Telegram Trigger receives incoming messages (text, voice, photo, document). Switch routes by message type to appropriate processors: Text → forwarded as-is. Voice → downloaded and sent to Transcribe a
Transform your Telegram messenger into a powerful, multi-modal personal or team assistant. This n8n workflow creates an intelligent agent that can understand text, voice, images, and documents, and ta
> AI-powered nutrition assistant for Telegram — log meals, set goals, and get personalized daily reports with Google Sheets integration.
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.
Rizz AI is not just a chatbot; it's a full-featured, AI-powered CRM for your dating life.