AutomationFlowsData & Sheets › Clone Brand Voices and Generate Voiceovers with Smallest AI and Google Drive

Clone Brand Voices and Generate Voiceovers with Smallest AI and Google Drive

ByZain Khan @zain on n8n.io

This workflow receives a webhook request with an audio sample URL, voice name, and script, clones a voice and generates a matching voiceover using Smallest AI, uploads the MP3 to Google Drive, logs the voice ID in Google Sheets, and returns a public link in the webhook response.…

Webhook trigger★★★★☆ complexity15 nodesHTTP RequestN8N Nodes SmallestaiGoogle DriveGoogle Sheets
Data & Sheets Trigger: Webhook Nodes: 15 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #17152 — 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": "ed29ce66-4591-42dd-bf0e-f53a765d65a1",
      "name": "Webhook - Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        2208,
        784
      ],
      "parameters": {
        "path": "voice-clone",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 1
    },
    {
      "id": "b8e9120a-782b-4700-833f-74347ecde3a0",
      "name": "Set - Clean Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2416,
        784
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "955c3dfb-bd9f-4b8a-aebd-d51b6c6522b9",
      "name": "HTTP Request - Download Voice Sample",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2624,
        784
      ],
      "parameters": {
        "url": "={{ $json.body.audio_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b0b7d69e-5824-43e8-96ee-643b94d5f585",
      "name": "Code - Extract Voice ID",
      "type": "n8n-nodes-base.code",
      "position": [
        3168,
        784
      ],
      "parameters": {
        "jsCode": "const response = $input.first().json;\n\nconst voiceId = response.data?.voiceId || null;\n\nif (!voiceId) {\n  throw new Error('Voice clone failed \u2014 no voiceId returned: ' + JSON.stringify(response));\n}\n\nreturn [{\n  json: {\n    voice_id: voiceId,\n    voice_name: $('Set - Clean Fields').first().json.voice_name,\n    script_text: $('Set - Clean Fields').first().json.script_text,\n    cloned_at: $now.toISO()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "591e033d-2ccf-461d-bde3-1f24bffd3083",
      "name": "Code - Truncate Script",
      "type": "n8n-nodes-base.code",
      "position": [
        3392,
        784
      ],
      "parameters": {
        "jsCode": "const text = $input.first().json.script_text || '';\nconst MAX_CHARS = 3500;\nconst truncated = text.length > MAX_CHARS\n  ? text.substring(0, MAX_CHARS).replace(/\\s+\\S*$/, '') + '...'\n  : text;\nreturn [{\n  json: {\n    ...($input.first().json),\n    tts_text: truncated\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6bf23a11-e9f8-4edc-8d18-ae16142f7551",
      "name": "Smallest AI - Synthesize with Cloned Voice",
      "type": "n8n-nodes-smallestai.smallestai",
      "position": [
        3680,
        784
      ],
      "parameters": {
        "text": "={{ $('Set - Clean Fields').item.json.body.script }}",
        "voiceId": "={{ $json.voice_id }}",
        "additionalOptions": {
          "language": "en"
        }
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "1da66554-3229-4a9f-afed-ecb54f9c5413",
      "name": "Google Drive - Upload Voiceover",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3904,
        784
      ],
      "parameters": {
        "name": "={{ $('Set - Clean Fields').item.json.body.voice_name }}_voiceover_{{ $now.toFormat('yyyy-MM-dd') }}.mp3",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "a252b12e-0db4-423f-a224-196b82c2c5c3",
      "name": "Google Drive - Make Public",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        4112,
        784
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        }
      },
      "typeVersion": 3
    },
    {
      "id": "223170ae-6006-44f9-ac63-e8c993a98b36",
      "name": "Google Sheets - Log Voice Library",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4320,
        784
      ],
      "parameters": {
        "columns": {
          "value": {
            "voice id": "={{ $('Get cloned voice id').item.json.data.voiceId }}",
            "voice name ": "={{ $('Set - Clean Fields').item.json.body.voice_name }}"
          },
          "schema": [
            {
              "id": "voice id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "voice id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "voice name ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "voice name ",
              "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/1WEYzD9hoJ8Kqp5TkMvTAsLeKeiLjp68pDLv8yzil4wQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1WEYzD9hoJ8Kqp5TkMvTAsLeKeiLjp68pDLv8yzil4wQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1WEYzD9hoJ8Kqp5TkMvTAsLeKeiLjp68pDLv8yzil4wQ/edit?usp=drivesdk",
          "cachedResultName": "voice clonned ids"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "02ef225b-be25-4485-b589-267dcc3ffaa9",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        4528,
        784
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={\n  \"success\": true,\n  \"voice_id\": \"{{ $('Code - Extract Voice ID').first().json.voice_id }}\",\n  \"voice_name\": \"{{ $('Set - Clean Fields').item.json.body.voice_name }}\",\n  \"audio_link\": \"{{ $('Google Drive - Upload Voiceover').item.json.webViewLink }}\",\n  \"cloned_at\": \"{{ $('Code - Extract Voice ID').first().json.cloned_at }}\"\n}"
      },
      "typeVersion": 1
    },
    {
      "id": "27162556-a99e-4536-a72e-6351687d9507",
      "name": "Get cloned voice id",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2944,
        784
      ],
      "parameters": {
        "url": "https://api.smallest.ai/waves/v1/voice-cloning",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "displayName",
              "value": "={{ $json.body.voice_name }}"
            },
            {
              "name": "language",
              "value": "en"
            },
            {
              "name": "accent",
              "value": "general"
            },
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "77fa3ca0-ad7e-483a-b7fd-9c38ce72244c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1296,
        512
      ],
      "parameters": {
        "width": 816,
        "height": 624,
        "content": "## Brand Voice Clone to Reusable Voiceovers\n\n### How it works\nThis workflow builds an automated, on-demand custom voice generation engine. When an external application triggers the workflow via a webhook with an audio sample URL and script text, the system downloads the raw sample file and securely registers a brand-new cloned voice layout inside. It extracts the unique voice ID, instantly runs a dynamic text-to-speech script compilation matching that exact cloned voice model, and saves the output into Google Drive. The public link is then cataloged inside a master Google Sheets database for instant recall across marketing or support platforms.\n\n### Setup steps\n* Deploy the workflow to generate your live webhook\n* Connect your  credentials to handle both voice registration and speech synthesis.\n* Link your target **Google Drive** and **Google Sheets** accounts to host and log your reusable assets.\n* Ensure incoming payloads provide an  file path and a text string parameter.\n\n### Customization\nYou can modify the spreadsheet logging structure to add metadata properties like project names or intent tags. You can also adapt the conditional flow steps to check if a voice ID already exists for a client name before registering a completely new clone profile."
      },
      "typeVersion": 1
    },
    {
      "id": "df4dbb22-3815-4a1a-be42-6741f9b09288",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        624
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 400,
        "content": "## Webhook Ingestion & Sample Download\n"
      },
      "typeVersion": 1
    },
    {
      "id": "744ca954-439f-4375-ab1a-f823851b8277",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2848,
        624
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 400,
        "content": "## Voice Cloning & Extraction\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a1a11ee5-b046-4270-9116-bdcfab34946f",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3584,
        624
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 400,
        "content": "## Synthesis, Cloud Storage & Database Log\n\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Webhook - Trigger": {
      "main": [
        [
          {
            "node": "Set - Clean Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set - Clean Fields": {
      "main": [
        [
          {
            "node": "HTTP Request - Download Voice Sample",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get cloned voice id": {
      "main": [
        [
          {
            "node": "Code - Extract Voice ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Truncate Script": {
      "main": [
        [
          {
            "node": "Smallest AI - Synthesize with Cloned Voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Extract Voice ID": {
      "main": [
        [
          {
            "node": "Code - Truncate Script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive - Make Public": {
      "main": [
        [
          {
            "node": "Google Sheets - Log Voice Library",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive - Upload Voiceover": {
      "main": [
        [
          {
            "node": "Google Drive - Make Public",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Log Voice Library": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Download Voice Sample": {
      "main": [
        [
          {
            "node": "Get cloned voice id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Smallest AI - Synthesize with Cloned Voice": {
      "main": [
        [
          {
            "node": "Google Drive - Upload Voiceover",
            "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

This workflow receives a webhook request with an audio sample URL, voice name, and script, clones a voice and generates a matching voiceover using Smallest AI, uploads the MP3 to Google Drive, logs the voice ID in Google Sheets, and returns a public link in the webhook response.…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses googleDrive, httpRequest, notion, formTrigger. Webhook trigger; 67 nodes.

Google Drive, HTTP Request, Notion +3
Data & Sheets

Transform your n8n instance management with this advanced automation system featuring artificial intelligence-driven workflow selection. This template provides comprehensive maintenance operations wit

n8n, HTTP Request, Google Sheets +1
Data & Sheets

Convalidaciones Académicas - Estructura Base. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 35 nodes.

Google Sheets, Email Send, Google Drive +2
Data & Sheets

TrackCollect. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, moveBinaryData. Webhook trigger; 31 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +2
Data & Sheets

FlowV4. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 31 nodes.

Google Sheets, Email Send, Google Drive +2