AutomationFlowsAI & RAG › Score Sales Call Recordings with Google Drive, Google Gemini and Google Sheets

Score Sales Call Recordings with Google Drive, Google Gemini and Google Sheets

ByFahmi Fahreza @fahmiiireza on n8n.io

This workflow monitors a Google Drive folder for new audio recordings, analyzes each call with Google Gemini to extract sentiment and lead-qualification details, and appends the structured results to a Google Sheets log. Triggers every minute when a new file is created in a…

Event trigger★★★★☆ complexityAI-powered14 nodesGoogle Drive TriggerGoogle GeminiGoogle DriveGoogle Sheets
AI & RAG Trigger: Event Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #17888 — we link there as the canonical source.

This workflow follows the Google Drive → Google Drive Trigger 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 →

Download .json
{
  "id": "8Kz1ZPYp6wryQG3C",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "[INTERN - Aaron] Audio analysis & Potential customer Template (3)",
  "tags": [],
  "nodes": [
    {
      "id": "0d9787d8-e9ed-47d9-aefe-1722a338db0d",
      "name": "TriggerGDriveFolderChange",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -544,
        320
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1fhX3dpu9RNh0K5NkNJ_ysRBQhQJIGk8c",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1fhX3dpu9RNh0K5NkNJ_ysRBQhQJIGk8c",
          "cachedResultName": "[TMPLT-3] Call Recordings"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "79be87ad-f8db-4176-b81f-5b46656daeca",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -160,
        400
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "afddb095-8948-4084-84a4-a15274a4cd9c",
      "name": "Analyze audio",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        368,
        336
      ],
      "parameters": {
        "text": "=You are an expert Sales Quality Assurance and Lead Scoring AI Agent. Your task is to analyze a sales call audio recording between a Sales Representative and a Customer/Prospect, then extract key business metrics and context.\n\nAnalyze the provided audio and output ONLY a valid JSON object matching the schema below. Do not include any introductory or concluding text.\n\n### ANALYSIS RULES:\n1. \"sentiment\": Must be \"Positive\", \"Neutral\", or \"Negative\".\n2. \"sentiment_score\": A float value between -1.0 (extremely negative) and 1.0 (extremely positive).\n3. \"lead_qualification\": Categorize as:\n   - \"Hot Lead\": Showed high intent to buy, accepted an offer, or ready for next steps.\n   - \"Warm Lead\": Showed interest but has objections (price, timing, needs info) that need addressing.\n   - \"Cold Lead\": Expressed clear rejection, no budget, locked in competitor contracts, or requested no contact.\n4. \"objection_category\": Identify the main objection/pain point (e.g., \"Pricing/Budget\", \"Competitor Contract\", \"Security/Compliance\", \"Feature Comparison\", \"None\").\n5. \"summary\": A concise 1-2 sentence summary of the conversation context.\n6. \"recommended_action\": A clear, actionable next step for the sales team.\n7. \"follow_up_status\": Set as \"Assigned to Sales\", \"Nurturing\", \"Closed / Unqualified\", or \"Do Not Call\".\n\n### OUTPUT JSON FORMAT:\n{\n  \"prospect_name\": \"Extract if mentioned, else 'Unknown'\",\n  \"company_name\": \"Extract if mentioned, else 'Unknown'\",\n  \"summary\": \"String\",\n  \"sentiment\": \"Positive / Neutral / Negative\",\n  \"sentiment_score\": 0.00,\n  \"objection_category\": \"String\",\n  \"lead_qualification\": \"Hot Lead / Warm Lead / Cold Lead\",\n  \"recommended_action\": \"String\",\n  \"follow_up_status\": \"String\"\n}",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3.6-flash",
          "cachedResultName": "models/gemini-3.6-flash"
        },
        "options": {},
        "resource": "audio",
        "inputType": "binary",
        "operation": "analyze"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "dc5d61db-06f5-43db-a20d-278ad1adf5ad",
      "name": "SplitBatch",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        112,
        320
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "e6e5fd98-f797-40e0-a316-291dd9ee4212",
      "name": "Wait30Sec",
      "type": "n8n-nodes-base.wait",
      "position": [
        1040,
        336
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "7b928e65-53de-44b7-b49f-eca24603c953",
      "name": "IsAudioCheck",
      "type": "n8n-nodes-base.if",
      "position": [
        -320,
        320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "430c144e-4b52-42f4-9916-6aa4d143b951",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.mimeType }}",
              "rightValue": "audio"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "72b72d25-d40c-4fbb-bbd5-9b448b10c477",
      "name": "DownloadFileUploaded",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -160,
        208
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "8eec790e-8bce-43c3-9862-92ebfc5ba647",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -608,
        48
      ],
      "parameters": {
        "width": 224,
        "height": 480,
        "content": "# Google Drive Folder Trigger\nMonitors a specific Google Drive folder every minute for newly created files."
      },
      "typeVersion": 1
    },
    {
      "id": "1732fd4b-b9f0-4c88-982e-76b2dc8d63d8",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        48
      ],
      "parameters": {
        "width": 336,
        "height": 480,
        "content": "# Check File Type & Download\n1. Evaluates whether the uploaded file's mimeType contains \"audio\".\n2. Downloads the binary content of the verified audio file using the file ID from Google Drive."
      },
      "typeVersion": 1
    },
    {
      "id": "2ea01065-a3fe-4085-ba3b-0c70306cf607",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        48
      ],
      "parameters": {
        "width": 256,
        "height": 480,
        "content": "# Split File Downloaded into batch\nIterates through incoming files individually to prevent API rate limit issues during model execution."
      },
      "typeVersion": 1
    },
    {
      "id": "0b66c23c-fe3d-47ca-b7ac-f8de90b0e79d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        48
      ],
      "parameters": {
        "width": 864,
        "height": 480,
        "content": "# Analyze Audio, Save Info and Wait 30 Seconds\n1. Analyze Audio with Gemini: Uses models/gemini-3.6-flash to analyze the audio binary directly. Evaluates sentiment, sentiment score, lead qualification, objection category, conversation summary, and recommended sales action.\n2. Parse Analysis Output: Extracts and structures the raw JSON response received from the Gemini analysis into individual, clean data variables.\n3. Save to Spreadsheet: Map and append the extracted attributes (such as Lead Qualification, Sentiment Score, Objection Category, and Recommended Action) into the corresponding columns of the target Google Sheet.\n4. Rate Limit Delay: Introduces a 30-second delay between processing batches to adhere to model rate limits."
      },
      "typeVersion": 1
    },
    {
      "id": "bab5babb-4995-41be-9173-c99a576f0c98",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        -400
      ],
      "parameters": {
        "color": 5,
        "width": 544,
        "height": 1344,
        "content": "# Sales Audio Call Analysis & Lead Scoring Pipeline\n\nThis workflow automates the end-to-end processing of sales call recordings uploaded to Google Drive. It extracts key business metrics, such as caller sentiment, objections, lead qualifications, and recommended follow-up actions, using Google Gemini, and directly appends the structured outputs into a Google Sheet.\n\nTo ensure seamless integration with the workflow, please make a copy of the following Google Sheets template for your database setup:\n\n\ud83d\udd17 Spreadsheet Template: [Spreadsheet_Sentiment Template](https://docs.google.com/spreadsheets/d/1H-ZEYGJXuOMRIz4WgU6zlhiR_dC-ZxxgSxMW5JBjIuM/edit?usp=sharing)\n\n---\n\n## Who\u2019s it for?\nFor sales teams, account executives, quality assurance managers, and revenue operations specialists who want to automate lead qualification, sales call analysis, and CRM/spreadsheet logging directly from raw audio recordings.\n\n---\n\n## How it works\n1. **Trigger:** Listens for new call recording files uploaded to a designated Google Drive folder.\n2. **Validation & Download:** Checks if the uploaded file is an audio file. Non-audio files are ignored via a No-Op node, while valid audio files are downloaded into binary format.\n3. **Batching:** Splits incoming files into individual items (`SplitBatch`) to process audio sequentially and prevent rate-limiting issues.\n4. **Audio Analysis:** Google Gemini (`gemini-3.6-flash`) processes the audio binary directly to perform speech-to-intent analysis, evaluating sentiment, sentiment score, lead qualification status, objection categories, summary, and recommended actions.\n5. **JSON Parsing:** A Set node (`ParseJsonOutput`) extracts and structures the raw JSON response returned by Gemini into individual fields.\n6. **Data Entry & Integration:** The standard Google Sheets node (`SaveInfo`) maps and appends the extracted structured data into the destination spreadsheet (`Call Sheet`).\n7. **Rate Limit Delay:** A 30-second delay (`Wait30Sec`) is triggered after saving to respect API rate limits before loop-processing the next batch item.\n\n---\n\n## How to set up\n- **Google Drive Setup:** Connect your Google Drive OAuth2 credentials in `TriggerGDriveFolderChange` and select the target folder where call recordings are uploaded.\n- **Google Gemini Credentials:** Add your Google Gemini API credentials to the `Analyze audio` node.\n- **Google Sheets Setup:** Connect your Google Sheets OAuth2 credentials to the `SaveInfo` node, select your target document (`Spreadsheet_Sentiment`), and specify the target sheet tab (`Call Sheet` or `gid=0`).\n- **Activate Workflow:** Toggle the workflow to **Active** to process new audio recordings in real time."
      },
      "typeVersion": 1
    },
    {
      "id": "e35f9c88-f36b-4128-ba84-63634aeee22d",
      "name": "SaveInfo",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        816,
        336
      ],
      "parameters": {
        "columns": {
          "value": {
            "No": "-",
            "Call ID": "-",
            "Sentiment": "={{ $json.sentiment }}",
            "Timestamp": "={{ $now.format('yyyy-MM-dd, HH:mm') }}",
            "Company Name": "={{ $json.company_name }}",
            "Phone Number": "-",
            "Prospect Name": "={{ $json.prospect_name }}",
            "Follow-up Status": "={{ $json.follow_up_status }}",
            "Lead Qualification": "={{ $json.lead_qualification }}",
            "Objection Category": "={{ $json.objection_category }}",
            "Recommended Action": "={{ $json.recommended_action }}",
            "Conversation Summary": "={{ $json.summary }}",
            "Sentiment Score (-1 to 1)": "={{ $json.sentiment_score }}"
          },
          "schema": [
            {
              "id": "No",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "No",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Call ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Call ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prospect Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Prospect Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone Number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Conversation Summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Conversation Summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment Score (-1 to 1)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment Score (-1 to 1)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Objection Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Objection Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Qualification",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Lead Qualification",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recommended Action",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recommended Action",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Follow-up Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Follow-up Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": false
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H-ZEYGJXuOMRIz4WgU6zlhiR_dC-ZxxgSxMW5JBjIuM/edit#gid=0",
          "cachedResultName": "Call Sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1H-ZEYGJXuOMRIz4WgU6zlhiR_dC-ZxxgSxMW5JBjIuM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H-ZEYGJXuOMRIz4WgU6zlhiR_dC-ZxxgSxMW5JBjIuM/edit?usp=drivesdk",
          "cachedResultName": "Spreadsheet_Sentiment"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2478abab-fc4c-4056-a8b9-4b07b9fbc0a6",
      "name": "ParseJsonOutput",
      "type": "n8n-nodes-base.set",
      "position": [
        592,
        336
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ $json.content.parts[0].text }}"
      },
      "typeVersion": 3.5
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "2ec06e26-0217-4191-9d97-06bc0a27c06a",
  "nodeGroups": [],
  "connections": {
    "SaveInfo": {
      "main": [
        [
          {
            "node": "Wait30Sec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait30Sec": {
      "main": [
        [
          {
            "node": "SplitBatch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SplitBatch": {
      "main": [
        [],
        [
          {
            "node": "Analyze audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IsAudioCheck": {
      "main": [
        [
          {
            "node": "DownloadFileUploaded",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze audio": {
      "main": [
        [
          {
            "node": "ParseJsonOutput",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ParseJsonOutput": {
      "main": [
        [
          {
            "node": "SaveInfo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "DownloadFileUploaded": {
      "main": [
        [
          {
            "node": "SplitBatch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TriggerGDriveFolderChange": {
      "main": [
        [
          {
            "node": "IsAudioCheck",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow monitors a Google Drive folder for new audio recordings, analyzes each call with Google Gemini to extract sentiment and lead-qualification details, and appends the structured results to a Google Sheets log. Triggers every minute when a new file is created in a…

Source: https://n8n.io/workflows/17888/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Monitor a Google Drive folder, process each image based on the prompt defined in and save the new image to the specified output Google Drive folder. Maintain a processing log in Google Sheets.

Google Drive Trigger, Google Drive, HTTP Request +2
AI & RAG

This workflow is designed for teams and businesses that receive invoices in Google Drive and want to automatically extract structured financial data without manual processing. It is ideal for finance

Telegram Trigger, Google Drive Trigger, Google Drive +3
AI & RAG

The Problem That it Solves

Google Drive Trigger, OpenAI, Google Drive +5
AI & RAG

Content creators, YouTubers, and social media managers who want to repurpose long form videos into short clips without doing it manually. Works on self hosted n8n instances.

Google Drive Trigger, Google Drive, N8N Nodes Renderio +3
AI & RAG

Understand your customers before you build for them. This workflow, Market Segmentation: Buyer Persona Pain Point Report, automates the grueling process of primary market research. By scraping real-wo

Form Trigger, Google Gemini, N8N Nodes Olostep +3