AutomationFlowsAI & RAG › Analyze Zoom Phone Call Recordings with Gemini and Log Results to Google Sheets

Analyze Zoom Phone Call Recordings with Gemini and Log Results to Google Sheets

ByOka Hironobu @okp29 on n8n.io

Sales managers and team leads who use Zoom Phone for outbound calls and want automated performance tracking without manually reviewing every recording. A schedule trigger runs periodically and fetches recent phone recordings from the Zoom Phone API Each recording is split out…

Cron / scheduled trigger★★★★☆ complexity17 nodesHTTP RequestGoogle DriveGoogle Sheets
AI & RAG Trigger: Cron / scheduled Nodes: 17 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Drive → Google Sheets 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "c1ac5764-5a77-4105-bc2c-224badb11721",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -240
      ],
      "parameters": {
        "width": 580,
        "height": 660,
        "content": "### Analyze Zoom phone recordings with Gemini AI\nThis workflow grabs your Zoom Phone call recordings, sends them to Gemini for analysis, backs them up to Google Drive, and logs everything in a spreadsheet.\n\n### How it works\n1. **Schedule Trigger** kicks off every few hours and pulls recent recordings from Zoom Phone API\n2. Each recording is downloaded, then sent to both **Google Drive** (for backup) and **Gemini AI** (for analysis)\n3. Gemini evaluates the call \u2014 how far the conversation got, and what could be improved\n4. Results are merged with the Drive link and appended to a **Google Sheets** log\n\n### Setup steps\n1. Create a Zoom Server-to-Server OAuth app with `phone:read` and `recording:read` scopes\n2. Add your Google Gemini API key in n8n credentials\n3. Connect Google Drive and Google Sheets OAuth2\n4. Set the **Google Drive folder ID** in the \"Upload to Google Drive\" node\n5. Set the **Google Sheets document ID** in the \"Log to Google Sheets\" node \u2014 make sure the sheet has columns: Caller, Date, Number, Direction, Stage, Advice, Drive URL\n\n### Customization\n- Change the schedule interval in the trigger node\n- Edit the Gemini prompt to match your call scoring criteria\n- Add more columns to the spreadsheet for extra tracking"
      },
      "typeVersion": 1
    },
    {
      "id": "12116eca-f4b4-4c4e-bc0e-8469676ff2b0",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 650,
        "content": "## Fetch Zoom recordings\nPulls recent phone recordings from the Zoom API and splits them into individual items for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "0ec1e3ce-7526-499d-b07f-4dcc7675fb45",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 786,
        "height": 650,
        "content": "## Prepare & download\nBuilds a clean filename from the caller name + timestamp, then downloads the actual audio file."
      },
      "typeVersion": 1
    },
    {
      "id": "fbd4def3-d02a-48fc-bffb-eda5c1f9fad6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 582,
        "height": 650,
        "content": "## Analyze with Gemini AI\nThe audio goes to both Google Drive (backup) and Gemini (analysis) in parallel. Gemini returns a structured JSON with the call stage and improvement advice."
      },
      "typeVersion": 1
    },
    {
      "id": "fd90ece7-4eb1-4122-b062-590d93c76a77",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2256,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 650,
        "content": "## Log results\nCombines the Gemini analysis with caller metadata and the Drive link, then appends a row to your tracking spreadsheet."
      },
      "typeVersion": 1
    },
    {
      "id": "e064d2f3-25c8-4985-bf3d-8b3316f78440",
      "name": "Get Zoom Phone Recordings",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        672,
        -128
      ],
      "parameters": {
        "url": "https://api.zoom.us/v2/phone/recordings",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "page_size",
              "value": "20"
            }
          ]
        },
        "nodeCredentialType": "zoomOAuth2Api"
      },
      "typeVersion": 4.2
    },
    {
      "id": "570be236-0816-4287-81b4-5ad3cb1c6709",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1104,
        -128
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "b854e9de-3ca5-457a-a279-2205f3ad23cf",
      "name": "Build File Name",
      "type": "n8n-nodes-base.set",
      "position": [
        1328,
        -48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a6650e12-8a03-4efe-9fbb-aec55950b140",
              "name": "FileName",
              "type": "string",
              "value": "={{ $json.caller_name }}_{{ $json.date_time.replace(/[-T:Z]/g, '') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "941bbcab-c18b-4856-aa4f-4ad5f961ef37",
      "name": "Download Recording",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1520,
        -48
      ],
      "parameters": {
        "url": "={{ $('Loop Over Items').item.json.download_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zoomOAuth2Api"
      },
      "typeVersion": 4.2
    },
    {
      "id": "bb98c913-9b85-4b88-b47f-482c9e6e0e34",
      "name": "Upload to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1712,
        -48
      ],
      "parameters": {
        "name": "={{ $('Build File Name').item.json.FileName }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "typeVersion": 3
    },
    {
      "id": "bab6320f-cb6a-426d-9b3e-3e906cdbd79f",
      "name": "Upload Audio to Gemini",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1728,
        208
      ],
      "parameters": {
        "url": "https://generativelanguage.googleapis.com/upload/v1beta/files",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "binaryData",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Goog-Upload-Command",
              "value": "upload, finalize"
            },
            {
              "name": "X-Goog-Upload-Protocol",
              "value": "raw"
            }
          ]
        },
        "inputDataFieldName": "data",
        "nodeCredentialType": "googlePalmApi"
      },
      "typeVersion": 4.4
    },
    {
      "id": "eb7f11da-47a1-491c-bf05-63a44f9936cb",
      "name": "Analyze Call with Gemini",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1920,
        208
      ],
      "parameters": {
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"fileData\": {\n            \"mimeType\": \"{{ $json.file.mimeType }}\",\n            \"fileUri\": \"{{ $json.file.uri }}\"\n          }\n        },\n        {\n          \"text\": \"Analyze this phone call recording and evaluate it as a sales/telemarketing call.\\n\\nDetermine:\\n- How far the call got (one of: Contact reached / Needs identified / Meeting proposed / Appointment booked)\\n- Specific, actionable advice for the caller\\n\\nReturn ONLY valid JSON, no other text.\"\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"responseMimeType\": \"application/json\",\n    \"responseSchema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"step\": {\n          \"type\": \"string\",\n          \"description\": \"Stage reached in the call (Contact reached / Needs identified / Meeting proposed / Appointment booked)\"\n        },\n        \"advice\": {\n          \"type\": \"string\",\n          \"description\": \"Specific advice for improving the call\"\n        }\n      },\n      \"required\": [\"step\", \"advice\"]\n    }\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googlePalmApi"
      },
      "typeVersion": 4.4
    },
    {
      "id": "79fa4644-956c-4207-8bb0-bc65b36c0dc4",
      "name": "Merge Drive Link + Analysis",
      "type": "n8n-nodes-base.merge",
      "position": [
        2096,
        192
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "4cc6f30f-4b58-4322-98ae-f78c50c1f166",
      "name": "Format Results",
      "type": "n8n-nodes-base.set",
      "position": [
        2288,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b1234567-+12345678900000001",
              "name": "Caller",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.caller_name }}"
            },
            {
              "id": "b1234567-+12345678900000002",
              "name": "Date",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.date_time }}"
            },
            {
              "id": "b1234567-+12345678900000003",
              "name": "Number",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.callee_number }}"
            },
            {
              "id": "b1234567-+12345678900000004",
              "name": "Direction",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.direction }}"
            },
            {
              "id": "b1234567-+12345678900000005",
              "name": "Stage",
              "type": "string",
              "value": "={{ JSON.parse($json.candidates[0].content.parts[0].text).step }}"
            },
            {
              "id": "b1234567-+12345678900000006",
              "name": "Advice",
              "type": "string",
              "value": "={{ JSON.parse($json.candidates[0].content.parts[0].text).advice }}"
            },
            {
              "id": "b1234567-+12345678900000007",
              "name": "DriveURL",
              "type": "string",
              "value": "={{ $json.webViewLink }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0f60ec22-da9c-438b-a23f-4c26826e58a5",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2464,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.Date }}",
            "Stage": "={{ $json.Stage }}",
            "Advice": "={{ $json.Advice }}",
            "Caller": "={{ $json.Caller }}",
            "Number": "={{ $json.Number }}",
            "DriveURL": "={{ $json.DriveURL }}",
            "Direction": "={{ $json.Direction }}"
          },
          "schema": [
            {
              "id": "Caller",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Caller",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Direction",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Direction",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Stage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Advice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Advice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DriveURL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DriveURL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "e68e2ece-e4d2-418b-9b69-446fd4f3ce96",
      "name": "Run Every Hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        448,
        -128
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "a5a8a6d8-a337-4c7b-bb9c-2a613fe5d3a6",
      "name": "Process Each Recording",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        880,
        -128
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "recordings"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Format Results": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Every Hour": {
      "main": [
        [
          {
            "node": "Get Zoom Phone Recordings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build File Name": {
      "main": [
        [
          {
            "node": "Download Recording",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Build File Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Recording": {
      "main": [
        [
          {
            "node": "Upload to Google Drive",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload Audio to Gemini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Each Recording": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Audio to Gemini": {
      "main": [
        [
          {
            "node": "Analyze Call with Gemini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive": {
      "main": [
        [
          {
            "node": "Merge Drive Link + Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Call with Gemini": {
      "main": [
        [
          {
            "node": "Merge Drive Link + Analysis",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get Zoom Phone Recordings": {
      "main": [
        [
          {
            "node": "Process Each Recording",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Drive Link + Analysis": {
      "main": [
        [
          {
            "node": "Format Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

Sales managers and team leads who use Zoom Phone for outbound calls and want automated performance tracking without manually reviewing every recording. A schedule trigger runs periodically and fetches recent phone recordings from the Zoom Phone API Each recording is split out…

Source: https://n8n.io/workflows/13871/ — 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

Founder's Discovery Engine. Uses googleSheets, googleDrive, httpRequest, gmail. Scheduled trigger; 18 nodes.

Google Sheets, Google Drive, HTTP Request +1
AI & RAG

Who's this for Finance teams, AI developers, product managers, and business owners who need to monitor and control OpenAI API costs across different models and projects. If you're using GPT-4, GPT-3.5

HTTP Request, Google Sheets, Google Drive +1
AI & RAG

This comprehensive n8n automation template orchestrates a complete end-to-end workflow for generating engaging short-form Point-of-View (POV) style videos using multiple AI services and automatically

HTTP Request, OpenAI, Google Drive +4
AI & RAG

This workflow automates the generation of ad-ready product images by combining product and influencer photos with AI styling. It runs on a scheduled trigger, fetches data from Google Sheets, and retri

Google Drive, OpenAI, Google Sheets +1
AI & RAG

This n8n workflow automatically generates presentation-style "screen recording" videos with AI-generated slides and a talking head avatar overlay. You provide a topic and intention, and the workflow h

HTTP Request, N8N Nodes Veed, Google Drive +1