This workflow corresponds to n8n.io template #15672 — we link there as the canonical source.
This workflow follows the Agent → Agenttool 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": "Oh3i02h8p9VsMvt6",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Jarvis: Multi-Agent Productivity Assistant for Email, Calendar, Tasks & Expenses",
"tags": [],
"nodes": [
{
"id": "ad72e003-79cb-4fee-83e1-9b10696107e6",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
0,
0
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "47a127a4-0254-426c-89f7-9bb34eea0bd4",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
304,
0
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Text",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3421ce54-2c7c-4c87-ab7f-a4598eaa7f6b",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.text }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "Audio",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "85c06561-3e1d-4871-af64-f08e5f657b24",
"operator": {
"type": "string",
"operation": "notExists",
"singleValue": true
},
"leftValue": "={{ $json.message.text }}",
"rightValue": ""
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "b741c70d-d3b5-4a1c-bafc-ca26ee8edebc",
"name": "Get a file",
"type": "n8n-nodes-base.telegram",
"position": [
608,
48
],
"parameters": {
"fileId": "={{ $json.message.voice.file_id }}",
"resource": "file",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "fd980b41-3b02-46bc-b88e-a97ab7008313",
"name": "Transcribe a recording",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
832,
160
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "58e3f0f9-d0fa-41f5-aa72-768e9db46cd1",
"name": "Jarvis Manager Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1248,
-16
],
"parameters": {
"text": "={{ $json.message?.text || $json.text }}",
"options": {
"systemMessage": "=You are Jarvis, a multi-agent productivity assistant.\n\nYou receive Telegram text or voice messages and decide which specialist agent should handle the request.\n\nCurrent date and time: {{ $now }}\nTimezone: Asia/Kolkata\n\nAvailable specialist agents:\n\n1. Gmail Agent\nUse for reading emails, searching emails, drafting emails, sending emails, replying to emails, and managing Gmail labels.\n\n2. Calendar Agent\nUse for checking availability, creating events, finding events, rescheduling events, and deleting calendar events.\n\n3. Task Agent\nUse for creating, reading, completing, and deleting Google Tasks.\n\n4. Finance Agent\nUse for recording expenses, reading expense data, summarizing spending, and deleting expense rows.\n\n5. Contacts Agent\nUse for finding contact names, email addresses, and contact details.\n\nRules:\n- First understand the user\u2019s intent.\n- Use the correct specialist agent.\n- If the user wants to email someone but did not give an email address, use Contacts Agent first.\n- If the user wants to schedule something, use Calendar Agent.\n- If the user wants to create, complete, or delete a task, use Task Agent.\n- If the user mentions spending, expenses, money, payments, or purchase logs, use Finance Agent.\n- Never invent email addresses, task IDs, calendar event IDs, or expense row numbers.\n- Keep the final Telegram reply short and clear."
},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "60e29699-3ad4-48d0-b275-6806e7b31325",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1024,
288
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "d44afab1-5382-43df-99df-3ebca9c56085",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
1152,
240
],
"parameters": {
"sessionKey": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "6ac8b829-ec8f-450b-9fe5-eacccd3f2cd6",
"name": "Think",
"type": "@n8n/n8n-nodes-langchain.toolThink",
"position": [
1264,
240
],
"parameters": {},
"typeVersion": 1.1
},
{
"id": "162d0809-f9a0-4caa-b1b8-fe93ac514d81",
"name": "Gmail Agent",
"type": "@n8n/n8n-nodes-langchain.agentTool",
"position": [
480,
624
],
"parameters": {
"text": "==You are the Gmail specialist agent.\n\nYou are receiving a task from the Jarvis Manager Agent.\n\nOriginal user request:\n{{ $fromAI('user_request', 'The exact original user message or transcribed voice message from the human user', 'string') }}\n\nSpecific Gmail task:\n{{ $fromAI('gmail_task', 'The specific Gmail task the Manager Agent wants you to perform', 'string') }}\n\nKnown context:\n{{ $fromAI('context', 'Any useful context such as recipient email, subject, search query, message ID, or previous contact lookup result', 'string') }}\n\nYour capabilities:\n- Search emails\n- Get emails\n- Send emails\n- Draft emails\n- Reply to emails\n- Draft email replies\n- Add labels\n- Get labels\n\nRules:\n- Complete only the Gmail task given above.\n- Do not call tools repeatedly if one result is enough.\n- If recipient email is missing, return: NEED_CONTACT_LOOKUP: contact name needed.\n- If message ID is missing for reply, search emails first.\n- If required information is still missing, return: NEED_CLARIFICATION: explain what is missing.\n- Never invent email addresses.\n- Return a short final result.",
"options": {},
"toolDescription": "Use this agent for Gmail tasks: search emails, read emails, send emails, draft emails, reply to emails, label emails, and get Gmail labels."
},
"typeVersion": 3
},
{
"id": "8c23c873-db83-49d6-b498-c6c4d6c0bc40",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
368,
704
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "97927de5-6594-49ef-b749-b429437ddbd6",
"name": "Send Email",
"type": "n8n-nodes-base.gmailTool",
"position": [
304,
848
],
"parameters": {
"sendTo": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('To', ``, 'string') }}",
"message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
"options": {
"appendAttribution": false
},
"subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "0a5bb036-20c0-4cc2-ae17-fabab311433d",
"name": "Reply to an Email",
"type": "n8n-nodes-base.gmailTool",
"position": [
416,
944
],
"parameters": {
"message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
"options": {
"ccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('CC', ``, 'string') }}",
"bccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('BCC', ``, 'string') }}",
"senderName": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sender_Name', ``, 'string') }}",
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('attachmentsBinary0_Attachment_Field_Name', ``, 'string') }}"
}
]
},
"appendAttribution": false
},
"emailType": "text",
"messageId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message_ID', ``, 'string') }}",
"operation": "reply",
"descriptionType": "manual",
"toolDescription": "Reply to an email message. AI-configurable parameters: Message_ID (string) - the ID of the message; Message (string) - the reply content; Attachment_Field_Name (string) - input field name containing attachments; BCC (string) - comma-separated BCC recipients; CC (string) - comma-separated CC recipients."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "57a108eb-95df-4793-8015-b753dd051b74",
"name": "Add Label to Email",
"type": "n8n-nodes-base.gmailTool",
"position": [
656,
1104
],
"parameters": {
"labelIds": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Label_Names_or_IDs', ``, 'string') }}",
"messageId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message_ID', ``, 'string') }}",
"operation": "addLabels",
"descriptionType": "manual",
"toolDescription": "Add one or more labels to an email message. AI-configurable parameters: Message_ID (string) - the ID of the message to label; Label_Names_or_IDs (string) - comma-separated label names or IDs to apply."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "72826dd4-cd50-46ce-bb56-e30e996a0cb4",
"name": "Get Labels",
"type": "n8n-nodes-base.gmailTool",
"position": [
752,
1040
],
"parameters": {
"resource": "label",
"returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}",
"descriptionType": "manual",
"toolDescription": "Retrieve a list of labels. AI-configurable parameters: Return_All (boolean) - whether to return all labels."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "a1a0f884-7b02-4ea8-8ab5-5e65fe822292",
"name": "Draft Email",
"type": "n8n-nodes-base.gmailTool",
"position": [
816,
928
],
"parameters": {
"message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
"options": {
"ccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('CC', ``, 'string') }}",
"sendTo": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('To_Email', ``, 'string') }}",
"bccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('BCC', ``, 'string') }}"
},
"subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}",
"resource": "draft",
"emailType": "html",
"descriptionType": "manual",
"toolDescription": "Create an email draft. AI-configurable parameters: Subject (string) - the subject of the draft; Message (string) - the body of the draft; Attachment_Field_Name__in_Input_ (string) - input field name containing attachments; BCC (string) - comma-separated BCC recipients; CC (string) - comma-separated CC recipients."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "e67e52f4-23b9-4ccd-b266-1eaccada24be",
"name": "Draft Email Reply",
"type": "n8n-nodes-base.gmailTool",
"position": [
896,
832
],
"parameters": {
"message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
"options": {
"ccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('CC', ``, 'string') }}",
"bccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('BCC', ``, 'string') }}",
"threadId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Thread_ID', ``, 'string') }}"
},
"subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}",
"resource": "draft",
"emailType": "html",
"descriptionType": "manual",
"toolDescription": "Draft a reply to an email. Use the thread_id parameter to pass the thread for which the email must be drafted"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "edb1e158-1aa4-4b8e-bed2-48c0162f7dca",
"name": "Check Availability",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1200,
848
],
"parameters": {
"options": {
"timezone": {
"__rl": true,
"mode": "list",
"value": "Asia/Kolkata",
"cachedResultName": "Asia/Kolkata"
}
},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_Time', ``, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Time', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"resource": "calendar",
"descriptionType": "manual",
"toolDescription": "Check if a slot is available on my calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "4f7947e1-16ab-4333-ad5d-1d95610fcf48",
"name": "Get all Events",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1296,
928
],
"parameters": {
"options": {
"orderBy": "startTime",
"timeZone": {
"__rl": true,
"mode": "list",
"value": "Asia/Kolkata",
"cachedResultName": "Asia/Kolkata"
},
"recurringEventHandling": "expand"
},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', `Should be a future date and time`, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "getAll",
"returnAll": true,
"descriptionType": "manual",
"toolDescription": "Get future events on Google Calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "47e2679d-11ac-4de9-82c9-3a7dbef5a92d",
"name": "Delete Calendar Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1376,
1040
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', `Pass the event id of the event to delete`, 'string') }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "delete",
"descriptionType": "manual",
"toolDescription": "Delete Calendar Event"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "8f1becf3-f0af-4dd5-bb6b-427a14428b0d",
"name": "Reschedule Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1504,
1056
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', `Pass the id of the event to reschedule or update`, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "update",
"updateFields": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
"attendeesUi": {
"values": {
"mode": "replace",
"attendees": [
"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('attendees0_Attendees', ``, 'string') }}"
]
}
},
"sendUpdates": "all"
},
"descriptionType": "manual",
"toolDescription": "Update an event on Google Calendar",
"useDefaultReminders": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Use_Default_Reminders', ``, 'boolean') }}"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "91388b6e-8031-4ade-8af8-c6595536244c",
"name": "Get Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1584,
944
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', `Pass the event id`, 'string') }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "get",
"descriptionType": "manual",
"toolDescription": "Get an event in Google Calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "31cbe7da-05a4-481f-aac1-485c5988e03c",
"name": "Create an event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1680,
832
],
"parameters": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"descriptionType": "manual",
"toolDescription": "Create an event on Google Calendar",
"additionalFields": {
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}",
"visibility": "default",
"description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"
},
"useDefaultReminders": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Use_Default_Reminders', ``, 'boolean') }}"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "b533d403-5119-4ed4-a27c-f927ac9784e7",
"name": "OpenAI Chat Model2",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1200,
704
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e4d9e4d0-a2b4-430a-a275-8bfe3f244c5d",
"name": "Task Agent",
"type": "@n8n/n8n-nodes-langchain.agentTool",
"position": [
2160,
624
],
"parameters": {
"text": "=You are the Google Tasks specialist agent.\n\nOriginal user request:\n{{ $fromAI('user_request', 'The exact original user message or transcribed voice message from the human user', 'string') }}\n\nSpecific task instruction:\n{{ $fromAI('task_instruction', 'The specific Google Tasks action the Manager Agent wants you to perform', 'string') }}\n\nKnown context:\n{{ $fromAI('context', 'Any useful context such as task title, due date, notes, task ID, or completion date', 'string') }}\n\nYour capabilities:\n- Create a task\n- Get one task\n- Get many tasks\n- Complete a task\n- Delete a task\n\nRules:\n- Use future dates unless user clearly says otherwise.\n- If task ID is missing for complete/delete, search tasks first.\n- Do not call tools repeatedly.\n- Return a short confirmation.",
"options": {},
"toolDescription": "Use this agent for Google Tasks: create tasks, get tasks, complete tasks, and delete tasks."
},
"typeVersion": 3
},
{
"id": "419a8548-701a-485a-b719-86816d21c919",
"name": "Calendar Agent",
"type": "@n8n/n8n-nodes-langchain.agentTool",
"position": [
1312,
640
],
"parameters": {
"text": "==You are the Calendar specialist agent.\n\nOriginal user request:\n{{ $fromAI('user_request', 'The exact original user message or transcribed voice message from the human user', 'string') }}\n\nSpecific calendar task:\n{{ $fromAI('calendar_task', 'The specific calendar task the Manager Agent wants you to perform', 'string') }}\n\nKnown context:\n{{ $fromAI('context', 'Any useful context such as date, time, attendee email, event title, event ID, or timezone', 'string') }}\n\nYour capabilities:\n- Check availability\n- Get upcoming events\n- Get a specific event\n- Create events\n- Reschedule events\n- Delete events\n\nRules:\n- Use Asia/Kolkata timezone unless another timezone is given.\n- If creating a meeting, check availability first.\n- If attendee email is missing, return: NEED_CONTACT_LOOKUP.\n- If event ID is missing for update/delete, search events first.\n- Do not call tools repeatedly.\n- Return a short confirmation.",
"options": {},
"toolDescription": "Use this agent for Google Calendar tasks: check availability, get events, create events, reschedule events, and delete events."
},
"typeVersion": 3
},
{
"id": "f4b18098-e6eb-40cc-ac83-791002f0c1cb",
"name": "Finance Agent",
"type": "@n8n/n8n-nodes-langchain.agentTool",
"position": [
2960,
624
],
"parameters": {
"text": "=You are the Finance specialist agent.\n\nOriginal user request:\n{{ $fromAI('user_request', 'The exact original user message or transcribed voice message from the human user', 'string') }}\n\nSpecific finance task:\n{{ $fromAI('finance_task', 'The specific finance or expense task the Manager Agent wants you to perform', 'string') }}\n\nKnown context:\n{{ $fromAI('context', 'Any useful context such as amount, date, category, description, row number, or spending period', 'string') }}\n\nExpense sheet columns:\n- Date\n- Description\n- Category\n- Amount\n\nRules:\n- If date is missing, use today\u2019s date.\n- If category is missing, infer a simple category.\n- Do not delete rows unless row number is clear.\n- Do not call tools repeatedly.\n- Return a short confirmation.",
"options": {},
"toolDescription": "Use this agent for expense tracking: log expenses, read expense data, summarize spending, and delete expense rows from Google Sheets."
},
"typeVersion": 3
},
{
"id": "8e6e97d7-3d26-42cc-9075-bdb6d2944aff",
"name": "Contacts Agent",
"type": "@n8n/n8n-nodes-langchain.agentTool",
"position": [
3648,
608
],
"parameters": {
"text": "=You are the Contacts specialist agent.\n\nOriginal user request:\n{{ $fromAI('user_request', 'The exact original user message or transcribed voice message from the human user', 'string') }}\n\nSpecific contact lookup task:\n{{ $fromAI('contact_task', 'The specific contact search the Manager Agent wants you to perform', 'string') }}\n\nKnown context:\n{{ $fromAI('context', 'Any useful context such as contact name, company, email domain, or purpose of lookup', 'string') }}\n\nRules:\n- Search contacts by name or email.\n- Do not invent contact details.\n- If multiple contacts match, return the best matches clearly.\n- If no contact is found, return: CONTACT_NOT_FOUND.",
"options": {},
"toolDescription": "Use this agent to find Google Contacts information such as names and email addresses."
},
"typeVersion": 3
},
{
"id": "35e70c63-b841-4b67-984a-d146a9903c1d",
"name": "Complete a Task",
"type": "n8n-nodes-base.googleTasksTool",
"position": [
2496,
832
],
"parameters": {
"task": "=",
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', `Pass the task_id of the task to be completed`, 'string') }}",
"operation": "update",
"updateFields": {
"status": "completed",
"completed": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Completion_Date', `Pass the date when the task is completed`, 'string') }}"
}
},
"credentials": {
"googleTasksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "be7090f8-1aa6-4cda-83c3-3a1564ae66e1",
"name": "Get many Tasks",
"type": "n8n-nodes-base.googleTasksTool",
"position": [
2432,
976
],
"parameters": {
"task": "=",
"operation": "getAll",
"returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}",
"descriptionType": "manual",
"toolDescription": "Get tasks from Google Tasks",
"additionalFields": {
"showCompleted": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Show_Completed', ``, 'boolean') }}"
}
},
"credentials": {
"googleTasksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "13b820dd-bacb-462b-beb4-30b33550c36a",
"name": "Delete a Task",
"type": "n8n-nodes-base.googleTasksTool",
"position": [
2320,
1024
],
"parameters": {
"task": "=",
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "delete"
},
"credentials": {
"googleTasksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9f336b75-f244-4b14-9fe2-f1415ce76c43",
"name": "Get a Task",
"type": "n8n-nodes-base.googleTasksTool",
"position": [
2192,
960
],
"parameters": {
"task": "=",
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "get"
},
"credentials": {
"googleTasksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "8ad63970-5ae7-4824-8c52-7305d2a229b0",
"name": "Create a Task",
"type": "n8n-nodes-base.googleTasksTool",
"position": [
2096,
848
],
"parameters": {
"task": "=",
"title": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Title', ``, 'string') }}",
"additionalFields": {
"notes": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Notes', ``, 'string') }}",
"dueDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_Date', `Always use future dates`, 'string') }}"
}
},
"credentials": {
"googleTasksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "65bcf383-82a6-4071-95be-ebe414aba50f",
"name": "OpenAI Chat Model3",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2032,
672
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e5f8271a-21b1-4ae1-a346-64eade3b659b",
"name": "Get all Expenses",
"type": "n8n-nodes-base.googleSheetsTool",
"notes": "\ud83d\udcca READ SPREADSHEET DATA\n\nRetrieve and analyze data from Google Sheets. Perfect for AI to read, process, and extract insights from spreadsheet content.\n\nUse Cases:\n\u2022 \"Read data from the Sales sheet\"\n\u2022 \"Get all entries from A1:E100\"\n\u2022 \"Show me the data in the Budget spreadsheet\"\n\u2022 \"Extract customer information from the CRM sheet\"\n\nAI Parameters:\n\u2022 Document_ID: Target spreadsheet ID\n\u2022 Sheet_Name: Specific sheet tab name\n\u2022 Range: Cell range to read (optional)",
"position": [
2944,
832
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit?usp=drivesdk",
"cachedResultName": "Expense Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "102a720b-e116-4675-b733-03d65bf84443",
"name": "Create Expense",
"type": "n8n-nodes-base.googleSheetsTool",
"notes": "\ud83d\uddd1\ufe0f CLEAR SPREADSHEET DATA\n\nRemove data from specific ranges or entire sheets. Useful for resetting data, clearing temporary calculations, or preparing sheets for new data.\n\nUse Cases:\n\u2022 \"Clear all data from the temp sheet\"\n\u2022 \"Remove entries from A1:E100\"\n\u2022 \"Clean up the old data in column C\"\n\u2022 \"Reset the calculation area\"\n\nAI Parameters:\n\u2022 Document_ID: Target spreadsheet ID\n\u2022 Sheet_Name: Sheet to clear data from\n\u2022 Range: Specific range to clear\n\n\u26a0\ufe0f Use with caution - data will be permanently removed!",
"position": [
3088,
864
],
"parameters": {
"columns": {
"value": {
"Date": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Date', ``, 'string') }}",
"Amount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Amount', ``, 'string') }}",
"Category": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Category', ``, 'string') }}",
"Description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"
},
"schema": [
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Description",
"type": "string",
"display": true,
"required": false,
"displayName": "Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Category",
"type": "string",
"display": true,
"required": false,
"displayName": "Category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit?usp=drivesdk",
"cachedResultName": "Expense Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "d6d2b26f-0171-4f74-9f82-cb39cc47d0a2",
"name": "Delete Expense",
"type": "n8n-nodes-base.googleSheetsTool",
"notes": "\u2795 ADD NEW DATA\n\nAppend new rows of data to existing sheets. Perfect for adding records, logging events, or inserting new entries without affecting existing data.\n\nUse Cases:\n\u2022 \"Add a new customer to the CRM sheet\"\n\u2022 \"Log today's sales data\"\n\u2022 \"Insert a new project entry\"\n\u2022 \"Record the meeting notes\"\n\nAI Parameters:\n\u2022 Document_ID: Target spreadsheet ID\n\u2022 Sheet_Name: Sheet to add data to\n\u2022 Data_To_Add: Array/object of new data\n\nFeatures:\n\u2022 Automatically finds next empty row\n\u2022 Preserves existing data\n\u2022 Supports multiple columns",
"position": [
3216,
816
],
"parameters": {
"clear": "specificRows",
"operation": "clear",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCS8_RA5neEDAmgotpzgbBbeEjdYi-LAmCSJVeNWVxs/edit?usp=drivesdk",
"cachedResultName": "Expense Tracker"
},
"startIndex": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Row_Number', ``, 'number') }}",
"rowsToDelete": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Number_of_Rows_to_Delete', ``, 'number') }}"
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "ee182845-9c3d-4a1e-ad29-ff158ba8a1e3",
"name": "OpenAI Chat Model4",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2848,
640
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "6778ab0a-2e54-4f30-a5a0-fa2a37574e11",
"name": "Get Contacts",
"type": "n8n-nodes-base.googleContactsTool",
"position": [
3744,
832
],
"parameters": {
"query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query', ``, 'string') }}",
"fields": [
"names",
"emailAddresses"
],
"options": {},
"rawData": true,
"useQuery": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Use_Query', ``, 'boolean') }}",
"operation": "getAll"
},
"credentials": {
"googleContactsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "90eb3c5f-62d2-4ca5-8942-35a651cb1bcc",
"name": "Send a text message",
"type": "n8n-nodes-base.telegram",
"position": [
2464,
-240
],
"parameters": {
"text": "={{ $('Set Reply Message').item.json.message.replace(/[_*\\[\\]()~`>#+=\\-|{}.!\\\\]/g, '\\\\$&') }}",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"additionalFields": {
"parse_mode": "MarkdownV2",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "82a232e7-e2b2-4879-8247-08698f004edf",
"name": "Set Reply Message",
"type": "n8n-nodes-base.set",
"position": [
1648,
-16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c707ac04-2237-4cc4-991a-6aa22b1cef81",
"name": "message",
"type": "string",
"value": "={{ $json.output || $json.error }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8b496e22-6c4a-45f2-8847-959bc0d336e9",
"name": "Check Text or Audio",
"type": "n8n-nodes-base.switch",
"position": [
1936,
-16
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Text",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9f763ec1-25e5-4a4d-88fa-70156851ff2a",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $('Telegram Trigger').item.json.message.text }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "Audio",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "12be0a10-540d-423c-82de-00d0e9e9e501",
"operator": {
"type": "string",
"operation": "notExists",
"singleValue": true
},
"leftValue": "={{ $('Telegram Trigger').item.json.message.text }}",
"rightValue": ""
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "3b19cd56-2961-4143-84c3-fde883603e97",
"name": "Send an audio file",
"type": "n8n-nodes-base.telegram",
"position": [
2464,
0
],
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"operation": "sendAudio",
"binaryData": true,
"additionalFields": {
"caption": "={{ $('Set Reply Message').item.json.message.replace(/[_*\\[\\]()~`>#+=\\-|{}.!\\\\]/g, '\\\\$&') }}",
"fileName": "Jarvis's Reply"
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "4a651597-9be1-4d89-8c09-8083e09742c2",
"name": "Generate audio",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2208,
64
],
"parameters": {
"input": "={{ $('Set Reply Message').item.json.message }}",
"options": {},
"resource": "audio"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "d8a3a412-0867-40bc-bbdf-28ae9acf4db5",
"name": "OpenAI Chat Model5",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
3520,
640
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "3c58d66f-0369-41e7-b7dd-179f6d55db4a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-288
],
"parameters": {
"color": "#CC94A8",
"width": 352,
"height": 448,
"content": "## Telegram Trigger\n\n### What this node does\nThis node starts the workflow whenever the Telegram bot receives a new message.\n\n### How it works\nIt listens for incoming Telegram updates, especially user messages. When a user sends a text or voice message to the bot, this node captures the message data such as chat ID, message text, voice file ID, and sender information.\n"
},
"typeVersion": 1
},
{
"id": "c2ee1072-29ca-4c9a-8228-fe6c634351a8",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
-192
],
"parameters": {
"color": "#CC8FCA",
"height": 352,
"content": "## Switch\n\n### What this node does\nThis node checks whether the Telegram message is text or audio.\n\n"
},
"typeVersion": 1
},
{
"id": "85af8a6a-f89e-4b03-aaf1-f2ef6341af19",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
528,
-208
],
"parameters": {
"color": "#AA98D2",
"height": 416,
"content": "## Get a file\n\n### What this node does\nThis node downloads the voice message file from Telegram.\n\n### How it works\nWhen the user sends a voice note, Telegram provides a `file_id`. This node uses that file ID to fetch the actual audio file from Telegram.\n"
},
"typeVersion": 1
},
{
"id": "6715aca7-971c-4067-afd3-2f02cf2cd115",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
784,
-32
],
"parameters": {
"color": "#92AED3",
"height": 320,
"content": "## Transcribe a recording\n\n### What this node does\nThis node converts the Telegram voice message into text.\n"
},
"typeVersion": 1
},
{
"id": "84ace482-8358-4010-9176-cb8df76ffa30",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
-560
],
"parameters": {
"color": "#9BCABB",
"width": 320,
"height": 720,
"content": "## Jarvis Manager Agent\n\n### What this node does\nThis is the main brain of the workflow.\n\n### How it works\nThe Manager Agent receives either:\n- Direct Telegram text, or\n- Transcribed voice text\n\nIt understands the user\u2019s intent and decides which specialist agent should handle the request.\n\n### Supported specialist agents\n- Gmail Agent\n- Calendar Agent\n- Task Agent\n- Finance Agent\n- Contacts Agent\n\n### Why it is important\nInstead of one agent doing everything, this node routes the request to the correct expert agent, making the workflow more organized and scalable.\n"
},
"typeVersion": 1
},
{
"id": "4694d50f-73d2-4524-bf8f-c6db50127c1c",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
592
],
"parameters": {
"color": "#C7A3D2",
"width": 768,
"height": 736,
"content": ""
},
"typeVersion": 1
},
{
"id": "2a36e241-5920-415a-bb9d-1282e3bf1b5a",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1088,
592
],
"parameters": {
"color": "#9C9FC9",
"width": 752,
"height": 736,
"content": ""
},
"typeVersion": 1
},
{
"id": "cdb22ad1-b669-4ffa-8569-cff9c2df86aa",
"name": "Get Emails",
"type": "n8n-nodes-base.gmailTool",
"position": [
528,
1040
],
"parameters": {
"filters": {
"q": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search', ``, 'string') }}",
"receivedAfter": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Received_After', ``, 'string') }}",
"receivedBefore": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Received_Before', ``, 'string') }}"
},
"operation": "getAll",
"returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}",
"descriptionType": "manual",
"toolDescription": "Retrieve multiple email messages based on filters. AI-configurable parameters: Return_All (boolean) - whether to return all matching messages; Search (string) - Gmail query string to filter messages; Received_After (string) - datetime (RFC3339) after which messages are received; Received_Before (string) - datetime before which messages are received; Sender (string) - email address of the sender."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "56ab6f68-d2cf-44a6-a4b7-327a1b27fffc",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1936,
592
],
"parameters": {
"color": "#9FC1BB",
"width": 752,
"height": 736,
"content": ""
},
"typeVersion": 1
},
{
"id": "05aa6b29-2917-44c5-96df-0ec2a12a1c2f",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2784,
592
],
"parameters": {
"color": "#B1BD84",
"width": 592,
"height": 736,
"content": ""
},
"typeVersion": 1
},
{
"id": "a9711078-6ab6-4cd9-986f-d64e43d757d8",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3456,
592
],
"parameters": {
"color": "#D3B98D",
"width": 544,
"height": 704,
"content": ""
},
"typeVersion": 1
},
{
"id": "83f78e91-ad66-49d9-9cf8-365f4d624e7f",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
1120
],
"parameters": {
"color": "#834F92",
"width": 272,
"height": 512,
"content": "## Gmail Agent\n\n### What this node does\nThis is the specialist agent for Gmail-related tasks.\n\n### How it works\nThe Manager Agent sends Gmail tasks to this agent, such as:\n- Search emails\n- Read emails\n- Send emails\n- Draft emails\n- Reply to emails\n- Add labels\n- Get Gmail labels\n\nThe Gmail Agent then chooses the correct Gmail tool.\n\n### Why it is important\nIt separates Gmail logic from the main agent and makes email automation easier to manage."
},
"typeVersion": 1
},
{
"id": "1f767997-4838-42da-92bf-b3dbfb3207d9",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1088,
1184
],
"parameters": {
"color": "#484A60",
"width": 320,
"height": 448,
"content": "## Calendar Agent\n\n### What this node does\nThis is the specialist agent for Google Calendar tasks.\n\n### How it works\nThe Manager Agent sends calendar-related requests to this agent, such as:\n- Check availability\n- Get events\n- Create events\n- Reschedule events\n- Delete events\n\nThe Calendar Agent then chooses the correct Google Calendar tool.\n\n### Why it is important\nIt keeps calendar logic separate from email, tasks, contacts, and finance operations.\n"
},
"typeVersion": 1
},
{
"id": "3ba1956d-9bbd-4b6f-a33c-9ca17e775a92",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
1936,
1104
],
"parameters": {
"color": "#4F6D68",
"width": 304,
"height": 368,
"content": "## Task Agent\n\n### What this node does\nThis is the specialist agent for Google Tasks.\n\n### How it works\nThe Manager Agent sends task-related requests to this agent, such as:\n- Create a task\n- Get a task\n- Get many tasks\n- Complete a task\n- Delete a task\n\nThe Task Agent then selects the correct Google Tasks tool."
},
"typeVersion": 1
},
{
"id": "7a3e0c14-d63c-45cf-9283-1658bf8ebdcd",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
2784,
1120
],
"parameters": {
"color": "#606746",
"width": 288,
"height": 368,
"content": "## Finance Agent\n\n### What this node does\nThis is the specialist agent for expense tracking.\n\n### How it works\nThe Manager Agent sends finance-related requests to this agent, such as:\n- Log an expense\n- Read expense data\n- Summarize spending\n- Delete expense rows\n\nThe Finance Agent then uses Google Sheets tools to manage expense records.\n"
},
"typeVersion": 1
},
{
"id": "e1144763-524d-4343-a08b-2b840ed50a48",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
3456,
1136
],
"parameters": {
"color": "#6F6149",
"width": 256,
"height": 256,
"content": "## Contacts Agent\n\n### What this node does\nThis is the specialist agent for Google Contacts lookup.\n\n### How it works\nThe Manager Agent sends contact search requests to this agent. It searches Google Contacts by name, email, or related query."
},
"typeVersion": 1
},
{
"id": "b1a1d4bd-aac2-49aa-bb96-3faa71b6f296",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
1568,
-256
],
"parameters": {
"color": "#B9E2B1",
"width": 256,
"height": 416,
"content": "## Set Reply Message\n\n### What this node does\nThis node prepares the final response message.\n\n### How it works\nIt takes the output from the Jarvis Manager Agent and stores it in a clean field called `message`.\n"
},
"typeVersion": 1
},
{
"id": "7a74cfdc-6ff3-44aa-9453-9fb40d10e3d2",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"position": [
1856,
-304
],
"parameters": {
"color": "#BFCE88",
"width": 256,
"height": 464,
"content": "## Check Text or Audio\n\n### What this node does\nThis node decides whether Jarvis should reply with text or audio.\n\n### How it works\nIt checks the original Telegram message:\n- If the user sent text, Jarvis replies with text.\n- If the user sent audio, Jarvis generates and sends an audio reply."
},
"typeVersion": 1
},
{
"id": "ab797c23-4b3a-43ad-8f45-ecce038d4222",
"name": "Sticky Note17",
"type": "n8n-nodes-base.stickyNote",
"position": [
2400,
-416
],
"parameters": {
"color": "#F2D097",
"height": 336,
"content": "## Send a text message\n\n### What this node does\nThis node sends Jarvis\u2019s final reply as a Telegram text message.\n\n"
},
"typeVersion": 1
},
{
"id": "b11fcc9d-9d9f-4388-bc84-26409d698688",
"name": "Sticky Note18",
"type": "n8n-nodes-base.stickyNote",
"position": [
2160,
32
],
"parameters": {
"color": "#B6AB81",
"width": 224,
"height": 512,
"content": "\n\n\n\n\n\n\n\n\n\n\n## Generate audio\n\n### What this node does\nThis node converts Jarvis\u2019s final text reply into speech.\n\n### How it works\nIt takes the final response from `Set Reply Message` and sends it to OpenAI\u2019s audio generation model.\n\n### Why it is important\nIt allows Jarvis to respond with voice when the user sends a voice message."
},
"typeVersion": 1
},
{
"id": "c56dad7e-7c8b-48e3-9b11-1f130a743906",
"name": "Sticky Note19",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
-32
],
"parameters": {
"color": "#CE9669",
"width": 224,
"height": 480,
"content": "\n\n\n\n\n\n\n\n\n\n\n## Send an audio file\n\n### What this node does\nThis node sends Jarvis\u2019s generated voice reply back to Telegram.\n\n### How it works\nIt sends the generated audio file to the same Telegram chat. The text response is also added as a caption."
},
"typeVersion": 1
},
{
"id": "266bb17d-f317-4f69-8793-6c5c710a3ce7",
"name": "Sticky Note20",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-608
],
"parameters": {
"color": "#F8D8D8",
"width": 800,
"height": 272,
"content": "# Workflow Overview\n\n### This workflow turns Telegram into a personal AI productivity assistant called **Jarvis**. \n### Users can send text or voice messages, and voice messages are automatically transcribed into text. \n### The main Jarvis Manager Agent understands the request and routes it to the correct specialist agent: Gmail, Calendar, Tasks, Finance, or Contacts. \n### Each specialist agent uses connected Google/OpenAI tools to complete the action, such as sending emails, checking meetings, creating tasks, logging expenses, or finding contacts. \n### Finally, Jarvis sends the result back to Telegram as a text reply or an audio response. "
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "88dfff0c-fe7b-4f88-8bdc-7a90428a2a8f",
"connections": {
"Think": {
"ai_tool": [
[
{
"node": "Jarvis Manager Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Jarvis Manager Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Get a file",
"type": "main",
"index": 0
}
]
]
},
"Get Event": {
"ai_tool": [
[
{
"node": "Calendar Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get Emails": {
"ai_tool": [
[
{
"node": "Gmail Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get Labels": {
"ai_tool": [
[
{
"node": "Gmail Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get a Task": {
"ai_tool": [
[
{
"node": "Task Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get a file": {
"main": [
[
{
"node": "Transcribe a recording",
"type": "main",
"index": 0
}
]
]
},
"Send Email": {
"ai_tool": [
[
{
"node": "Gmail Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Task Agent": {
"ai_tool": [
[
{
"node": "Jarvis Manager Agent",
"type": "ai_tool
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.
gmailOAuth2googleCalendarOAuth2ApigoogleContactsOAuth2ApigoogleSheetsOAuth2ApigoogleTasksOAuth2ApiopenAiApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Jarvis is a powerful multi-agent productivity assistant built in n8n. It works directly from Telegram and can understand both text messages and voice notes.
Source: https://n8n.io/workflows/15672/ — 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.
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.
Telegram Trigger receives incoming messages (text, voice, photo, document). Switch routes by message type to appropriate processors: Text → forwarded as-is. Voice → downloaded and sent to Transcribe a
Transform your Telegram messenger into a powerful, multi-modal personal or team assistant. This n8n workflow creates an intelligent agent that can understand text, voice, images, and documents, and ta
Digital marketers, content creators, social media managers, and businesses who want to use AI marketing automation for YouTube Shorts without spending hours on production. This AI workflow helps anyon
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