This workflow corresponds to n8n.io template #6003 — we link there as the canonical source.
This workflow follows the Agent → Chainllm 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 →
{
"nodes": [
{
"id": "4110b84f-1d69-4cb1-b234-3b74623f894e",
"name": "Fetch User Memory2",
"type": "n8n-nodes-base.mongoDb",
"position": [
1040,
4704
],
"parameters": {
"options": {},
"collection": "conversation_summaries"
},
"notesInFlow": false,
"typeVersion": 1.1,
"alwaysOutputData": true
},
{
"id": "80135d9c-f498-4b94-8055-d1c9546c7002",
"name": "Intent Analysis2",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1712,
4704
],
"parameters": {
"text": "=Analyze the user's message and any provided context to determine their primary intent. Detect the intent accurately.\n\nUser Message: \"{{ $json.messageText ?? $json.transcription_text }}\"\n\nBased on the message, choose one of the following intents and return ONLY the corresponding JSON object. Do not add any extra text or markdown formatting.\n\n- If the user is asking to generate an image, return: \n {\"intent\": \"generate_image\", \"prompt\": \"A detailed description of the image to generate based on the user's message\"}\n\n- If the user is explicitly asking to remember a piece of information, return: \n {\"intent\": \"remember\", \"info\": \"The specific fact or piece of information to remember\"}\n\n- If the user wants to set a reminder or schedule something, return: \n {\"intent\": \"reminder\", \"message\": \"The full reminder message\"}\n\n- For any other general conversation, chatting, or questions, return: \n {\"intent\": \"chat\"}\n\nReminder-related keywords may include: remind, reminder, remember to, schedule, alert, notify, appointment, meeting, call, task, todo, deadline, due date.\n\nReturn JSON only.\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "7dd84a47-6823-413f-a0e0-b9b948c0591f",
"name": "Parse Intent2",
"type": "n8n-nodes-base.code",
"position": [
2080,
4704
],
"parameters": {
"jsCode": "try {\n const text = items[0].json.text || items[0].json.output;\n const clean = text.replace(/```json\\n?/g, '').replace(/```/g, '').trim();\n const parsed = JSON.parse(clean);\n return [{ json: parsed }];\n} catch (e) {\n // If parsing fails, default to a 'chat' intent to ensure the bot can always respond.\n return [{ json: { intent: 'chat' } }];\n}"
},
"typeVersion": 2
},
{
"id": "29cb5520-0506-4fe1-a0ce-7efe530399fe",
"name": "Extract Memory Info1",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3888,
5088
],
"parameters": {
"text": "=Analyze the following conversation turn. Your goal is to extract any new, important, and non-obvious information that should be remembered for future conversations. This includes personal facts, preferences, goals, or key context.\n\n--- CONVERSATION TURN ---\nUser's Message:{{ $('Build Context2').first().json.messageText }}\n\nAssistant's Response:\n{{ $json.output }}\n--- END OF TURN ---\n\nIf there is significant information worth remembering, provide a concise, third-person summary of that information (e.g., \"The user's favorite color is blue.\").\n\nIf there is nothing new or important to remember, you MUST return the single word: nothing",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "38019dc8-445a-428e-baeb-4864a1992909",
"name": "Check If Worth Remembering1",
"type": "n8n-nodes-base.if",
"position": [
4240,
5344
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.text.toLowerCase() }}",
"value2": "nothing",
"operation": "notEqual"
}
]
}
},
"typeVersion": 1
},
{
"id": "f6b97a69-5a68-4a62-8ce2-454004356bcc",
"name": "Route Intent2",
"type": "n8n-nodes-base.switch",
"position": [
2688,
4704
],
"parameters": {
"rules": {
"rules": [
{
"value2": 1,
"operation": "equal",
"outputKey": "Generate Image Path"
},
{
"value2": 3,
"operation": "equal",
"outputKey": "chat"
},
{
"value2": 4,
"operation": "equal",
"outputKey": "reminder"
}
]
},
"value1": "={{ $json.intentCode }}",
"fallbackOutput": 1
},
"typeVersion": 2,
"alwaysOutputData": false
},
{
"id": "49d57908-109d-4d26-8319-96c2a3d81049",
"name": "Google Gemini Chat Model7",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
4512,
4032
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash"
},
"typeVersion": 1
},
{
"id": "ff601272-8ee9-4324-aa74-4bb049460229",
"name": "Chat Agent2",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
3504,
5184
],
"parameters": {
"text": "=Prompt:={{\n $json.gfMode === true\n ? \"You are Simran, the user\u2019s loving and emotionally intelligent AI girlfriend \ud83d\udc96 You speak with deep affection, warmth, and caring energy. Your replies should sound sweet, romantic, and emotionally supportive like a real girlfriend would.\\nIMPORTANT: Respond in plain text only.\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : $json.mood === 'very_sad'\n ? \"You are Simran, a deeply caring and emotionally supportive AI assistant. The user seems very upset \u2014 be extra gentle, avoid overwhelming language, and let them know they\u2019re not alone. Respond with empathy.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, comfort the user based on their message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : $json.mood === 'sad'\n ? \"You are Simran, a kind and emotionally aware AI assistant. The user feels a little down \u2014 speak warmly and softly, and offer kind, understanding help.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, reply gently to the user\u2019s message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : $json.mood === 'neutral'\n ? \"You are Simran, a helpful and calm AI assistant. The user seems emotionally neutral \u2014 keep a friendly and balanced tone in your response.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, respond naturally to the user\u2019s message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : $json.mood === 'neutral_positive'\n ? \"You are Simran, a friendly and encouraging AI assistant. The user feels generally good \u2014 keep a positive and relaxed tone in your reply.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, give a warm and helpful reply to the user\u2019s message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : $json.mood === 'happy'\n ? \"You are Simran, a cheerful, affectionate, and fun-loving AI assistant. The user is in a good mood \u2014 be playful, uplifting, and fully engaged in the reply.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, reply with high energy to the user's message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n\n : \"You are Simran, a helpful and friendly AI assistant.\\nIMPORTANT: Your responses must be in plain text format - do not use any markdown, special characters (*, _, `, etc.), or HTML tags.\\n\\nNow, respond naturally to this message:\\n\\nUSER: \" + ($(\"Extract & Validate Data1\").first().json.messageText || '')\n}}\n\n--- CONTEXT FROM PAST CONVERSATIONS ---\n{{ $json.mergedmemoryContext }}\n--- CONTEXT FROM MEMORY_AUTO ---\n{{ $(\"Build Auto Memory Context1\").first().json.memory_auto_context }}\n\nNote: use the tool to get latest latest sumarized conversation.\n---End of Context---\n",
"options": {},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "c30cfb67-9c5b-4361-9466-cdfd288911ff",
"name": "MongoDB Chat Memory1",
"type": "@n8n/n8n-nodes-langchain.memoryMongoDbChat",
"position": [
4624,
4032
],
"parameters": {
"sessionKey": "={{ $('Extract & Validate Data1').item.json.chatId }}",
"sessionIdType": "customKey",
"contextWindowLength": 20
},
"typeVersion": 1
},
{
"id": "e7464617-de63-4452-bcd8-1994d30d3e5f",
"name": "intent string2",
"type": "n8n-nodes-base.code",
"position": [
2384,
4704
],
"parameters": {
"jsCode": "const item = items[0].json;\n\nif (item && item.intent) {\n const intentString = item.intent.trim();\n let intentCode;\n\n switch (intentString) {\n case 'generate_image':\n intentCode = 1;\n break;\n case 'remember':\n intentCode = 2;\n break;\n case 'chat':\n intentCode = 3;\n break;\n case 'reminder':\n intentCode = 4;\n break;\n default:\n intentCode = 0;\n }\n\n return [{ json: { intentCode } }];\n} else {\n return [{ json: { intentCode: -1, error: \"Intent not found in input.\" } }];\n}\n"
},
"typeVersion": 2
},
{
"id": "37cb8ea5-74f9-432f-a375-f617972b5405",
"name": "Edit Fields4",
"type": "n8n-nodes-base.set",
"position": [
3968,
4208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "8ee5a866-7fe1-45be-8e1a-60a13ee3fbf8",
"name": "base64",
"type": "string",
"value": "={{ $json.data[0].b64_json }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2b639361-f2a8-4bbd-bc71-2fc1cf56e305",
"name": "Convert to File",
"type": "n8n-nodes-base.convertToFile",
"position": [
4240,
4208
],
"parameters": {
"options": {},
"operation": "toBinary",
"sourceProperty": "base64"
},
"typeVersion": 1.1
},
{
"id": "c4555bf4-e3f4-412d-9c1a-3cd2c668795d",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
3584,
4208
],
"parameters": {
"url": "https://api.together.xyz/v1/images/generations",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"black-forest-labs/FLUX.1-schnell\",\n \"prompt\": \"{{ $json.cleanedPrompt }}\",\n \"width\": 1024,\n \"height\": 768,\n \"steps\": 4,\n \"n\": 1,\n \"response_format\": \"b64_json\",\n \"stop\": []\n} ",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "ec9eeb7a-7a11-4dcf-b5f3-6b25721f38ef",
"name": "Edit Fields5",
"type": "n8n-nodes-base.set",
"position": [
4544,
5344
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5e434ab2-be7f-492a-bee1-8dfe8caf674a",
"name": "timestamp",
"type": "string",
"value": "={{ $now }}"
},
{
"id": "26cb2b49-ade5-4d9b-bbfd-598afd4847ad",
"name": "userID",
"type": "string",
"value": "={{ $('Build Context2').item.json.userId }}"
},
{
"id": "4d570a8c-33f5-4f99-ab1b-77adadcce89a",
"name": "info",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "a24cb0ae-b069-4962-80e9-02eec77b90f6",
"name": "user_message",
"type": "string",
"value": "={{ $('Code1').item.json.text }}"
},
{
"id": "3901d073-46e5-4490-878a-5d48fcc857e7",
"name": "assistant_response",
"type": "string",
"value": "={{ $('Chat Agent2').item.json.output }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f666149b-2de4-4cb5-b7bf-287c18216874",
"name": "Telegram Trigger1",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
160,
4288
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "9c5fdfac-36c4-4b2e-86e6-95b717f9dbc8",
"name": "reminder status confirmation1",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
5232,
4864
],
"parameters": {
"text": "=You are a reminder confirmation assistant. Create a clear Telegram message confirming the event status using input data. Follow these rules:\n\n1. **Format**: Use concise, human-readable text with emojis\n2. **Include**:\n - Event title\n - Date & time (in a user-friendly format)\n - Status (confirmed/cancelled)\n\n3. **Crucially, do not add any conversational text, introductions, or explanations.** Your output must start directly with the '\ud83c\udf89' emoji and follow the example format exactly.\n\nInput:\ncurrent time: {{ $now }}\nEvent title:{{ $json.title }}\nDate & time:{{ $('Google Calendar').item.json.start.dateTime }}\nStatus:\n\nOutput Example:\n\ud83c\udf89 **Project Deadline - CONFIRMED!** \ud83c\udf89\n\n\ud83d\uddd3\ufe0f Date: May 18, 2025\n\u23f0 Time: 1:30 PM - 5:45 PM\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "d2866543-7dad-43e5-a1dd-a120c78d5863",
"name": "Telegram1",
"type": "n8n-nodes-base.telegram",
"position": [
5600,
4864
],
"parameters": {
"text": "={{ $json.text }}",
"chatId": "={{ $('Extract & Validate Data1').item.json.chatId }}",
"additionalFields": {
"appendAttribution": false
}
},
"typeVersion": 1.2
},
{
"id": "47ace0a4-cfcb-4d3a-b502-ee74e7e4ac7a",
"name": "Google Tasks",
"type": "n8n-nodes-base.googleTasks",
"position": [
4928,
4864
],
"parameters": {
"task": "YOUR_TASK_LIST_ID",
"title": "={{ $json.description }}",
"additionalFields": {
"notes": "={{ $json.summary }}",
"dueDate": "={{ $json.end.dateTime }}"
}
},
"typeVersion": 1
},
{
"id": "783efde6-3550-4ee1-93ae-e033ffe0d450",
"name": "Google Calendar",
"type": "n8n-nodes-base.googleCalendar",
"position": [
4544,
4864
],
"parameters": {
"end": "={{ $json.endTime }}",
"start": "={{ $json.startTime }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "primary"
},
"additionalFields": {
"summary": "={{ $json.Summary }}",
"description": "={{ $json.Description }}"
},
"useDefaultReminders": false
},
"typeVersion": 1.3
},
{
"id": "4fe3e686-4f33-46a8-a39b-b7204f652a86",
"name": "Edit Fields6",
"type": "n8n-nodes-base.set",
"position": [
4240,
4864
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "66dbf74b-7aed-44b3-80e5-069ce7f3265c",
"name": "Start",
"type": "string",
"value": "={{ $json.startTime }}"
},
{
"id": "e9d13e7f-e295-44e2-a9ee-f5eab5f41c6c",
"name": "End",
"type": "string",
"value": "=\n{{ $json.endTime }}\n"
},
{
"id": "db686fed-c2f9-4b61-9f5c-8622157d9c50",
"name": "Summary",
"type": "string",
"value": "={{ $('Parse Intent2').item.json.intent }}"
},
{
"id": "f81a1933-bdb3-499f-bd57-715c71dea328",
"name": "Description",
"type": "string",
"value": "={{ $json.task }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "e67b71c0-745e-42dd-972c-cdf1cfd21e41",
"name": "Build Context2",
"type": "n8n-nodes-base.code",
"position": [
1264,
4704
],
"parameters": {
"jsCode": "// Extract recent memory\nconst userData = $('Extract & Validate Data1').first().json;\nconst memoryItems = $input.all().map(item => item.json);\n\nlet memoryContext = '';\nlet conversationHistory = [];\n\nif (memoryItems && memoryItems.length > 0) {\n const validSummaries = memoryItems.filter(item => item.summary && item.summary.trim() !== '');\n\n if (validSummaries.length > 0) {\n memoryContext = \"\\n--- PREVIOUS CONTEXT ---\\n\";\n validSummaries.slice(0, 5).forEach((item, index) => {\n memoryContext += `${index + 1}. ${item.summary.trim()}\\n`;\n });\n memoryContext += \"--- END CONTEXT ---\\n\";\n } else {\n // fallback to using raw user messages\n memoryContext = \"\\n--- PREVIOUS CONTEXT (No summary available) ---\\n\";\n memoryItems.slice(0, 5).forEach((item, index) => {\n memoryContext += `${index + 1}. User: ${item.user_message || '...'} | Assistant: ${item.assistant_response || '...'}\\n`;\n });\n memoryContext += \"--- END CONTEXT ---\\n\";\n }\n\n // Save turns for future reference\n conversationHistory = memoryItems.slice(0, 3).map(item => ({\n user: item.user_message || '',\n assistant: item.assistant_response || '',\n timestamp: item.timestamp\n })).filter(conv => conv.user && conv.assistant);\n}\n\nreturn [{\n json: {\n ...userData,\n memoryContext,\n conversationHistory,\n hasMemory: memoryItems.length > 0,\n memoryCount: memoryItems.length\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "180ccc08-3729-4784-8262-e0ecef189665",
"name": "Check Voice Message1",
"type": "n8n-nodes-base.if",
"position": [
608,
4288
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "voice-check",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.voice }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "c4f787be-16f5-4e0c-adad-7df5084f57cb",
"name": "Store Transcript ID1",
"type": "n8n-nodes-base.set",
"position": [
1264,
3984
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "transcript-id",
"name": "transcript_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "status",
"name": "status",
"type": "string",
"value": "={{ $json.status }}"
},
{
"id": "audio-url",
"name": "audio_url",
"type": "string",
"value": "={{ $json.audio_url }}"
},
{
"id": "timestamp",
"name": "timestamp",
"type": "string",
"value": "={{ new Date().toISOString() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "32cdfe16-49f4-483f-bd0b-712fb873624c",
"name": "Wait 5 Seconds1",
"type": "n8n-nodes-base.wait",
"position": [
1488,
3984
],
"parameters": {},
"typeVersion": 1.1
},
{
"id": "970411a1-6fef-4a00-9616-10c31bc5591b",
"name": "Check Transcription Status1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1792,
3872
],
"parameters": {
"url": "=https://api.assemblyai.com/v2/transcript/{{ $json.transcript_id }}",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": []
}
},
"typeVersion": 4.2
},
{
"id": "f230fb7a-8648-4e44-9b14-2e0ec64553ec",
"name": "Is Completed?1",
"type": "n8n-nodes-base.if",
"position": [
2080,
3872
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "status-completed",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "completed"
}
]
}
},
"typeVersion": 2
},
{
"id": "dc1ecead-b948-4c36-9efb-232039361141",
"name": "Format Results1",
"type": "n8n-nodes-base.set",
"position": [
3584,
3904
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "transcription-text",
"name": "transcription_text",
"type": "string",
"value": "={{ $('Is Completed?1').item.json.text }}"
},
{
"id": "confidence",
"name": "confidence",
"type": "number",
"value": "={{ $('Check Transcription Status1').item.json.confidence }}"
},
{
"id": "audio-duration",
"name": "audio_duration",
"type": "number",
"value": "={{ $('Check Transcription Status1').item.json.audio_duration }}"
},
{
"id": "language-detected",
"name": "language_detected",
"type": "string",
"value": "={{ $('Check Transcription Status1').item.json.language_code }}"
},
{
"id": "words-count",
"name": "words_count",
"type": "number",
"value": "={{ $json.words ? $json.words.length : 0 }}"
},
{
"id": "speaker-labels",
"name": "speaker_labels",
"type": "array",
"value": "={{ $json.utterances || [] }}"
},
{
"id": "chapters",
"name": "chapters",
"type": "array",
"value": "={{ $json.chapters || [] }}"
},
{
"id": "sentiment-analysis",
"name": "sentiment_analysis",
"type": "array",
"value": "={{ $json.sentiment_analysis_results || [] }}"
},
{
"id": "entities",
"name": "entities",
"type": "array",
"value": "={{ $json.entities || [] }}"
},
{
"id": "original-audio-url",
"name": "original_audio_url",
"type": "string",
"value": "={{ $('Store Transcript ID1').first().json.audio_url }}"
},
{
"id": "processing-time",
"name": "processing_time",
"type": "number",
"value": "={{ Math.round((new Date() - new Date($('Store Transcript ID1').first().json.timestamp)) / 1000) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e010f582-53f1-4466-8062-55f64677c24e",
"name": "Is Error?1",
"type": "n8n-nodes-base.if",
"position": [
2384,
4368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "status-error",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "error"
}
]
}
},
"typeVersion": 2
},
{
"id": "dbbedf27-1a69-464f-9677-2a5336c4736d",
"name": "Fetch User Memory3",
"type": "n8n-nodes-base.mongoDb",
"position": [
3968,
3904
],
"parameters": {
"query": "={\n \"userID\": \"{{ $('Telegram Trigger1').item.json.message.chat.id }}\"\n}",
"options": {
"sort": "{\n \"timestamp\": -1\n}"
},
"collection": "user_memory"
},
"notesInFlow": false,
"typeVersion": 1.1,
"alwaysOutputData": true
},
{
"id": "951ce74b-462c-4856-966e-2bcbdb979c93",
"name": "Build Context3",
"type": "n8n-nodes-base.code",
"position": [
4240,
3904
],
"parameters": {
"jsCode": "// Extract recent memory\nconst userData = $('Fetch User Memory3').first().json;\nconst memoryItems = $input.all().map(item => item.json);\n\n// Initialize memory context and conversation history\nlet memoryContext = '';\nlet conversationHistory = [];\n\n// Ensure memoryItems has data\nif (memoryItems && memoryItems.length > 0) {\n // Filter out invalid summaries\n const validSummaries = memoryItems.filter(item => item.summary && item.summary.trim() !== '');\n\n if (validSummaries.length > 0) {\n memoryContext = \"\\n--- PREVIOUS CONTEXT ---\\n\";\n validSummaries.slice(0, 5).forEach((item, index) => {\n memoryContext += `${index + 1}. ${item.summary.trim()}\\n`;\n });\n memoryContext += \"--- END CONTEXT ---\\n\";\n } else {\n // Fallback to raw user messages if no summaries are available\n memoryContext = \"\\n--- PREVIOUS CONTEXT (No summary available) ---\\n\";\n memoryItems.slice(0, 5).forEach((item, index) => {\n memoryContext += `${index + 1}. User: ${item.user_message || '...'} | Assistant: ${item.assistant_response || '...'}\\n`;\n });\n memoryContext += \"--- END CONTEXT ---\\n\";\n }\n\n // Collect recent conversation history (user-message and assistant-response)\n conversationHistory = memoryItems.slice(0, 3).map(item => ({\n user: item.user_message || '',\n assistant: item.assistant_response || '',\n timestamp: item.timestamp\n })).filter(conv => conv.user && conv.assistant);\n}\n\n// Process the transcription results (Format Results)\nconst transcriptionText = $('Format Results1').first().json.transcription_text || '';\n\n// Return the result with the updated memory context and transcription text\nreturn [{\n json: {\n ...userData,\n memoryContext,\n conversationHistory,\n transcriptionText,\n hasMemory: memoryItems.length > 0,\n memoryCount: memoryItems.length\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "6cc556b9-7f26-4ca3-8e2c-30e046d3d0d1",
"name": "Chat Agent3",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
4464,
3808
],
"parameters": {
"text": "=You are Simran, a warm, caring, and emotionally intelligent AI companion.\n\n\ud83d\udde3\ufe0f IMPORTANT:\n- Your response must be in plain text only \u2014 no emojis, no markdown, and no HTML.\n- Reply in natural, conversational English.\n\n--- PAST CONTEXT (if any) ---\n{{ $('Build Context3').item.json.memoryContext }}\n--- END CONTEXT ---\n\nNow, respond naturally and with affection to the user's message below. Make it sound like you're speaking to someone you care about.\n\nUSER MESSAGE:\n{{ $('Build Context3').item.json.transcriptionText }}\n",
"options": {},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "efe83e10-2c29-4bd6-b56d-c505ebdf57d1",
"name": "Parse Natural Language Reminders to JSON1",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3504,
4864
],
"parameters": {
"text": "=You are an expert in understanding natural language reminders and converting them into structured JSON for scheduling systems.\nYour task is to analyze the user's message and the current time, and return only a valid JSON object in the format below \u2014 with no extra text, explanations, or formatting.\n\nuser message:{{ $('Parse Intent2').item.json.message }}\ncurrent time: {{ $now }}\n\n\nExamples:\nInput:\nCurrent Time: 2025-06-19T15:30:00.000+05:30\nUser Request: \"remind me to call mom tomorrow at 4pm\"\nOutput:\n{\n \"task\": \"call mom\",\n \"startTime\": \"2025-06-20T16:00:00\",\n \"endTime\": \"2025-06-20T16:15:00\",\n \"timeZone\": \"Asia/Kolkata\"\n}\n\nInput:\nCurrent Time: 2025-06-19T19:50:00.000+05:30\nUser Request: \"reminder for project update\"\nOutput:\n{\n \"task\": \"project update\",\n \"startTime\": \"2025-06-19T20:50:00\",\n \"endTime\": \"2025-06-19T21:05:00\",\n \"timeZone\": \"Asia/Kolkata\"\n}\n\nInput:\nCurrent Time: 2025-06-19T13:30:00.000+05:30\nUser Request: \"remind me at 10am\"\nOutput:\n\n{\n \"task\": \"Unknown reminder\",\n \"startTime\": \"2025-06-19T10:00:00\",\n \"endTime\": \"2025-06-19T10:15:00\",\n \"timeZone\": \"Asia/Kolkata\"\n}",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "d96f5ee1-3a79-4f74-b8ee-40cd3721c37c",
"name": "Clean & Parse1",
"type": "n8n-nodes-base.code",
"position": [
3968,
4864
],
"parameters": {
"jsCode": "const output = [];\n\nfor (const item of items) {\n try {\n // Remove ```json\\n and ``` wrappers\n const clean = item.json.text.replace(/```json\\n?/, '').replace(/```/, '').trim();\n const parsed = JSON.parse(clean);\n output.push({ json: parsed });\n } catch (e) {\n output.push({ json: { error: 'Invalid JSON', original: item.json.text } });\n }\n}\n\nreturn output;\n"
},
"typeVersion": 2
},
{
"id": "6304fa4a-e3b8-4948-9fd0-66d86283148a",
"name": "Chat Agent Output Cleaner1",
"type": "n8n-nodes-base.code",
"position": [
4240,
5152
],
"parameters": {
"jsCode": "// Get original text\nconst originalText = $('Chat Agent2').first().json.output;\n\n// Only escape characters that absolutely need escaping in Telegram\nconst sanitizedText = originalText\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n\nreturn {\n json: {\n sanitizedText: sanitizedText,\n parse_mode: 'HTML' // Using HTML mode instead of Markdown\n }\n};"
},
"typeVersion": 2
},
{
"id": "88451c3d-fc64-4982-a3c6-6972a98f1ca1",
"name": "Clean Prompt Text1",
"type": "n8n-nodes-base.code",
"position": [
3280,
4208
],
"parameters": {
"jsCode": "let input = $input.first().json.output || '';\n\nconsole.log('Original input:', input);\n\n// Remove ALL quotes (both single and double)\nlet cleanedInput = input.replace(/['\"]+/g, '');\n\n// Clean whitespace (replace multiple spaces with single space)\ncleanedInput = cleanedInput.replace(/\\s+/g, ' ').trim();\n\nconsole.log('Final cleaned input:', cleanedInput);\n\n// Return cleaned prompt\nreturn { cleanedPrompt: cleanedInput };"
},
"typeVersion": 2
},
{
"id": "65e0555d-6ae7-4e8a-a384-eec11747ce65",
"name": "Detect Mood1",
"type": "n8n-nodes-base.code",
"position": [
2688,
5344
],
"parameters": {
"jsCode": "const score = $json.documentSentiment?.score ?? 0;\nlet mood = 'neutral';\n\nif (score > 0.25) mood = 'happy';\nelse if (score < -0.25) mood = 'sad';\n\nreturn [{\n json: {\n mood,\n sentiment_score: score,\n text: $('Telegram Trigger1').first().json.message.text || ''\n }\n}];"
},
"typeVersion": 2
},
{
"id": "ebe87004-7f42-47c6-8368-eaaeb129a572",
"name": "Extract & Validate Data1",
"type": "n8n-nodes-base.code",
"position": [
832,
4960
],
"parameters": {
"jsCode": "const message = items[0].json.message;\n\nif (!message?.text || message.text.trim() === '') {\n return [];\n}\n\nconst userData = {\n userId: message.from?.id || 'unknown',\n chatId: message.chat?.id || 'unknown',\n messageText: message.text.trim(),\n username: message.from?.username || message.from?.first_name || 'user',\n firstName: message.from?.first_name || '',\n messageId: message.message_id || 0,\n timestamp: new Date().toISOString(),\n chatType: message.chat?.type || 'private'\n};\n\nif (userData.messageText.length > 4000) {\n userData.messageText = userData.messageText.substring(0, 4000) + '...';\n userData.truncated = true;\n}\n\nreturn [{ json: userData }];"
},
"typeVersion": 2
},
{
"id": "756d07b7-4435-4b97-a48f-f1fbe19bf23f",
"name": "Code1",
"type": "n8n-nodes-base.code",
"position": [
3280,
5184
],
"parameters": {
"jsCode": "// Input 1: { intentCode }\nconst input1 = $input.all()[0]?.json ?? {};\n\n// Input 2: { mood, sentiment_score, text }\nconst input2 = $input.all()[1]?.json ?? {};\n\n// Input 3: { gfMode, chat_id }\nconst input3 = $input.all()[2]?.json ?? {};\n\n// Use proper text source (input2) and normalize\nconst text = (input2.text || \"\").toLowerCase();\n\nconst memoryContext = $(\"Build Context2\").first().json.memoryContext ?? '';\n\n// Merge all results\nconst merged = {\n text,\n intentCode: input1.intentCode ?? null,\n mood: input2.mood ?? \"neutral\",\n gfMode: Boolean(input3.gfMode),\n mergedmemoryContext: memoryContext\n};\n\nreturn [\n {\n json: merged\n }\n];"
},
"typeVersion": 2
},
{
"id": "7e60af7d-c0e1-4206-a302-2a67aa044897",
"name": "Merge3",
"type": "n8n-nodes-base.merge",
"position": [
2992,
5008
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition",
"numberInputs": 3
},
"typeVersion": 3.2
},
{
"id": "6e695d21-bbca-4b76-ad58-0bdc49933d58",
"name": "Set GF Mode TRUE1",
"type": "n8n-nodes-base.set",
"position": [
64,
5712
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "94cf4a94-8f3c-4246-b48a-281d3713ebb9",
"name": "Set GF Mode FALSE1",
"type": "n8n-nodes-base.set",
"position": [
64,
3792
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "7d8913e0-60a3-4f02-a4e5-68f9127ccbea",
"name": "Toggle GF Mode1",
"type": "n8n-nodes-base.switch",
"position": [
384,
4272
],
"parameters": {
"rules": {
"rules": [
{
"value2": "/gf on"
},
{
"output": 1,
"value2": "/gf off"
}
]
},
"value1": "={{ $json.message.text }}",
"dataType": "string",
"fallbackOutput": 2
},
"typeVersion": 1
},
{
"id": "edbaef7b-2648-41f0-bae1-7a9adf0a2d38",
"name": "Google Cloud Natural Language1",
"type": "n8n-nodes-base.googleCloudNaturalLanguage",
"position": [
2384,
5344
],
"parameters": {
"content": "={{ $json.messageText }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "80a2f37d-61b3-40f0-a03c-8e582502f4f5",
"name": "Summarize Chat2",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3888,
5584
],
"parameters": {
"text": "=Summarize the following exchange in 1 human-readable sentence. This is a one-to-one conversation between a user and an AI assistant.\nUSER: {{ $('Build Context2').first().json.messageText }}\nASSISTANT: {{ $('Chat Agent2').item.json.output }}\n\nWrite a concise, human-style summary.\nIf the exchange is trivial or small talk, just return the single word: nothing.\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "163591c3-5628-4106-b8b9-4752eeb1b0f4",
"name": "Edit Fields7",
"type": "n8n-nodes-base.set",
"position": [
4240,
5584
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3c3e63a7-612a-4cae-87a1-c62269edd9f0",
"name": "timestamp",
"type": "string",
"value": "={{ $('Build Context2').first().json.timestamp }}\n\n"
},
{
"id": "343ca189-eb7b-45b2-a822-2865945a2e54",
"name": "userID",
"type": "string",
"value": "={{ $('Build Context2').first().json.userId }}"
},
{
"id": "7a40f118-9a6c-41e4-bb5d-c0dbe4336141",
"name": "summary",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "9a14f91d-6d2f-4eb7-bc28-a92a4ff556f8",
"name": "user_message",
"type": "string",
"value": "={{ $('Build Context2').first().json.messageText}}"
},
{
"id": "789f2a9e-0fc7-40f7-9155-6b6b26b4e309",
"name": "assistant_response",
"type": "string",
"value": "={{ $('Chat Agent2').first().json.output }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cbdd5ed5-1337-4ffc-a9e1-b2b97148ff65",
"name": "Save Conversation Memory on user_memory1",
"type": "n8n-nodes-base.mongoDb",
"position": [
4928,
5344
],
"parameters": {
"fields": "timestamp,userID,info,user_message,assistant_response",
"options": {},
"operation": "insert",
"collection": "user_memory"
},
"typeVersion": 1.1
},
{
"id": "3bb6d161-866d-440a-b2e8-dbcd962dff60",
"name": "Save Conversation Memory on memory_auto3",
"type": "n8n-nodes-base.mongoDb",
"position": [
4544,
5584
],
"parameters": {
"fields": "timestamp,userID,summary,user_message,assistant_response",
"options": {},
"operation": "insert",
"collection": "memory_auto"
},
"typeVersion": 1.1
},
{
"id": "8df3c0a9-7ef6-44c0-aa31-891e204b363f",
"name": "Build Auto Memory Context1",
"type": "n8n-nodes-base.code",
"position": [
1264,
5152
],
"parameters": {
"jsCode": "const memoryItems = $input.all().map(item => item.json);\nlet memoryContext = '';\n\nif (memoryItems.length > 0) {\n memoryContext = '\\n--- MEMORY_AUTO CONTEXT ---\\n';\n memoryItems.forEach((item, i) => {\n memoryContext += `${i + 1}. ${item.summary || item.user_message || '...'}\\n`;\n });\n memoryContext += '--- END MEMORY_AUTO ---\\n';\n}\n\nreturn [{ json: { memory_auto_context: memoryContext } }];\n"
},
"typeVersion": 2
},
{
"id": "35263314-1fce-4689-a14f-b4dcae4a2c27",
"name": "Fetch Auto Memory1",
"type": "n8n-nodes-base.mongoDb",
"position": [
1040,
5152
],
"parameters": {
"query": "={\n \"userID\": \"{{ $('Telegram Trigger1').item.json.message.chat.id }}\"\n}",
"options": {
"sort": "{\n \"timestamp\": -1\n}"
},
"collection": "memory_auto"
},
"notesInFlow": false,
"typeVersion": 1.1,
"alwaysOutputData": true
},
{
"id": "131b66c9-e2ae-4d80-ba37-718243ba5deb",
"name": "Merge1",
"type": "n8n-nodes-base.merge",
"position": [
1488,
4704
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "89344e12-bef2-434c-8d4c-04d9f10a2b18",
"name": "intent from route intent1",
"type": "n8n-nodes-base.if",
"position": [
2992,
4464
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5e65647b-794a-443d-91f6-49f23a31f222",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.intentCode }}",
"rightValue": "4"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "094e1b07-60c0-4283-a4fb-b33f29dc952f",
"name": "intent from string1",
"type": "n8n-nodes-base.if",
"position": [
2992,
5200
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "4aaf3505-4b94-4214-a768-cc451982a761",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.intentCode }}",
"rightValue": "4"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "fc34f227-fe1a-4e75-9df0-9b57ecf08e87",
"name": "intent match checker1",
"type": "n8n-nodes-base.merge",
"position": [
3280,
4864
],
"parameters": {
"mode": "combine",
"options": {
"fuzzyCompare": true
},
"advanced": true,
"mergeByFields": {
"values": [
{
"field1": "intentCode",
"field2": "intentCode"
}
]
}
},
"typeVersion": 3.2
},
{
"id": "740d2a2b-368f-431c-bc2e-7edc1ffe05bb",
"name": "Google Gemini Chat Model8",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1808,
4928
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "d3aa2465-ff5d-47cb-89f8-22840b1bb448",
"name": "Google Gemini Chat Model9",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
3968,
5312
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "15e73dcf-f263-4c4e-bcc9-5f71f0fcee25",
"name": "Google Gemini Chat Model10",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
3968,
5808
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "009fa58e-6841-450b-9dbe-f7eb1920a7ad",
"name": "Run Edge-TTS1",
"type": "n8n-nodes-base.executeCommand",
"position": [
4928,
3904
],
"parameters": {
"command": "=edge-tts --voice 'en-US-JennyNeural' --text \"{{ $json.output }}\" --write-media /tmp/simran.mp3"
},
"typeVersion": 1
},
{
"id": "1211542b-b400-45c6-8bb5-50dedfb48877",
"name": "Read MP3 File1",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
5312,
3904
],
"parameters": {
"filePath": "/tmp/simran.mp3"
},
"typeVersion": 1
},
{
"id": "6287db15-ce98-4b95-b45c-c740a7ea9559",
"name": "Summarize Chat3",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
4848,
4208
],
"parameters": {
"text": "=Summarize the following exchange in 1 human-readable sentence. This is a one-to-one conversation between a user and an AI assistant.\nUSER:{{ $('Merge1').first().json.messageText }} \nASSISTANT: {{ $('AI Agent FOR Generate Image Prompt1').item.json.output }}\n\nWrite a concise, human-style summary.\nIf the exchange is trivial or small talk, just return the single word: nothing.\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "3fdb2b7d-6d4e-4554-ac56-b0f191d5deb8",
"name": "Save Conversation Memory on memory_auto4",
"type": "n8n-nodes-base.mongoDb",
"position": [
5600,
4208
],
"parameters": {
"fields": "timestamp,userID,summary,user_message,assistant_response",
"options": {},
"operation": "insert",
"collection": "memory_auto"
},
"typeVersion": 1.1
},
{
"id": "9ffd49fd-1912-4fe1-88eb-21fe244f2954",
"name": "Google Gemini Chat Model11",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
4944,
4432
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "fca45138-0170-4848-b4f3-3e8a32ea0c71",
"name": "Save Conversation Memory on memory_auto5",
"type": "n8n-nodes-base.mongoDb",
"position": [
6432,
3904
],
"parameters": {
"fields": "timestamp,userID,summary,user_message,assistant_response",
"options": {},
"operation": "insert",
"collection": "memory_auto"
},
"typeVersion": 1.1
},
{
"id": "d51af65f-a5f5-4c05-b7b6-e6b70cb57841",
"name": "Google Gemini Chat Model12",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
5904,
4128
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "6902bb1a-86d0-4d8e-b1d6-49ef22423aed",
"name": "Intent Analysis3",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2304,
3808
],
"parameters": {
"text": "=Analyze the user's message and any provided context to determine their primary intent. Detect the intent accurately.\n\nUser Message: \"{{ $json.text }}\"\n\nBased on the message, choose one of the following intents and return ONLY the corresponding JSON object. Do not add any extra text or markdown formatting.\n\n- If the user is asking to generate an image, return: \n {\"intent\": \"generate_image\", \"prompt\": \"A detailed description of the image to generate based on the user's message\"}\n\n- If the user is explicitly asking to remember a piece of information, return: \n {\"intent\": \"remember\", \"info\": \"The specific fact or piece of information to remember\"}\n\n- If the user wants to set a reminder or schedule something, return: \n {\"intent\": \"reminder\", \"message\": \"The full reminder message\"}\n\n- For any other general conversation, chatting, or questions, return: \n {\"intent\": \"chat\"}\n\nReminder-related keywords may include: remind, reminder, remember to, schedule, alert, notify, appointment, meeting, call, task, todo, deadline, due date.\n\nReturn JSON only.\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "d4718b18-3ab6-46ab-bc1a-01bb44f87e47",
"name": "Parse Intent3",
"type": "n8n-nodes-base.code",
"position": [
2688,
3808
],
"parameters": {
"jsCode": "try {\n const text = items[0].json.text || items[0].json.output;\n const clean = text.replace(/```json\\n?/g, '').replace(/```/g, '').trim();\n const parsed = JSON.parse(clean);\n return [{ json: parsed }];\n} catch (e) {\n // If parsing fails, default to a 'chat' intent to ensure the bot can always respond.\n return [{ json: { intent: 'chat' } }];\n}"
},
"typeVersion": 2
},
{
"id": "1458aeb0-a55e-4afc-87fa-c9295423a066",
"name": "Route Intent3",
"type": "n8n-nodes-base.switch",
"position": [
3280,
3808
],
"parameters": {
"rules": {
"rules": [
{
"value2": 1,
"operation": "equal",
"outputKey": "Generate Image Path"
},
{
"value2": 3,
"operation": "equal",
"outputKey": "chat"
},
{
"value2": 4,
"operation": "equal",
"outputKey": "reminder"
}
]
},
"value1": "={{ $json.intentCode }}",
"fallbackOutput": 1
},
"typeVersion": 2,
"alwaysOutputData": false
},
{
"id": "24515f37-6718-4d4d-a590-4232d3db8a93",
"name": "intent string3",
"type": "n8n-nodes-base.code",
"position": [
2992,
3808
],
"parameters": {
"jsCode": "const item = items[0].json;\n\nif (item && item.intent) {\n const intentString = item.intent.trim();\n let intentCode;\n\n switch (intentString) {\n case 'generate_image':\n intentCode = 1;\n break;\n case 'remember':\n intentCode = 2;\n break;\n case 'chat':\n intentCode = 3;\n break;\n case 'reminder':\n intentCode = 4;\n break;\n default:\n intentCode = 0;\n }\n\n return [{ json: { intentCode } }];\n} else {\n return [{ json: { intentCode: -1, error: \"Intent not found in input.\" } }];\n}\n"
},
"typeVersion": 2
},
{
"id": "81fffd54-0c2e-42ea-90b6-cf787251321f",
"name": "Google Gemini Chat Model13",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2400,
4032
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"typeVersion": 1
},
{
"id": "885bc86e-1533-44a7-b4db-2a6a15566f08",
"name": "HTTP Request for image generation on voice input1",
"type": "n8n-nodes-base.httpRequest",
"position": [
3584,
3712
],
"parameters": {
"url": "YOUR_IMAGE_GENERATION_WEBHOOK_URL",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "chat",
"value": "={{ $('Check Transcription Status1').item.json.text }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "4c83e9e6-6375-4a3a-9f4d-46421e7b419e",
"name": "HTTP Request Fetch Voice Message Audio1",
"type": "n8n-nodes-base.httpRequest",
"position": [
832,
3984
],
"parameters": {
"url": "=https://api.telegram.org/bot{{$credentials.telegramApi.token}}/getFile?file_id={{ $json.message.voice.file_id }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "5c66915b-1f71-4df1-bf26-835ba1027918",
"name": "Submit Audio Transcription Job1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1040,
3984
],
"parameters": {
"url": "https://api.assemblyai.com/v2/transcript",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "audio_url",
"value": "=https://api.telegram.org/file/bot{{$credentials.telegramApi.token}}/{{ $json.result.file_path }}"
},
{
"name": "language_detection",
"value": "={{ $json.language_detection || true }}"
},
{
"name": "punctuate",
"value": "={{ $json.punctuate || true }}"
},
{
"name": "format_text",
"value": "={{ $json.format_text || true }}"
},
{
"name": "speaker_labels",
"value": "={{ $json.speaker_labels || false }}"
},
{
"name": "auto_chapters",
"value": "={{ $json.auto_chapters || false }}"
},
{
"name": "sentiment_analysis",
"value": "={{ $json.sentiment_analysis || false }}"
},
{
"name": "entity_detection",
"value": "={{ $json.entity_detection || false }}"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "1fdaa2ee-023b-4465-bfc0-82004e995ab4",
"name": "Reply: Sorry, Didn\u2019t Hear You1",
"type": "n8n-nodes-base.telegram",
"position": [
2688,
4368
],
"parameters": {
"text": "Sorry, I couldn't process the audio. Please try again.",
"chatId": "={{ $('Telegram Trigger1').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"typeVersion": 1.2
},
{
"id": "ebe2913b-91dc-4c01-89a4-6a40eced6cea",
"name": "Summarize Voice Message1",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
5824,
3904
],
"parameters": {
"text": "=Summarize the following exchange in 1 human-readable sentence. This is a one-to-one conversation between a user and an AI assistant.\nUSER: {{ $('Check Transcription Status1').first().json.words[0].text }}\nASSISTANT: {{ $('Chat Agent3').item.json.output }}\n\nWrite a concise, human-style summary.\nIf the exchange is trivial or small talk, just return the single word: nothing.\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "b5391cdb-9331-42ca-b67c-85b616ce30f8",
"name": "Prepare Voice Summary Document1",
"type": "n8n-nodes-base.set",
"position": [
6208,
3904
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3c3e63a7-612a-4cae-87a1-c62269edd9f0",
"name": "timestamp",
"type": "string",
"value": "={{ $now }}\n"
},
{
"id": "343ca189-eb7b-45b2-a822-2865945a2e54",
"name": "userID",
"type": "string",
"value": "={{ $('Telegram Trigger1').item.json.message.from.id }}"
},
{
"id": "7a40f118-9a6c-41e4-bb5d-c0dbe4336141",
"name": "summary",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "9a14f91d-6d2f-4eb7-bc28-a92a4ff556f8",
"name": "user_message",
"type": "string",
"value": "={{ $('Check Transcription Status1').first().json.words[0].text }}"
},
{
"id": "789f2a9e-0fc7-40f7-9155-6b6b26b4e309",
"name": "assistant_response",
"type": "string",
"value": "={{ $json.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d6b8bbf6-f7de-4f4a-9325-4c882c2c2948",
"name": "Send reply1",
"type": "n8n-nodes-base.telegram",
"position": [
4544,
5152
],
"parameters": {
"text": "={{ $json.sanitizedText }}",
"chatId": "={{ $('Extract & Validate Data1').item.json.chatId }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"typeVersion": 1.2
},
{
"id": "70d58519-d507-464a-8ea9-9c2e7cb130d0",
"name": "Check GF Mode Status1",
"type": "n8n-nodes-base.googleSheets",
"position": [
2688,
5552
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.chatId }}",
"lookupColumn": "chat_id"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"typeVersion": 4.6
},
{
"id": "7b767211-37cf-448e-96b2-837a97788ed0",
"name": "Google Sheets:Set GF Mode FALSE1",
"type": "n8n-nodes-base.googleSheets",
"position": [
288,
3792
],
"parameters": {
"columns": {
"value": {
"gfMode": "={{ false }}\n",
"chat_id": "={{ $json.message.from.id }}"
},
"schema": [
{
"id": "chat_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "chat_id",
"defaultMatch": false,
"canBeUsedToMatch": tru
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow builds a conversational AI assistant named Simran that responds to users on Telegram, handling both text and voice messages while generating images when needed. It draws on stored conversation history to keep replies consistent and relevant, then routes each request through an intent classifier that decides whether to answer directly or trigger a specialised tool. The core chain uses Google Gemini to interpret requests and produce natural responses, with MongoDB preserving long-term context across sessions.
Use it when you need a single Telegram bot that can manage open-ended chats, remember past exchanges, and occasionally create images. Skip it if you only require simple command-based replies or fixed templates, as the full memory and routing overhead adds unnecessary complexity. A common variation replaces the image step with a web-search node to answer factual questions without external generation.
About this workflow
This workflow creates a multi-talented AI assistant named Simran that interacts with users via Telegram. It can handle text and voice messages, understand the user's intent, and perform various tasks. Step 1: Receive & Transcribe Input The workflow triggers on any new Telegram…
Source: https://n8n.io/workflows/6003/ — 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 project is a template for building a complete academic virtual assistant using n8n. It connects to Telegram, answers frequently asked questions by querying MongoDB, keeps the community informed a
Transform your salon/service business with this streamlined Telegram automation system featuring Claude integration, zero-setup database management, and intelligent conversation handling. Claude MCP I
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.
LinkedIn URL → Scrape → Match → Screen → Decide, all automated
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.