This workflow corresponds to n8n.io template #8151 — we link there as the canonical source.
This workflow follows the Agent → Google Drive 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "9a21ebb6-763a-4d2c-b91f-f135e24cc3c3",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-720,
-80
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.2
},
{
"id": "73d1c0b8-49e1-4ce8-af80-106ac1702acc",
"name": "Search For New Call Recordings",
"type": "n8n-nodes-base.googleDrive",
"position": [
-416,
-80
],
"parameters": {
"filter": {
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1Kz8dGr8Hful3CeUJWjsbxktAEih3-Xjt",
"cachedResultUrl": "https://drive.google.com/drive/folders/1Kz8dGr8Hful3CeUJWjsbxktAEih3-Xjt",
"cachedResultName": "Company - Support Call Recordings"
},
"whatToSearch": "files"
},
"options": {},
"resource": "fileFolder",
"queryString": "mimeType = 'audio/wav'",
"searchMethod": "query"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "b0f31a61-f491-4d8c-8bb4-b8aa542fd4c8",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
736,
144
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9a1137fe-2fa0-4844-9c8d-b56e92e27f17",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
928,
144
],
"parameters": {
"jsonSchemaExample": "{\n \"speaker_identification\": {\n \"agent\": \"speaker_id\",\n \"agent_name\": \"The agent's name if mentioned, otherwise 'Not mentioned'\",\n \"client\": \"speaker_id\",\n \"client_name\": \"The client's name if mentioned, otherwise 'Not mentioned'\"\n },\n \"summary\": \"A concise, one-paragraph summary of the entire conversation.\",\n \"client_sentiment\": \"Classify the client's overall sentiment as 'Positive', 'Negative', or 'Neutral'.\",\n \"call_topic\": \"A brief phrase describing the main reason for the call.\",\n \"department_tag\": \"The single most relevant department tag from the provided list.\",\n \"action_items\": [\n \"A list of clear, actionable tasks for the company or agent.\",\n \"A second action item if identified.\"\n ]\n}"
},
"typeVersion": 1.3
},
{
"id": "827a11ee-3f33-49e8-90ac-8a87a0e83bb5",
"name": "Send Alert To Managers",
"type": "n8n-nodes-base.telegram",
"position": [
1856,
-544
],
"parameters": {
"text": "=*\ud83d\ude20 Negative Call Alert*\n\nA call with negative sentiment has been flagged.\n\n*Agent:* `{{ $('Call Analyze').item.json.output.speaker_identification.agent_name }}`\n*Client:* `{{ $('Call Analyze').item.json.output.speaker_identification.client_name }}`\n*Topic:* `{{ $('Call Analyze').item.json.output.call_topic }}`\n\n*Summary:*\n> {{ $('Call Analyze').item.json.output.summary }}\n\n*Action Items:*\n{{ $json.Actions }}",
"chatId": "123456789",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "633c28f1-066c-4804-82aa-08f8a93100f2",
"name": "Send Kudos to Team",
"type": "n8n-nodes-base.telegram",
"position": [
1856,
-256
],
"parameters": {
"text": "=*\ud83d\ude0a Great Job!*\n\nKudos to *{{ $json.Agnent }}* for handling a positive call regarding *{{ $json.Topic }}*! Keep up the great work. \u2728",
"chatId": "123456789",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "d5e2a2a1-0c64-4b8d-81f2-64af3648032d",
"name": "Client Sentiment",
"type": "n8n-nodes-base.switch",
"position": [
1552,
-400
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Negative",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "790e5d44-51a2-4132-b2d4-4dcd393e77fa",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Call Analyze').item.json.output.client_sentiment }}",
"rightValue": "Negative"
}
]
},
"renameOutput": true
},
{
"outputKey": "Positive",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9b0236dc-4452-428a-add5-9764fc166d50",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Call Analyze').item.json.output.client_sentiment }}",
"rightValue": "Positive"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "e962bcca-4d42-4c1a-ab50-6d9e944df94f",
"name": "Call Analyze",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
768,
-80
],
"parameters": {
"text": "=Analyze the following support call transcript according to the system instructions.\n\n---\n{{ $json.formattedTranscript }}\n---",
"options": {
"systemMessage": "=You are an expert AI assistant specializing in call center quality assurance and conversation analysis. Your task is to analyze a support call transcript, identify roles and names, and extract key information for routing and analytics.\n\nLook for names mentioned in the conversation (e.g., \"my name is Alex\", \"Hi, this is Sarah\"). Based on the call's topic, assign a single, most relevant department tag from the following list: [Billing, Technical Support, Sales, Customer Service, HR, Marketing].\n\nYou MUST provide your response exclusively in a valid JSON format. Do not add any explanatory text, greetings, or markdown formatting before or after the JSON object.\n\nThe JSON object must conform to the following structure:\n{\n \"speaker_identification\": {\n \"agent\": \"speaker_id\",\n \"agent_name\": \"The agent's name if mentioned, otherwise 'Not mentioned'\",\n \"client\": \"speaker_id\",\n \"client_name\": \"The client's name if mentioned, otherwise 'Not mentioned'\"\n },\n \"summary\": \"A concise, one-paragraph summary of the entire conversation.\",\n \"client_sentiment\": \"Classify the client's overall sentiment as 'Positive', 'Negative', or 'Neutral'.\",\n \"call_topic\": \"A brief phrase describing the main reason for the call.\",\n \"department_tag\": \"The single most relevant department tag from the provided list.\",\n \"action_items\": [\n \"A list of clear, actionable tasks for the company or agent.\",\n \"A second action item if identified.\"\n ]\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "40fa2621-945b-474a-bd51-8a31a43d8442",
"name": "Log Recording Analysis",
"type": "n8n-nodes-base.googleSheets",
"position": [
1168,
-80
],
"parameters": {
"columns": {
"value": {
"Topic": "={{ $json.output.call_topic }}",
"Agnent": "={{ $json.output.speaker_identification.agent_name }}",
"Client": "={{ $json.output.speaker_identification.client_name }}",
"Actions": "={{ '\u2022 '+$json.output.action_items.join('\\n\u2022 ')}}",
"Summary": "={{ $json.output.summary }}",
"Fulltext": "={{ $('Convert to Conversational Transcribe').item.json.formattedTranscript.replaceAll($json.output.speaker_identification.agent,$json.output.speaker_identification.agent_name.toLowerCase()=='not mentioned' ? 'Agent' : $json.output.speaker_identification.agent_name).replaceAll($json.output.speaker_identification.client,$json.output.speaker_identification.client_name.toLowerCase()=='not mentioned' ? 'Client' : $json.output.speaker_identification.client_name) }}",
"Sentiment": "={{ $json.output.client_sentiment }}",
"Department": "={{ $json.output.department_tag }}",
"Recording Filename": "={{ $('Download Audio Files').item.json.name }}"
},
"schema": [
{
"id": "Recording Filename",
"type": "string",
"display": true,
"required": false,
"displayName": "Recording Filename",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sentiment",
"type": "string",
"display": true,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Department",
"type": "string",
"display": true,
"required": false,
"displayName": "Department",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Topic",
"type": "string",
"display": true,
"required": false,
"displayName": "Topic",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Agnent",
"type": "string",
"display": true,
"required": false,
"displayName": "Agnent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client",
"type": "string",
"display": true,
"required": false,
"displayName": "Client",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Summary",
"type": "string",
"display": true,
"required": false,
"displayName": "Summary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Actions",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Actions",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Fulltext",
"type": "string",
"display": true,
"required": false,
"displayName": "Fulltext",
"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/182ds-RDJ2RcNo1xmx0EucXkmBAlBJe-muhnN78My3wc/edit#gid=0",
"cachedResultName": "Logs"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "182ds-RDJ2RcNo1xmx0EucXkmBAlBJe-muhnN78My3wc",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/182ds-RDJ2RcNo1xmx0EucXkmBAlBJe-muhnN78My3wc/edit?usp=drivesdk",
"cachedResultName": "Call Recording Process Results"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "d4263888-9284-4be1-8f44-3bd1ec785c54",
"name": "Download Audio Files",
"type": "n8n-nodes-base.googleDrive",
"position": [
-208,
-80
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "fe3de287-6e9f-4f2a-a132-ec3c03555250",
"name": "Convert to Conversational Transcribe",
"type": "n8n-nodes-base.code",
"position": [
400,
-80
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Get the array of words from the input JSON provided by ElevenLabs\n// It assumes the input data is in the format $json.words or $items[0].json.words\nconst words = $json.words;\n\n// If there are no words, return an empty transcript\nif (!words || words.length === 0) {\n return { json: { transcript: \"\" } };\n}\n\nlet transcript = \"\";\nlet currentSpeaker = null;\nlet currentLine = \"\";\n\n// Loop through each word object provided by the API\nfor (const word of words) {\n const speakerId = word.speaker_id;\n \n // Check if this is the very first word\n if (currentSpeaker === null) {\n currentSpeaker = speakerId;\n // Format the speaker ID for better readability (e.g., 'speaker_0' becomes 'Speaker 0')\n const formattedSpeaker = `Speaker ${speakerId.split('_')[1]}`;\n currentLine = `${formattedSpeaker}: ${word.text}`;\n continue;\n }\n\n // If the speaker changes, add the completed line to the transcript and start a new one\n if (speakerId !== currentSpeaker) {\n transcript += currentLine.trim() + \"\\n\"; // Add the previous line and a newline\n currentSpeaker = speakerId;\n const formattedSpeaker = `Speaker ${speakerId.split('_')[1]}`;\n currentLine = `${formattedSpeaker}: ${word.text}`;\n } else {\n // If the same speaker continues, just add their word to the current line\n // The API includes spacing objects, so we just append the text\n currentLine += word.text;\n }\n}\n\n// Add the very last line to the transcript\ntranscript += currentLine.trim();\n\n// Return the final formatted transcript in a new n8n item\nreturn {\n json: {\n formattedTranscript: transcript\n }\n};"
},
"typeVersion": 2
},
{
"id": "c604ea35-a82d-45a9-87f1-22a24f120ab0",
"name": "Move Audio To Processed Folder",
"type": "n8n-nodes-base.googleDrive",
"position": [
1552,
192
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Download Audio Files').item.json.id }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1MDRPnlY6WYFwpR7WgNg2yhriq75gH8Bc",
"cachedResultUrl": "https://drive.google.com/drive/folders/1MDRPnlY6WYFwpR7WgNg2yhriq75gH8Bc",
"cachedResultName": "Processed Audio"
},
"operation": "move"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "38a5598e-18c5-4745-a5e5-80137527aa0a",
"name": "Convert Speech To Text",
"type": "n8n-nodes-base.httpRequest",
"position": [
192,
-80
],
"parameters": {
"url": "https://api.elevenlabs.io/v1/speech-to-text",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "diarize",
"value": "true"
},
{
"name": "model_id",
"value": "scribe_v1"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "multipart/form-data"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "d789c6cc-a8e0-4725-b222-bdb855dba2a9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
-240
],
"parameters": {
"width": 512,
"height": 352,
"content": "## Speech To Text \nConvert the call recording into a conversational multi-speaker transcript."
},
"typeVersion": 1
},
{
"id": "3c662a89-8cb6-4cb1-b52a-3524ac044591",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
-240
],
"parameters": {
"color": 3,
"width": 512,
"height": 352,
"content": "## New Call Recordings\nCheck the designated Google Drive folder for new call recordings and prepare them in binary format."
},
"typeVersion": 1
},
{
"id": "1f90983e-ae47-44ea-97a6-642671b642c8",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1440,
-704
],
"parameters": {
"color": 4,
"width": 640,
"height": 640,
"content": "## Take Action\n\nEvaluate the client\u2019s sentiment. If it\u2019s positive, send a kudos message to the support team\u2019s Telegram channel. If it\u2019s negative, notify the managers\u2019 Telegram group to take the necessary actions."
},
"typeVersion": 1
}
],
"connections": {
"Call Analyze": {
"main": [
[
{
"node": "Log Recording Analysis",
"type": "main",
"index": 0
}
]
]
},
"Client Sentiment": {
"main": [
[
{
"node": "Send Alert To Managers",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Kudos to Team",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Search For New Call Recordings",
"type": "main",
"index": 0
}
]
]
},
"Download Audio Files": {
"main": [
[
{
"node": "Convert Speech To Text",
"type": "main",
"index": 0
}
]
]
},
"Convert Speech To Text": {
"main": [
[
{
"node": "Convert to Conversational Transcribe",
"type": "main",
"index": 0
}
]
]
},
"Log Recording Analysis": {
"main": [
[
{
"node": "Move Audio To Processed Folder",
"type": "main",
"index": 0
},
{
"node": "Client Sentiment",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Call Analyze",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Call Analyze",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Move Audio To Processed Folder": {
"main": [
[]
]
},
"Search For New Call Recordings": {
"main": [
[
{
"node": "Download Audio Files",
"type": "main",
"index": 0
}
]
]
},
"Convert to Conversational Transcribe": {
"main": [
[
{
"node": "Call Analyze",
"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.
googleDriveOAuth2ApigooglePalmApigoogleSheetsOAuth2ApihttpHeaderAuthtelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Customer support calls contain a wealth of valuable feedback and urgent issues, but manually reviewing audio files is inefficient. This workflow acts as an AI assistant for your call log, transforming unstructured audio recordings into structured, actionable data. It provides a…
Source: https://n8n.io/workflows/8151/ — 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 n8n workflow is designed for content creators, digital marketers, and social media managers who want to automate their entire content creation and publishing process across multiple platforms. It
Turn a single topic into a published Instagram Carousel in minutes.
Sign up for Decodo — get better pricing here
Veo3_POV_Vlogs. Uses googleSheets, toolThink, agent, outputParserStructured. Scheduled trigger; 18 nodes.
Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.