This workflow corresponds to n8n.io template #9700 — we link there as the canonical source.
This workflow follows the Agent → Datatable 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": "KmdYybT84NNAa1yM",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Telegram bot for capturing CRM contacts",
"tags": [
{
"id": "0fVOYNM7WPnd6GTh",
"name": "public",
"createdAt": "2025-10-14T10:25:40.579Z",
"updatedAt": "2025-10-14T10:25:40.579Z"
}
],
"nodes": [
{
"id": "baf521e1-ad2c-40cf-bdd6-78c1872987d7",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
-720,
-48
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {
"download": true,
"imageSize": "large"
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "acd4c00f-ab7d-4c20-925f-7f8e827bbf17",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-832,
368
],
"parameters": {
"width": 816,
"height": 800,
"content": "## Telegram bot for capturing contacts\n\nThis workflow is an AI agent in the form of a Telegram bot. Its main purpose is to **capture contact information and store it in a CRM**. The agent supports multi-modal inputs and can extract contact details from text messages, voice recordings, and images (like photos of business cards).\n\nThe bot guides the user through data collection via a natural conversation, asks clarifying questions for missing information, and summarizes the extracted data for confirmation before saving. It also checks for duplicate contacts by email and gives users the choice to either create a new contact or update an existing one.\n\nFor simplicity, this example uses a Google Sheets document to store collected contacts. It can easily be replaced by a real CRM like HubSpot, Pipedrive, Monday, etc.\n\n### How to use the bot\n\nSend contact details via text or voice, or upload a photo of a business card. The bot will show the extracted information and ask questions when needed. Once the bot confirms saving of the current contact, you can send the next one. Use the `/new` command at any moment to discard the previous conversation and start from scratch.\n\n### Requirements\n1. A Telegram bot [Access Token](https://docs.n8n.io/integrations/builtin/credentials/telegram/)\n2. Google Gemini API key\n3. Google Sheets credentials\n\n### Setup\n1. Create a new Telegram bot (see [n8n docs](https://docs.n8n.io/integrations/builtin/credentials/telegram/#using-api-bot-access-token) and [Telegram bot API docs](https://core.telegram.org/bots/features) for details)\n2. Take webhook URL from the Telegram Trigger node (`WEBHOOK_URL`) and your bot's access token (`TOKEN`) and run `curl -X POST \"https://api.telegram.org/bot{TOKEN}/setWebhook?url={WEBHOOK_URL}\"`\n2. Create a new Google Sheets document with \"Full name\", \"Email\", \"Phone\", \"Company\", \"Job title\" and \"Meeting notes\" columns\n3. Configure parameters in the **parameters** node:\n - Set ID of the Google Sheets document\n - Set sheet name (\"Sheet1\" by default)\n4. Configure Google Sheets credentials for AI Agent's tools: **Search for contact** and **Create new contact** and **Update existing contact**.\n5. Add Google Gemini API key for the models (\"AI Agent\", \"Transcribe audio\", \"Analyze image\" nodes)"
},
"typeVersion": 1
},
{
"id": "62ece471-e4b4-4ed8-ae54-338a6acd02e4",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
384,
1168
],
"parameters": {
"text": "={{ $json.userMessage }}",
"options": {
"systemMessage": "You are a helpful personal assistant. You are direct and don't talk much.\nYour job is to create and update contacts in the CRM system. User communicates with you via text, audio (transcribed) and images (recognized).\n\nIt is mandatory to extract the following information:\n- first name\n- last name\n- email\n- company name\n\nWhenever possible extract as well:\n- phone number \n- job title\n- meeting notes\n\nYou may ask up to 3 questions about each new contact. Always confirm extracted information using the following format.\n\nExample of confirmation when all mandatory data is extracted, but there are no meeting notes:\n\"\"\"\n\u2705 First name: {first_name}\n\u2705 Last name: {last_name}\n\u2705 Email: {email}\n\u2705 Company: {company}\n\nDo you have any other info or meeting notes?\n\"\"\"\n\nExample of confirmation when some data is missing:\n\"\"\"\n\u2705 First name: {first_name}\n\u2753 Last name:\n\u2705 Email: {email}\n\u2753 Company:\n\nDo you know the last name and the company name?\n\"\"\"\n\nExample of confirmation when all mandatory data, as well as some extra data and meeting notes are extracted:\n\"\"\"\n\u2705 First name: {first_name}\n\u2705 Last name: {last_name}\n\u2705 Email: {email}\n\u2705 Company: {company}\n\u2705 Title: {job_title}\n\u2705 Phone: {phone}\n\nDo you have any other info?\n\"\"\"\n\nOnce all the information for a contact is collected, search the CRM for an existing contact by email. If the contact is not found, create a new contact. If the contact exists, ask user whether to create a new contact or update the existing one.\n\nIMPORTANT:\nIf phone number begins with \"+\", prepend it with \"'\" (single quote symbol) when saving. The CRM expects the phone in this format. \n\nUser may send `/new` command which indicates beginning of a fresh chat session. In this case simply confirm that you are waiting for a new contact."
},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "791fd96b-9808-4573-af52-226695245cf5",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
192,
1392
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "c3feefb6-c757-42aa-b78a-af8cc1b8026c",
"name": "Send a text message",
"type": "n8n-nodes-base.telegram",
"position": [
1104,
1168
],
"parameters": {
"text": "={{ $json.output }}",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "510e5fa0-1ab1-44be-9338-12ceef3474bb",
"name": "Get sessionID",
"type": "n8n-nodes-base.dataTable",
"position": [
192,
-208
],
"parameters": {
"limit": 1,
"filters": {
"conditions": [
{
"keyName": "chatID",
"keyValue": "={{ $json.message.chat.id }}"
}
]
},
"matchType": "allConditions",
"operation": "get",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "Y6od4eTrxRkUbtyC",
"cachedResultUrl": "/projects/ZnaXyIe6Nbrn9Af2/datatables/Y6od4eTrxRkUbtyC",
"cachedResultName": "telegram-crm-example"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "d320aae4-14ec-4682-8b79-3f320ca58c24",
"name": "Generate sessionID",
"type": "n8n-nodes-base.crypto",
"position": [
752,
-208
],
"parameters": {
"action": "generate",
"dataPropertyName": "sessionID"
},
"typeVersion": 1
},
{
"id": "96f9ff1d-c25a-471e-ab11-ac6985ac61c0",
"name": "Upsert row(s)",
"type": "n8n-nodes-base.dataTable",
"position": [
1008,
-208
],
"parameters": {
"columns": {
"value": {
"chatID": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"sessionID": "={{ $json.sessionID }}"
},
"schema": [
{
"id": "chatID",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "chatID",
"defaultMatch": false
},
{
"id": "sessionID",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "sessionID",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"sessionID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"filters": {
"conditions": [
{
"keyName": "chatID",
"keyValue": "={{ $('Telegram Trigger').item.json.message.chat.id }}"
}
]
},
"matchType": "allConditions",
"operation": "upsert",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "Y6od4eTrxRkUbtyC",
"cachedResultUrl": "/projects/ZnaXyIe6Nbrn9Af2/datatables/Y6od4eTrxRkUbtyC",
"cachedResultName": "telegram-crm-example"
}
},
"typeVersion": 1
},
{
"id": "5f7ce514-bccc-414d-8337-1d051cf03538",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
-304
],
"parameters": {
"color": 6,
"width": 1024,
"height": 256,
"content": "## Get existing sessionID or create a new one\nsessionID is used to store conversation history"
},
"typeVersion": 1
},
{
"id": "cd95f448-16aa-4746-b9bc-89966dbcd1c6",
"name": "If no sessionID or /new",
"type": "n8n-nodes-base.if",
"position": [
496,
-208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "aa9bdac4-3246-4a92-98ed-695640ff93d7",
"operator": {
"type": "object",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json }}",
"rightValue": ""
},
{
"id": "92c64c2d-5a97-4f07-a98d-b4035930bb56",
"operator": {
"type": "string",
"operation": "notExists",
"singleValue": true
},
"leftValue": "={{ $json.sessionID }}",
"rightValue": ""
},
{
"id": "b4e2e2b1-63de-4c57-9218-27bb29e3f18d",
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $('Telegram Trigger').item.json.message.text }}",
"rightValue": "/new"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "5281020e-eb31-426c-b123-eb4e1fb0df07",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
336,
1424
],
"parameters": {
"sessionKey": "={{ $('Add sessionID to input').item.json.sessionID }}",
"sessionIdType": "customKey",
"contextWindowLength": 10
},
"typeVersion": 1.3
},
{
"id": "a292b5ef-a1d7-48dd-b806-f6a154a1a8a9",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
432,
192
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "audio input",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c0814978-ad52-4537-bdfb-c83b83955df4",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.voice }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "image input",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cc1fd7ef-c1cf-4682-8cad-65833275ff23",
"operator": {
"type": "array",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.photo }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "text input",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "aeff368c-421b-4823-aeec-dc4473d9ff76",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.text }}",
"rightValue": ""
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.3
},
{
"id": "f0f58425-7e6c-4ec7-bd21-849dc6471e1e",
"name": "Add sessionID to input",
"type": "n8n-nodes-base.merge",
"position": [
208,
224
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "4661d734-4f58-412f-bb74-9789eb11feb6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
48
],
"parameters": {
"color": 6,
"width": 992,
"height": 944,
"content": "## Process various types of user messages\n- Transcribe audio\n- Analyse image\n- Prepare text message"
},
"typeVersion": 1
},
{
"id": "532435f7-2ed0-4c4c-a783-cd3e2d7761d0",
"name": "parameters",
"type": "n8n-nodes-base.set",
"position": [
-192,
-48
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "8c23a9c4-8623-41b6-bbe0-e34f0d500611",
"name": "spreadsheet_document_id",
"type": "string",
"value": ""
},
{
"id": "309e133e-faa1-47d3-83f6-77f153da7239",
"name": "sheet_name",
"type": "string",
"value": "Sheet1"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "7ac77e30-faf2-4f88-bdee-0bf3e4fcbbe5",
"name": "Create new contact",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
656,
1488
],
"parameters": {
"columns": {
"value": {
"Email": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Email__using_to_match_', `Contact's email`, 'string') }}",
"Phone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Phone', `Contact's phone number`, 'string') }}",
"Company": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Company', `Company name`, 'string') }}",
"Full name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Full_name', `Contact's full name (first name + last name)`, 'string') }}",
"Job title": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Job_title', `Contact's job title`, 'string') }}",
"Meeting notes": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Meeting_notes', `Notes from the meeting with contact`, 'string') }}"
},
"schema": [
{
"id": "Full name",
"type": "string",
"display": true,
"required": false,
"displayName": "Full name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone",
"type": "string",
"display": true,
"required": false,
"displayName": "Phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company",
"type": "string",
"display": true,
"required": false,
"displayName": "Company",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Job title",
"type": "string",
"display": true,
"required": false,
"displayName": "Job title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Meeting notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Meeting notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {
"useAppend": true
},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('parameters').item.json.sheet_name }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('parameters').item.json.spreadsheet_document_id }}"
},
"authentication": "serviceAccount",
"descriptionType": "manual",
"toolDescription": "Create a new contact in CRM"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "005acc6f-eb10-47cf-a45f-c8fbe7e0ed01",
"name": "Update existing contact",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
816,
1504
],
"parameters": {
"columns": {
"value": {
"Email": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Email__using_to_match_', `Contact's email`, 'string') }}",
"Phone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Phone', `Contact's phone number`, 'string') }}",
"Company": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Company', `Company name`, 'string') }}",
"Full name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Full_name', `Contact's full name (first name + last name)`, 'string') }}",
"Job title": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Job_title', `Contact's job title`, 'string') }}",
"Meeting notes": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Meeting_notes', `Notes from the meeting with contact`, 'string') }}"
},
"schema": [
{
"id": "Full name",
"type": "string",
"display": true,
"required": false,
"displayName": "Full name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone",
"type": "string",
"display": true,
"required": false,
"displayName": "Phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company",
"type": "string",
"display": true,
"required": false,
"displayName": "Company",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Job title",
"type": "string",
"display": true,
"required": false,
"displayName": "Job title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Meeting notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Meeting notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('parameters').item.json.sheet_name }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('parameters').item.json.spreadsheet_document_id }}"
},
"authentication": "serviceAccount",
"descriptionType": "manual",
"toolDescription": "Update existing contact in CRM"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "f842b387-64bb-4555-95aa-43deedb813cb",
"name": "Search for contact",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
496,
1456
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('values0_Value', `Contact's email`, 'string') }}",
"lookupColumn": "Email"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('parameters').item.json.sheet_name }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('parameters').item.json.spreadsheet_document_id }}"
},
"authentication": "serviceAccount",
"descriptionType": "manual",
"toolDescription": "Search for an exisitng contact in CRM (by email)"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "9fbf58e9-4e04-4cdf-99b9-962cc1659232",
"name": "Send \"typing...\"",
"type": "n8n-nodes-base.telegram",
"position": [
-464,
-256
],
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"operation": "sendChatAction"
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "6f06a5e9-e54d-4333-b720-4234b95d7fd5",
"name": "Get audio file",
"type": "n8n-nodes-base.telegram",
"position": [
752,
352
],
"parameters": {
"fileId": "={{ $json.message.voice.file_id }}",
"resource": "file",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "804bfa01-8a62-46ed-b86b-c3c21776acdf",
"name": "Transcribe audio",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"position": [
960,
352
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-flash",
"cachedResultName": "models/gemini-2.5-flash"
},
"options": {},
"resource": "audio",
"inputType": "binary"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "06564c94-911c-42bc-86a0-9562d02469e4",
"name": "Process audio transcript",
"type": "n8n-nodes-base.code",
"position": [
1168,
352
],
"parameters": {
"jsCode": "let new_items = []\nlet index = 0\nfor (const item of $input.all()) {\n let userMessage = \"<transcribed_audio>\" + item.json.content.parts[0].text + \"</transcribed_audio>\";\n \n new_items.push({\n \"userMessage\": userMessage\n })\n\n index += 1;\n}\n\nreturn new_items;"
},
"typeVersion": 2
},
{
"id": "5b0e9ade-60c3-46a6-a00f-2d7183750fb1",
"name": "Analyze image",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"position": [
752,
576
],
"parameters": {
"text": "Extract contact information from this image. Look for the following information:\n- first name\n- last name\n- email\n- phone number\n- company name\n- job title",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-flash",
"cachedResultName": "models/gemini-2.5-flash"
},
"options": {},
"resource": "image",
"simplify": false,
"inputType": "binary",
"operation": "analyze"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "192ac754-ad6c-46c6-9e93-12833cb00751",
"name": "Process extracted data",
"type": "n8n-nodes-base.code",
"position": [
960,
576
],
"parameters": {
"jsCode": "let new_items = []\nlet index = 0\nfor (const item of $input.all()) {\n let userMessage = \"<extracted_image_content>\" + item.json.candidates[0].content.parts[0].text + \"</extracted_image_content>\";\n let text = $('Switch').itemMatching(index).json.message.caption\n if (text) {\n userMessage += \"\\n\" + text;\n }\n \n new_items.push({\n \"userMessage\": userMessage\n })\n\n index += 1;\n}\n\nreturn new_items;"
},
"typeVersion": 2
},
{
"id": "dba4133a-dd92-4a4f-9170-0b14af98a63d",
"name": "Process text input",
"type": "n8n-nodes-base.code",
"position": [
752,
784
],
"parameters": {
"jsCode": "let new_items = []\nfor (const item of $input.all()) {\n let userMessage = item.json.message.text;\n \n new_items.push({\n \"userMessage\": userMessage\n })\n}\n\nreturn new_items;"
},
"typeVersion": 2
},
{
"id": "2fce79a3-9119-41cc-835a-fe8fb04af738",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-272,
-160
],
"parameters": {
"color": 5,
"width": 256,
"height": 272,
"content": "## Configure\n\u27a4 set spreadsheet document ID\n\u27a4 set sheet name"
},
"typeVersion": 1
},
{
"id": "085c7e80-bd92-4f6b-ad39-b5a6ee2f13ed",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
128,
1072
],
"parameters": {
"color": 6,
"width": 832,
"height": 608,
"content": "## AI Agent"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "d978e1d6-316e-41a6-b579-25d8332e4053",
"connections": {
"Switch": {
"main": [
[
{
"node": "Get audio file",
"type": "main",
"index": 0
}
],
[
{
"node": "Analyze image",
"type": "main",
"index": 0
}
],
[
{
"node": "Process text input",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
},
"parameters": {
"main": [
[
{
"node": "Add sessionID to input",
"type": "main",
"index": 1
},
{
"node": "Get sessionID",
"type": "main",
"index": 0
}
]
]
},
"Analyze image": {
"main": [
[
{
"node": "Process extracted data",
"type": "main",
"index": 0
}
]
]
},
"Get sessionID": {
"main": [
[
{
"node": "If no sessionID or /new",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Upsert row(s)": {
"main": [
[
{
"node": "Add sessionID to input",
"type": "main",
"index": 0
}
]
]
},
"Get audio file": {
"main": [
[
{
"node": "Transcribe audio",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "parameters",
"type": "main",
"index": 0
},
{
"node": "Send \"typing...\"",
"type": "main",
"index": 0
}
]
]
},
"Transcribe audio": {
"main": [
[
{
"node": "Process audio transcript",
"type": "main",
"index": 0
}
]
]
},
"Create new contact": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Generate sessionID": {
"main": [
[
{
"node": "Upsert row(s)",
"type": "main",
"index": 0
}
]
]
},
"Process text input": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Search for contact": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Add sessionID to input": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Process extracted data": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"If no sessionID or /new": {
"main": [
[
{
"node": "Generate sessionID",
"type": "main",
"index": 0
}
],
[
{
"node": "Add sessionID to input",
"type": "main",
"index": 0
}
]
]
},
"Update existing contact": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Process audio transcript": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
googleApigooglePalmApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is an AI agent in the form of a Telegram bot. Its main purpose is to capture contact information and store it in a CRM. The agent supports multi-modal inputs and can extract contact details from text messages, voice recordings, and images (like photos of business…
Source: https://n8n.io/workflows/9700/ — 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
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
A comprehensive n8n workflow demonstrating advanced AI agent orchestration, stateful conversation management, and multi-modal input processing for nutrition tracking applications.
> AI-powered nutrition assistant for Telegram — log meals, set goals, and get personalized daily reports with Google Sheets integration.