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": "06 - Email Sender",
"nodes": [
{
"parameters": {},
"name": "Execute Workflow Trigger",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"jsCode": "// Parse command and determine action type\nconst command = $input.first().json.command; // 'send', 'reply', 'draft'\nconst args = $input.first().json.args || '';\nconst emailId = $input.first().json.emailId;\n\nreturn [{\n json: {\n command: command,\n args: args,\n emailId: emailId,\n userId: $input.first().json.userId,\n chatId: $input.first().json.chatId,\n username: $input.first().json.username\n }\n}];"
},
"name": "Parse Command",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
450,
300
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT gmail_id, sender_name, sender_email, subject, body_text, thread_id FROM emails WHERE id = $1 AND user_id = $2",
"additionalFields": {
"parameters": [
{
"name": "email_id",
"value": "={{ $json.emailId }}"
},
{
"name": "user_id",
"value": "={{ $json.userId }}"
}
]
}
},
"name": "Get Original Email",
"type": "n8n-nodes-base.sqlite",
"typeVersion": 2.2,
"position": [
650,
200
],
"credentials": {
"sqlite": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM writing_style WHERE user_id = $1 ORDER BY analysis_date DESC LIMIT 1",
"additionalFields": {
"parameters": [
{
"name": "user_id",
"value": "={{ $json.userId }}"
}
]
}
},
"name": "Get Writing Style",
"type": "n8n-nodes-base.sqlite",
"typeVersion": 2.2,
"position": [
650,
400
],
"credentials": {
"sqlite": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Build AI prompt for reply generation\nconst originalEmail = $('Get Original Email').first().json;\nconst style = $('Get Writing Style').first().json || {};\n\nif (!originalEmail) {\n return [{ json: { error: 'Email not found' } }];\n}\n\n// Build style description\nlet styleDesc = 'professional but friendly';\nif (style.greeting_style) {\n styleDesc = `${style.greeting_style} and ${style.sign_off_style || 'professional'}`;\n}\n\nconst prompt = `You are helping write an email reply. Here is the context:\n\nORIGINAL EMAIL:\nFrom: ${originalEmail.sender_name} <${originalEmail.sender_email}>\nSubject: ${originalEmail.subject}\n\nBody:\n${originalEmail.body_text.substring(0, 2000)}\n\nWRITING STYLE:\nThe user writes in a ${styleDesc} tone.\n${style.common_phrases ? 'Common phrases they use: ' + style.common_phrases : ''}\n${style.formality_score ? 'Formality level: ' + (style.formality_score > 0.5 ? 'formal' : 'casual') : ''}\n\nTASK:\nGenerate 3 different reply options:\n1. FORMAL - Professional, polite, business-like\n2. CASUAL - Friendly, warm, conversational\n3. BRIEF - Short, direct, to the point\n\nFor each option, provide:\n- Subject line (if different from original)\n- Full email body\n- Brief explanation of the tone/style\n\nMake sure the replies:\n- Address the key points in the original email\n- Match the user's writing style\n- Are appropriate for the relationship with the sender\n- Sound natural and human-written\n\nFormat as JSON with keys: formal, casual, brief`;\n\nreturn [{\n json: {\n prompt: prompt,\n originalEmail: originalEmail,\n chatId: $input.first().json.chatId\n }\n}];"
},
"name": "Build AI Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
850,
300
]
},
{
"parameters": {
"model": "gemini-3-flash",
"options": {
"temperature": 0.8,
"maxOutputTokens": 2000
}
},
"name": "Generate AI Replies",
"type": "n8n-nodes-base.googlePaLmChatModel",
"typeVersion": 1,
"position": [
1050,
300
],
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Parse AI response into structured options\nconst aiResponse = $input.first().json.response || $input.first().json.content;\nconst chatId = $input.first().json.chatId;\n\n// Try to extract JSON from response\nlet options = {};\ntry {\n // Find JSON in the response\n const jsonMatch = aiResponse.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n options = JSON.parse(jsonMatch[0]);\n }\n} catch (e) {\n console.log('Failed to parse JSON, using text fallback');\n}\n\n// Format for Telegram\nlet message = '\ud83d\udce7 **AI-Generated Reply Options**\\n\\n';\nmessage += 'Replying to: *' + ($input.first().json.originalEmail?.subject || 'Email') + '*\\n\\n';\n\nif (options.formal) {\n message += '**1\ufe0f\u20e3 FORMAL**\\n';\n message += options.formal.body || options.formal || 'Professional reply option\\n';\n message += '\\n';\n}\n\nif (options.casual) {\n message += '**2\ufe0f\u20e3 CASUAL**\\n';\n message += options.casual.body || options.casual || 'Friendly reply option\\n';\n message += '\\n';\n}\n\nif (options.brief) {\n message += '**3\ufe0f\u20e3 BRIEF**\\n';\n message += options.brief.body || options.brief || 'Short reply option\\n';\n message += '\\n';\n}\n\nmessage += 'Reply with the number (1, 2, or 3) to send that option, or type \"custom\" to write your own.';\n\n// Store options for later retrieval\nconst storeOptions = JSON.stringify(options);\n\nreturn [{\n json: {\n message: message,\n options: storeOptions,\n chatId: chatId,\n originalEmailId: $input.first().json.originalEmail?.gmail_id,\n threadId: $input.first().json.originalEmail?.thread_id\n }\n}];"
},
"name": "Format Reply Options",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1250,
300
]
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "={{ $json.message }}",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"name": "Send Reply Options",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.1,
"position": [
1450,
300
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Execute Workflow Trigger": {
"main": [
[
{
"node": "Parse Command",
"type": "main",
"index": 0
}
]
]
},
"Parse Command": {
"main": [
[
{
"node": "Get Original Email",
"type": "main",
"index": 0
},
{
"node": "Get Writing Style",
"type": "main",
"index": 0
}
]
]
},
"Get Original Email": {
"main": [
[
{
"node": "Build AI Prompt",
"type": "main",
"index": 0
}
]
]
},
"Get Writing Style": {
"main": [
[
{
"node": "Build AI Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build AI Prompt": {
"main": [
[
{
"node": "Generate AI Replies",
"type": "main",
"index": 0
}
]
]
},
"Generate AI Replies": {
"main": [
[
{
"node": "Format Reply Options",
"type": "main",
"index": 0
}
]
]
},
"Format Reply Options": {
"main": [
[
{
"node": "Send Reply Options",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"tags": [
"ronkbot",
"gmail",
"email",
"send",
"ai"
]
}
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.
googlePalmApisqlitetelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
06 - Email Sender. Uses executeWorkflowTrigger, sqlite, googlePaLmChatModel, telegram. Event-driven trigger; 8 nodes.
Source: https://github.com/rohankag/ronkbot/blob/db03432335532bdeb4ebcee0c72d9109e04b466f/n8n-workflows/06-email-sender.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.
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.
IR-CLU — ربات فروش (احراز هویت + هوش مصنوعی + پرداخت کارتبهکارت). Uses telegramTrigger, googleSheets, telegram, httpRequest. Event-driven trigger; 83 nodes.