This workflow corresponds to n8n.io template #10385 — we link there as the canonical source.
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 →
{
"id": "VSvhSHg8Qnpr8mEg",
"name": "Telegram Auto-Translation Relay Bot",
"tags": [],
"nodes": [
{
"id": "334fd0bb-01af-4874-8e13-39617a7f35d9",
"name": "Webhook - Incoming Message",
"type": "n8n-nodes-base.webhook",
"notes": "Receives incoming messages from chat platforms (Telegram, Slack, Discord, etc.)",
"position": [
-304,
96
],
"parameters": {
"path": "translate-relay",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1.1
},
{
"id": "ec936c37-bd14-4436-91cd-55e85171a238",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-368,
-96
],
"parameters": {
"color": 4,
"height": 336,
"content": "## \ud83d\udce5 WEBHOOK ENTRY\nReceives incoming messages with:\n- Message text\n- Sender ID\n- Group ID"
},
"typeVersion": 1
},
{
"id": "aa988c16-bd2e-44cc-89c3-db8119de94f0",
"name": "Extract Message Data",
"type": "n8n-nodes-base.code",
"notes": "Parses webhook payload and extracts message, sender, and group information",
"position": [
-96,
96
],
"parameters": {
"jsCode": "// Extract message data from webhook payload\nconst messageText = $input.item.json.body.message || $input.item.json.body.text;\nconst senderId = $input.item.json.body.sender_id || $input.item.json.body.user_id;\nconst groupId = $input.item.json.body.group_id || $input.item.json.body.chat_id;\nconst senderName = $input.item.json.body.sender_name || 'User';\n\nreturn {\n json: {\n originalMessage: messageText,\n senderId: senderId,\n groupId: groupId,\n senderName: senderName,\n timestamp: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "f5e76353-19ae-41ae-b081-6be35f733086",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-80
],
"parameters": {
"color": 5,
"width": 220,
"height": 316,
"content": "## \ud83d\udd0d DATA EXTRACTION\nExtracts key fields from incoming payload"
},
"typeVersion": 1
},
{
"id": "1b9baf80-d7ea-42ba-b985-9f70339acf38",
"name": "Detect Language (OpenAI)",
"type": "n8n-nodes-base.httpRequest",
"notes": "Uses OpenAI to detect the source language of the incoming message",
"position": [
128,
96
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-3.5-turbo"
},
{
"name": "messages",
"value": "=[{\"role\": \"system\", \"content\": \"Detect the language of the following text and respond with only the ISO 639-1 language code (e.g., 'en' for English, 'es' for Spanish, 'fr' for French, 'de' for German, 'hi' for Hindi, 'ar' for Arabic, etc.). Respond with only the two-letter code.\"}, {\"role\": \"user\", \"content\": \"{{ $json.originalMessage }}\"}]"
},
{
"name": "temperature",
"value": "0.3"
},
{
"name": "max_tokens",
"value": "10"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "e41c6bf8-4f9c-462b-b537-6b6a7d058305",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
-80
],
"parameters": {
"color": 6,
"width": 220,
"height": 316,
"content": "## \ud83c\udf10 LANGUAGE DETECTION\nIdentifies source language using AI"
},
"typeVersion": 1
},
{
"id": "defcc8cf-3e60-4fab-aec7-1ee38af266c4",
"name": "Parse Detected Language",
"type": "n8n-nodes-base.code",
"notes": "Extracts and stores the detected language code from AI response",
"position": [
352,
96
],
"parameters": {
"jsCode": "// Extract detected language code\nconst detectedLanguage = $input.item.json.choices[0].message.content.trim().toLowerCase();\n\nreturn {\n json: {\n ...($input.item.json),\n detectedLanguage: detectedLanguage,\n originalMessage: $('Extract Message Data').item.json.originalMessage,\n senderId: $('Extract Message Data').item.json.senderId,\n groupId: $('Extract Message Data').item.json.groupId,\n senderName: $('Extract Message Data').item.json.senderName\n }\n};"
},
"typeVersion": 2
},
{
"id": "845f51c6-f222-4b00-bf22-45d5047959b5",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
-80
],
"parameters": {
"color": 5,
"width": 220,
"height": 316,
"content": "## \ud83d\udccb LANGUAGE PARSING\nStores detected language code"
},
"typeVersion": 1
},
{
"id": "dab99bae-3799-4329-8236-1ad92e1fcd62",
"name": "Get Group Members & Languages",
"type": "n8n-nodes-base.code",
"notes": "Retrieves group members and their language preferences, creates translation tasks",
"position": [
576,
96
],
"parameters": {
"jsCode": "// Define group members and their preferred languages\n// In production, this would come from a database\nconst groupMembers = {\n 'group_123': [\n { userId: 'user_1', name: 'John', language: 'en' },\n { userId: 'user_2', name: 'Mar\u00eda', language: 'es' },\n { userId: 'user_3', name: 'Pierre', language: 'fr' },\n { userId: 'user_4', name: 'Hans', language: 'de' },\n { userId: 'user_5', name: 'Rajesh', language: 'hi' },\n { userId: 'user_6', name: 'Ahmed', language: 'ar' },\n { userId: 'user_7', name: 'Yuki', language: 'ja' },\n { userId: 'user_8', name: 'Wei', language: 'zh' }\n ]\n};\n\nconst groupId = $input.item.json.groupId;\nconst senderId = $input.item.json.senderId;\nconst detectedLanguage = $input.item.json.detectedLanguage;\n\n// Get all members of the group except the sender\nconst members = groupMembers[groupId] || [];\nconst recipients = members.filter(member => member.userId !== senderId);\n\n// Get unique target languages\nconst targetLanguages = [...new Set(recipients.map(r => r.language))];\n\n// Remove the source language from targets if present\nconst languagesToTranslate = targetLanguages.filter(lang => lang !== detectedLanguage);\n\nreturn languagesToTranslate.map(language => ({\n json: {\n targetLanguage: language,\n originalMessage: $input.item.json.originalMessage,\n detectedLanguage: detectedLanguage,\n senderId: senderId,\n senderName: $input.item.json.senderName,\n groupId: groupId,\n recipients: recipients.filter(r => r.language === language)\n }\n}));"
},
"typeVersion": 2
},
{
"id": "b78baf28-17db-44f6-80f8-25c1b280ebcc",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
-80
],
"parameters": {
"color": 4,
"height": 316,
"content": "## \ud83d\udc65 GROUP MEMBERS\nFetches recipient list and their preferred languages"
},
"typeVersion": 1
},
{
"id": "e9118f93-8d9e-404d-bbf6-e2ff2cd6af1d",
"name": "Translate Message (OpenAI)",
"type": "n8n-nodes-base.httpRequest",
"notes": "Translates the original message to each target language using AI",
"position": [
816,
96
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-3.5-turbo"
},
{
"name": "messages",
"value": "=[{\"role\": \"system\", \"content\": \"You are a professional translator. Translate the following text to {{ $json.targetLanguage }}. Provide only the translation without any additional text or explanations.\"}, {\"role\": \"user\", \"content\": \"{{ $json.originalMessage }}\"}]"
},
{
"name": "temperature",
"value": "0.3"
},
{
"name": "max_tokens",
"value": "500"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "f3661592-3e4c-439d-b12e-0c0eee12857e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
784,
-80
],
"parameters": {
"color": 6,
"width": 384,
"height": 316,
"content": "## \ud83d\udd04 TRANSLATION ENGINE\nTranslates message to target languages and Wait for answer"
},
"typeVersion": 1
},
{
"id": "69d8915d-ee59-486e-b8ac-9001feb83aaf",
"name": "Format Translation Result",
"type": "n8n-nodes-base.code",
"notes": "Combines translated text with recipient information for delivery",
"position": [
1232,
96
],
"parameters": {
"jsCode": "// Extract translated text and combine with recipient info\nconst translatedText = $input.item.json.choices[0].message.content.trim();\nconst originalData = $('Get Group Members & Languages').item.json;\n\nreturn {\n json: {\n translatedMessage: translatedText,\n targetLanguage: originalData.targetLanguage,\n originalMessage: originalData.originalMessage,\n senderName: originalData.senderName,\n recipients: originalData.recipients,\n groupId: originalData.groupId\n }\n};"
},
"typeVersion": 2
},
{
"id": "b8085dda-e25d-471d-9718-538b6ac44101",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
-80
],
"parameters": {
"color": 5,
"width": 220,
"height": 316,
"content": "## \ud83d\udcdd FORMAT RESULTS\nPrepares translated messages with metadata"
},
"typeVersion": 1
},
{
"id": "d1ff1f34-0d49-4fae-aaea-b3bea85e07af",
"name": "Split to Individual Recipients",
"type": "n8n-nodes-base.code",
"notes": "Creates separate message items for each recipient in the target language",
"position": [
1456,
96
],
"parameters": {
"jsCode": "// Create individual messages for each recipient\nconst recipients = $input.item.json.recipients;\nconst translatedMessage = $input.item.json.translatedMessage;\nconst senderName = $input.item.json.senderName;\nconst targetLanguage = $input.item.json.targetLanguage;\n\nreturn recipients.map(recipient => ({\n json: {\n recipientId: recipient.userId,\n recipientName: recipient.name,\n recipientLanguage: recipient.language,\n message: `${senderName}: ${translatedMessage}`,\n translatedMessage: translatedMessage,\n senderName: senderName,\n targetLanguage: targetLanguage\n }\n}));"
},
"typeVersion": 2
},
{
"id": "cd7c4bc1-bb5b-4018-b17d-66812ac8798a",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1392,
-80
],
"parameters": {
"color": 4,
"width": 220,
"height": 316,
"content": "## \ud83d\udce4 RECIPIENT SPLIT\nCreates individual delivery items"
},
"typeVersion": 1
},
{
"id": "95e0386a-4913-4fef-b469-971097cf886a",
"name": "Send Translated Message",
"type": "n8n-nodes-base.httpRequest",
"notes": "Delivers translated message to each recipient via chat platform API",
"position": [
1680,
96
],
"parameters": {
"url": "https://api.your-chat-platform.com/send",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "recipient_id",
"value": "={{ $json.recipientId }}"
},
{
"name": "message",
"value": "={{ $json.message }}"
},
{
"name": "language",
"value": "={{ $json.recipientLanguage }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "41a6a1ef-780b-459d-b700-0e94e58d6528",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1600,
-80
],
"parameters": {
"color": 6,
"width": 220,
"height": 316,
"content": "## \ud83d\udce8 MESSAGE DELIVERY\nSends translated messages to recipients"
},
"typeVersion": 1
},
{
"id": "48539383-fb0c-4234-84cf-5ddc696c7e0d",
"name": "Log Delivery Status",
"type": "n8n-nodes-base.code",
"notes": "Records delivery status for monitoring and analytics",
"position": [
1904,
96
],
"parameters": {
"jsCode": "// Log successful delivery\nconst deliveryLog = {\n timestamp: new Date().toISOString(),\n recipientId: $input.item.json.recipientId,\n recipientName: $('Split to Individual Recipients').item.json.recipientName,\n language: $('Split to Individual Recipients').item.json.targetLanguage,\n status: 'delivered',\n messageLength: $('Split to Individual Recipients').item.json.translatedMessage.length\n};\n\nreturn {\n json: deliveryLog\n};"
},
"typeVersion": 2
},
{
"id": "55ba798e-91e3-4349-a86a-2bbb25d98a24",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1824,
-80
],
"parameters": {
"color": 5,
"width": 220,
"height": 316,
"content": "## \ud83d\udcca DELIVERY LOGGING\nTracks successful message deliveries"
},
"typeVersion": 1
},
{
"id": "6c024f54-ae29-4860-8726-a62277a2e710",
"name": "Webhook Response",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "Sends success response back to the webhook caller",
"position": [
2112,
96
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ { \"status\": \"success\", \"message\": \"Translation relay completed\", \"deliveries\": $items().length } }}"
},
"typeVersion": 1.1
},
{
"id": "322b28ef-0f72-4578-8441-623d693b0963",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
2048,
-80
],
"parameters": {
"color": 4,
"width": 200,
"height": 316,
"content": "## \u2705 RESPONSE\nConfirms successful translation relay"
},
"typeVersion": 1
},
{
"id": "fb9d20ac-4e01-437c-a74c-b7bd0f88a8d8",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
-624
],
"parameters": {
"color": 7,
"width": 380,
"height": 408,
"content": "## \ud83e\udd16 TRANSLATION RELAY BOT\n\n**Workflow:** Detects message language \u2192 Translates \u2192 Delivers to multilingual group\n\n**Features:**\n\u2713 Automatic language detection\n\u2713 Multi-language translation\n\u2713 Individual recipient delivery\n\u2713 Delivery tracking\n\n**Setup Required:**\n1. Add OpenAI API credentials\n2. Configure chat platform API\n3. Update group member database\n4. Test webhook endpoint"
},
"typeVersion": 1
},
{
"id": "980314c5-5690-4901-a971-426f94d12b31",
"name": "Wait For Answer",
"type": "n8n-nodes-base.wait",
"position": [
1024,
96
],
"parameters": {},
"typeVersion": 1.1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "63ee52ca-bb22-470a-9c65-5c0afc182db4",
"connections": {
"Wait For Answer": {
"main": [
[
{
"node": "Format Translation Result",
"type": "main",
"index": 0
}
]
]
},
"Log Delivery Status": {
"main": [
[
{
"node": "Webhook Response",
"type": "main",
"index": 0
}
]
]
},
"Extract Message Data": {
"main": [
[
{
"node": "Detect Language (OpenAI)",
"type": "main",
"index": 0
}
]
]
},
"Parse Detected Language": {
"main": [
[
{
"node": "Get Group Members & Languages",
"type": "main",
"index": 0
}
]
]
},
"Send Translated Message": {
"main": [
[
{
"node": "Log Delivery Status",
"type": "main",
"index": 0
}
]
]
},
"Detect Language (OpenAI)": {
"main": [
[
{
"node": "Parse Detected Language",
"type": "main",
"index": 0
}
]
]
},
"Format Translation Result": {
"main": [
[
{
"node": "Split to Individual Recipients",
"type": "main",
"index": 0
}
]
]
},
"Translate Message (OpenAI)": {
"main": [
[
{
"node": "Wait For Answer",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Incoming Message": {
"main": [
[
{
"node": "Extract Message Data",
"type": "main",
"index": 0
}
]
]
},
"Get Group Members & Languages": {
"main": [
[
{
"node": "Translate Message (OpenAI)",
"type": "main",
"index": 0
}
]
]
},
"Split to Individual Recipients": {
"main": [
[
{
"node": "Send Translated Message",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
SmartPoll Automator is an n8n-powered workflow that automatically creates and publishes polls in Telegram. It helps teams, communities, and businesses run polls without manual work.
Source: https://n8n.io/workflows/10385/ — 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.
Advanced Slackbot With N8N. Uses slack, httpRequest, stickyNote, executeWorkflow. Webhook trigger; 34 nodes.
Slackbots are super powerful. At n8n, we have been using them to get a lot done.. But it can become hard to manage and maintain many different operations that a workflow can do.
Standup Bot 4 4 Worker. Uses mattermost, httpRequest, noOp, executeWorkflow. Webhook trigger; 29 nodes.
This is the fourth workflow for the Mattermost Standup Bot. This workflow sends the team a message every morning to ask them three standup questions. What have you accomplished since your last report?
CV Slack Bot: Save to Sheet & Card Actions. Uses googleSheets, httpRequest. Webhook trigger; 14 nodes.