This workflow follows the HTTP Request → 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 →
{
"id": "gpsTelegramFlota01",
"name": "Telegram \u2192 Estatus de flota / RAG \u2192 Reply",
"nodes": [
{
"parameters": {},
"id": "TelegramTrigger",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1,
"position": [
-880,
0
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"keepOnlySet": true,
"values": {
"string": [
{
"name": "chat_id",
"value": "={{$json[\"message\"][\"chat\"][\"id\"]}}"
},
{
"name": "chat_type",
"value": "={{$json[\"message\"][\"chat\"][\"type\"]}}"
},
{
"name": "username",
"value": "={{$json[\"message\"][\"from\"][\"username\"] || ''}}"
},
{
"name": "first_name",
"value": "={{$json[\"message\"][\"from\"][\"first_name\"] || ''}}"
},
{
"name": "text",
"value": "={{$json[\"message\"][\"text\"] || ''}}"
}
]
}
},
"id": "SetExtract",
"name": "Set extract",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
-680,
0
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.chat_type}}",
"operation": "equal",
"value2": "private"
}
]
}
},
"id": "IfPrivate",
"name": "IF private",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
-480,
0
]
},
{
"parameters": {
"jsCode": "// Traduce los comandos de Telegram a preguntas para /ask.\n//\n// No consulta la base por su cuenta: /ask ya resuelve estatus contra\n// gps_event y devuelve el texto formateado, con unidad, hora y aviso de dato\n// viejo. Duplicar aqu\u00ed ese formato crear\u00eda una segunda versi\u00f3n que se ir\u00eda\n// separando de la de la API.\n//\n// Los comandos existen porque escribir \"/estatus T-142\" en el radio mental de\n// Tr\u00e1fico es m\u00e1s r\u00e1pido y m\u00e1s predecible que redactar una pregunta: no\n// dependen de que el router de intenciones reconozca la frase.\n\nconst AYUDA = [\n 'Consultas de flota:',\n '',\n '/estatus <unidad> d\u00f3nde est\u00e1 y desde hace cu\u00e1nto',\n '/disponibles unidades en base o en la zona de La Laguna',\n '/sinsenal unidades sin se\u00f1al o sin reportar',\n '/atoradas detenidas en ruta por mucho tiempo',\n '/combustible <unidad> cargas y descargas de los \u00faltimos 7 d\u00edas',\n '/eventos <unidad> \u00faltimos eventos registrados',\n '/salud si est\u00e1 entrando informaci\u00f3n al sistema',\n '',\n 'Tambi\u00e9n puedes preguntar con tus palabras, por ejemplo:',\n '\"\u00bfd\u00f3nde est\u00e1 la T-142?\" o \"\u00bfqu\u00e9 unidades est\u00e1n libres?\"',\n].join('\\n');\n\n// Comando -> pregunta que el router de /ask reconoce.\nconst SIN_ARGUMENTO = {\n '/disponibles': '\u00bfqu\u00e9 unidades est\u00e1n disponibles?',\n '/libres': '\u00bfqu\u00e9 unidades est\u00e1n disponibles?',\n '/sinsenal': '\u00bfqu\u00e9 unidades est\u00e1n sin se\u00f1al?',\n '/atoradas': '\u00bfhay unidades atoradas en ruta?',\n '/salud': '\u00bfest\u00e1 entrando informaci\u00f3n?',\n};\n\nconst CON_ARGUMENTO = {\n '/estatus': (u) => `estatus de la unidad ${u}`,\n '/status': (u) => `estatus de la unidad ${u}`,\n '/combustible': (u) => `combustible de la unidad ${u}`,\n '/eventos': (u) => `\u00faltimos eventos de la unidad ${u}`,\n};\n\nconst out = [];\n\nfor (const item of $input.all()) {\n const base = item.json;\n const texto = (base.text || '').trim();\n\n // Mensaje normal: pasa tal cual a /ask.\n if (!texto.startsWith('/')) {\n out.push({ json: { ...base, question: texto, direct_reply: null } });\n continue;\n }\n\n // En grupos Telegram manda \"/estatus@mi_bot\"; se limpia el sufijo.\n const partes = texto.split(/\\s+/);\n const comando = partes[0].split('@')[0].toLowerCase();\n const argumento = partes.slice(1).join(' ').trim();\n\n if (comando === '/start' || comando === '/ayuda' || comando === '/help') {\n out.push({ json: { ...base, question: null, direct_reply: AYUDA } });\n continue;\n }\n\n if (SIN_ARGUMENTO[comando]) {\n out.push({ json: { ...base, question: SIN_ARGUMENTO[comando], direct_reply: null } });\n continue;\n }\n\n if (CON_ARGUMENTO[comando]) {\n if (!argumento) {\n out.push({\n json: {\n ...base,\n question: null,\n direct_reply: `Falta la unidad. Ejemplo: ${comando} T-142`,\n },\n });\n continue;\n }\n\n out.push({\n json: { ...base, question: CON_ARGUMENTO[comando](argumento), direct_reply: null },\n });\n continue;\n }\n\n out.push({\n json: {\n ...base,\n question: null,\n direct_reply: `No conozco el comando ${comando}.\\n\\n${AYUDA}`,\n },\n });\n}\n\nreturn out;"
},
"id": "RouteCommand",
"name": "Rutear comando",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-280,
0
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "necesita-api",
"leftValue": "={{ $json.question }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "IfNeedsApi",
"name": "IF necesita API",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
-60,
0
]
},
{
"parameters": {
"method": "POST",
"url": "http://api:8000/ask",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"q\": {{ JSON.stringify($json.question) }},\n \"top_k\": 4\n}",
"options": {
"timeout": 120000
}
},
"id": "AskApi",
"name": "API: /ask",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
180,
-120
]
},
{
"parameters": {
"jsCode": "// Telegram corta los mensajes en 4096 caracteres y una lista de flota\n// completa los pasa con facilidad. La API ya devuelve `chunks` partidos por\n// salto de l\u00ednea; aqu\u00ed solo se convierten en items para que el nodo de env\u00edo\n// mande uno por mensaje, en orden.\n\nconst out = [];\n\nfor (const item of $input.all()) {\n const cuerpo = item.json;\n const chat_id = $('Rutear comando').first().json.chat_id;\n\n const partes =\n Array.isArray(cuerpo.chunks) && cuerpo.chunks.length\n ? cuerpo.chunks\n : [cuerpo.text || 'No encontr\u00e9 respuesta.'];\n\n for (const parte of partes) {\n out.push({ json: { chat_id, reply: parte } });\n }\n}\n\nreturn out;"
},
"id": "SplitReply",
"name": "Partir respuesta",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
-120
]
},
{
"parameters": {
"jsCode": "// Respuestas que no necesitan la API: ayuda y errores de comando.\nreturn $input.all().map((item) => ({\n json: { chat_id: item.json.chat_id, reply: item.json.direct_reply },\n}));"
},
"id": "DirectReply",
"name": "Respuesta directa",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
180,
140
]
},
{
"parameters": {
"chatId": "={{ $json.chat_id }}",
"text": "={{ $json.reply }}",
"additionalFields": {}
},
"id": "TelegramSend",
"name": "Telegram: Send",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
640,
0
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Set extract",
"type": "main",
"index": 0
}
]
]
},
"Set extract": {
"main": [
[
{
"node": "IF private",
"type": "main",
"index": 0
}
]
]
},
"IF private": {
"main": [
[
{
"node": "Rutear comando",
"type": "main",
"index": 0
}
],
[]
]
},
"Rutear comando": {
"main": [
[
{
"node": "IF necesita API",
"type": "main",
"index": 0
}
]
]
},
"IF necesita API": {
"main": [
[
{
"node": "API: /ask",
"type": "main",
"index": 0
}
],
[
{
"node": "Respuesta directa",
"type": "main",
"index": 0
}
]
]
},
"API: /ask": {
"main": [
[
{
"node": "Partir respuesta",
"type": "main",
"index": 0
}
]
]
},
"Partir respuesta": {
"main": [
[
{
"node": "Telegram: Send",
"type": "main",
"index": 0
}
]
]
},
"Respuesta directa": {
"main": [
[
{
"node": "Telegram: Send",
"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.
telegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Telegram → Estatus de flota / RAG → Reply. Uses telegramTrigger, httpRequest, telegram. Event-driven trigger; 9 nodes.
Source: https://github.com/DRAnguiano/gps-fleet-events/blob/main/n8n/telegram_rag_workflow.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.
Creators, designers, and developers exploring AI-powered image generation. Automation enthusiasts who want to integrate image creation into n8n workflows. Telegram bot builders looking to add visual A
[](https://www.linkedin.com/in/mosaab-yassir-lafrimi/)[](https://t.me/joevenner)
Transcribe audio messages from Telegram using Google Gemini for free.
A sophisticated Telegram bot that provides AI-powered responses with conversation memory. This template demonstrates how to integrate any AI API service with Telegram, making it easy to swap between d
Template Description This description details the template's purpose, how it works, and its key features. You can copy and use it directly.