This workflow follows the Agent → Google Sheets 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": "Telegram - Create draft article (topic -> length -> AI)",
"nodes": [
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-560,
0
],
"id": "f0b3d3d4-0a87-4d0c-a5b9-5d316c0d18f1",
"name": "Telegram Trigger",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Stateless conversation router for Telegram ForceReply\n// Flow: /create_a_draft -> topic -> length -> generate\n\nconst chatId = $json?.message?.chat?.id;\nconst text = String($json?.message?.text ?? '').trim();\nconst replyToText = String($json?.message?.reply_to_message?.text ?? '');\n\nif (!chatId) {\n return [{ json: { action: 'ignore' } }];\n}\n\nif (text === '/create_a_draft') {\n return [{ json: { action: 'ask_topic', chatId } }];\n}\n\n// Topic reply (reply to our prompt)\nif (replyToText && /\u0412\u0432\u0435\u0434\u0438\\s+\u0442\u0435\u043c\u0443/i.test(replyToText)) {\n const topic = text;\n if (!topic) {\n return [{ json: { action: 'ask_topic', chatId } }];\n }\n return [{ json: { action: 'ask_length', chatId, topic } }];\n}\n\nfunction parseTopicFromPrompt(prompt) {\n // Prompt format we send: \u0422\u0435\u043c\u0430: \"<topic>\"\\n\u0412\u0432\u0435\u0434\u0438 \u0434\u043b\u0438\u043d\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 ...\n const m = String(prompt).match(/\u0422\u0435\u043c\u0430:\\s*[\"\u201c\u201d]?([^\\n\\r\"\u201d]+)[\"\u201d]?/i);\n return m ? m[1].trim() : '';\n}\n\n// Length reply\nif (replyToText && /(\u0412\u0432\u0435\u0434\u0438\\s+\u0434\u043b\u0438\u043d\u0443\\s+\u0441\u0442\u0430\u0442\u044c\u0438|\u043a\u043e\u043b-?\u0432\u043e\\s*\u0441\u0438\u043c\u0432\u043e\u043b)/i.test(replyToText)) {\n const topic = parseTopicFromPrompt(replyToText);\n const raw = text.replace(/[^0-9]/g, '');\n const length = parseInt(raw || '0', 10);\n\n if (!topic) {\n return [{ json: { action: 'ask_topic', chatId } }];\n }\n\n if (!Number.isFinite(length) || length <= 0) {\n return [{ json: { action: 'ask_length_invalid', chatId, topic } }];\n }\n\n return [{ json: { action: 'generate', chatId, topic, length } }];\n}\n\nreturn [{ json: { action: 'ignore' } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-320,
0
],
"id": "0b84a7c2-d72e-47cc-b8a8-ff64f620b8f7",
"name": "Conversation Router"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "a1",
"leftValue": "={{ $json.action }}",
"rightValue": "ask_topic",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "ask topic"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "a2",
"leftValue": "={{ $json.action }}",
"rightValue": "ask_length",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "ask length"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "a3",
"leftValue": "={{ $json.action }}",
"rightValue": "ask_length_invalid",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "ask length invalid"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "a4",
"leftValue": "={{ $json.action }}",
"rightValue": "generate",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "generate"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
-80,
0
],
"id": "4b5c9f95-6fd0-47b1-85a5-1f03c8d1cde3",
"name": "Switch"
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "=\u0412\u0432\u0435\u0434\u0438 \u0442\u0435\u043c\u0443 \u0441\u0442\u0430\u0442\u044c\u0438",
"replyMarkup": "forceReply",
"forceReply": {
"force_reply": true
},
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
160,
-220
],
"id": "a7e78d49-62d3-4f63-8b3d-c9cf10f06c9c",
"name": "Ask topic",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "=\u0422\u0435\u043c\u0430: \"{{ $json.topic }}\"\n\u0412\u0432\u0435\u0434\u0438 \u0434\u043b\u0438\u043d\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 (\u043a\u043e\u043b-\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)",
"replyMarkup": "forceReply",
"forceReply": {
"force_reply": true
},
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
160,
0
],
"id": "f4d04f79-9b86-4e10-a08f-4b47f5c0f2ad",
"name": "Ask length",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "=\u0422\u0435\u043c\u0430: \"{{ $json.topic }}\"\n\u041d\u0443\u0436\u043d\u043e \u0447\u0438\u0441\u043b\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 1500. \u0412\u0432\u0435\u0434\u0438 \u0434\u043b\u0438\u043d\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 (\u043a\u043e\u043b-\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)",
"replyMarkup": "forceReply",
"forceReply": {
"force_reply": true
},
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
160,
220
],
"id": "c85c1ad8-a76f-4790-a7d7-4f3cbe8d0d89",
"name": "Ask length (invalid)",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "p1",
"name": "prompt",
"value": "=\u041d\u0430\u043f\u0438\u0448\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430 \u0442\u0435\u043c\u0443: {{ $json.topic }}.\n\n\u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:\n- \u0414\u043b\u0438\u043d\u0430: \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e {{ $json.length }} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (\u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e).\n- \u042f\u0437\u044b\u043a: \u0440\u0443\u0441\u0441\u043a\u0438\u0439.\n- \u0411\u0435\u0437 Markdown \u0438 \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0438\u0445 \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0439 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u043a\u0441\u0442 \u0441\u0442\u0430\u0442\u044c\u0438.\n\n\u0421\u0442\u0438\u043b\u044c (\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e):\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043c\u0430\u043d\u0435\u0440\u0443, \u043b\u0435\u043a\u0441\u0438\u043a\u0443, \u0440\u0438\u0442\u043c \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0430\u0432\u0442\u043e\u0440\u0430 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e Style Guide (\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c \u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432):\n{{ $json.style_guide }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
400,
440
],
"id": "4d8b8436-4762-48c5-8c2d-6f138c6d9f34",
"name": "Build prompt"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1VnmBL5OTy4i9VtQieMrniHxY5BVVTQp7m_54cahfvsg",
"mode": "list",
"cachedResultName": "ila table",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VnmBL5OTy4i9VtQieMrniHxY5BVVTQp7m_54cahfvsg/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "\u041b\u0438\u0441\u04421",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VnmBL5OTy4i9VtQieMrniHxY5BVVTQp7m_54cahfvsg/edit#gid=0"
},
"options": {}
},
"id": "6c8b32c4-0d5f-4e63-8a36-3ad4f2d1e7a1",
"name": "Get ILA articles",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
400,
220
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Build a compact corpus of the latest articles to learn the author's style\n// Expected columns in the sheet: topic, article, createdAt, updatedAt (optional)\n\nfunction parseDate(v) {\n if (!v) return null;\n const d = new Date(v);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\nconst rows = items.map(i => i.json || {});\n\nrows.sort((a, b) => {\n const da = parseDate(a.updatedAt) || parseDate(a.createdAt) || null;\n const db = parseDate(b.updatedAt) || parseDate(b.createdAt) || null;\n if (da && db) return db.getTime() - da.getTime();\n if (da && !db) return -1;\n if (!da && db) return 1;\n const ia = Number(a.id ?? 0);\n const ib = Number(b.id ?? 0);\n if (Number.isFinite(ia) && Number.isFinite(ib) && ia !== ib) return ib - ia;\n return 0;\n});\n\nconst MAX_ARTICLES = 6;\nconst MAX_CHARS = 9000;\n\nconst parts = [];\nlet used = 0;\n\nfor (const r of rows) {\n const topic = String(r.topic ?? '').trim();\n const article = String(r.article ?? '').trim();\n if (!article) continue;\n\n const block = `\u0422\u0415\u041c\u0410: ${topic || '(\u0431\u0435\u0437 \u0442\u0435\u043c\u044b)'}\n\u0422\u0415\u041a\u0421\u0422:\n${article}`;\n if (used + block.length + 6 > MAX_CHARS) break;\n parts.push(block);\n used += block.length + 6;\n if (parts.length >= MAX_ARTICLES) break;\n}\n\nconst styleCorpus = parts.join(`\n\n---\n\n`);\n\n// Pull base params (chatId/topic/length) from the earlier router output\nconst baseItem = ($items('Conversation Router', 0, 0) || [])[0];\nconst base = baseItem?.json ?? {};\n\nreturn [{\n json: {\n chatId: base.chatId,\n topic: base.topic,\n length: base.length,\n style_corpus: styleCorpus\n }\n}];"
},
"id": "e1d6df2a-44e0-4f8c-9a8b-3f6d1f0f1bcb",
"name": "Build style corpus",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
640,
220
]
},
{
"parameters": {
"promptType": "define",
"text": "=\u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0439 \u0442\u0435\u043a\u0441\u0442\u044b \u0430\u0432\u0442\u043e\u0440\u0430 \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u044c Style Guide \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439.\n\n\u0422\u0435\u043a\u0441\u0442\u044b \u0430\u0432\u0442\u043e\u0440\u0430 (\u043a\u043e\u0440\u043f\u0443\u0441):\n{{ $json.style_corpus }}\n\n\u0424\u043e\u0440\u043c\u0430\u0442 \u043e\u0442\u0432\u0435\u0442\u0430:\n- 10\u201315 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b (\u0431\u0443\u043b\u043b\u0435\u0442\u044b) \u043e \u0442\u043e\u043d\u0435, \u0434\u043b\u0438\u043d\u0435 \u0430\u0431\u0437\u0430\u0446\u0435\u0432, \u0440\u0438\u0442\u043c\u0435, \u043b\u0435\u043a\u0441\u0438\u043a\u0435, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0440\u0438\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u0430\u0445\n- 3 \u0437\u0430\u043f\u0440\u0435\u0442\u0430 (\u0447\u0435\u0433\u043e \u041d\u0415 \u0434\u0435\u043b\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0431\u0438\u0442\u044c\u0441\u044f \u0438\u0437 \u0441\u0442\u0438\u043b\u044f)\n- 3 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u0444\u0440\u0430\u0437\u044b/\u043e\u0431\u043e\u0440\u043e\u0442\u0430 \u0432 \u0441\u0442\u0438\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0430\n\n\u041e\u0442\u0432\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a \u0442\u0435\u043a\u0441\u0442 Style Guide, \u0431\u0435\u0437 \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0439.",
"options": {
"systemMessage": "\u0422\u044b \u2014 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440-\u0441\u0442\u0438\u043b\u0438\u0441\u0442. \u0422\u0432\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0441\u0442\u0438\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0430 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 Style Guide."
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
880,
220
],
"id": "3c0a6b9b-4d38-4fb8-a0bd-6a6df4c0f5c3",
"name": "AI Style Analyst"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "s1",
"name": "chatId",
"value": "={{ $('Build style corpus').item.json.chatId }}",
"type": "number"
},
{
"id": "s2",
"name": "topic",
"value": "={{ $('Build style corpus').item.json.topic }}",
"type": "string"
},
{
"id": "s3",
"name": "length",
"value": "={{ $('Build style corpus').item.json.length }}",
"type": "number"
},
{
"id": "s4",
"name": "style_guide",
"value": "={{ $json.output }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1120,
220
],
"id": "22c62c7c-7a59-4c6b-9a24-6d9d6a2d9a1f",
"name": "Attach style guide"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.prompt }}",
"options": {
"systemMessage": "\u0422\u044b \u2014 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0442\u0430\u0442\u0435\u0439. \u0412\u0435\u0440\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0441\u0442\u0430\u0442\u044c\u0438."
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
640,
440
],
"id": "a1c53c6e-5023-4bd1-9a1e-6b4f7d3c89c7",
"name": "AI Agent"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
640,
620
],
"id": "9b25b4bb-9d8c-4d79-8b5c-6edc0b64e6c0",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "={{ $json.output }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
880,
440
],
"id": "e4c2d3df-9b4d-4c6d-9f1a-67b2d54f6e0c",
"name": "Send article",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Conversation Router",
"type": "main",
"index": 0
}
]
]
},
"Conversation Router": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Ask topic",
"type": "main",
"index": 0
}
],
[
{
"node": "Ask length",
"type": "main",
"index": 0
}
],
[
{
"node": "Ask length (invalid)",
"type": "main",
"index": 0
}
],
[
{
"node": "Get ILA articles",
"type": "main",
"index": 0
}
],
[]
]
},
"Get ILA articles": {
"main": [
[
{
"node": "Build style corpus",
"type": "main",
"index": 0
}
]
]
},
"Build style corpus": {
"main": [
[
{
"node": "AI Style Analyst",
"type": "main",
"index": 0
}
]
]
},
"AI Style Analyst": {
"main": [
[
{
"node": "Attach style guide",
"type": "main",
"index": 0
}
]
]
},
"Attach style guide": {
"main": [
[
{
"node": "Build prompt",
"type": "main",
"index": 0
}
]
]
},
"Build prompt": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
],
[
{
"node": "AI Style Analyst",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send article",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "26e9dea1-e9f2-4490-8768-6516657ea3bd",
"meta": {
"templateCredsSetupCompleted": true
}
}
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.
googleSheetsOAuth2ApiopenAiApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Telegram - Create draft article (topic -> length -> AI). Uses telegramTrigger, telegram, googleSheets, agent. Event-driven trigger; 14 nodes.
Source: https://github.com/Hydralisk-zerg/first-project-n8n/blob/ee2608a989b3d0e1ecf9b16b6a752e3f3b8789de/files/workflows/telegram-create-draft-article.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.
BoomerBobBot.TP. Uses agent, telegramTrigger, telegram, memoryBufferWindow. Event-driven trigger; 95 nodes.
Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.
This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste
N8N-Workflow. Uses telegramTrigger, telegram, googleSheets, openAi. Event-driven trigger; 63 nodes.
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.