{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Transcribe new audio files from Google Drive using Gladia and Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "3f6d2b7d-c7e9-4543-9b9a-cfa7b2d2baa7",
      "name": "Google Drive Audio Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -16,
        704
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_SOURCE_FOLDER_ID"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "72166108-75e5-4b98-90af-026316c77a2a",
      "name": "Prepare Config Values",
      "type": "n8n-nodes-base.set",
      "position": [
        208,
        704
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "wait_seconds",
              "type": "number",
              "value": 15
            },
            {
              "id": "c2",
              "name": "max_attempts",
              "type": "number",
              "value": 40
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "25b2175b-fcfb-4918-ab1c-05642a0be3cd",
      "name": "Download File from Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        432,
        704
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Google Drive Audio Trigger').item.json.id }}"
        },
        "options": {
          "binaryPropertyName": "data"
        },
        "resource": "file",
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "ba1499c8-97bf-4054-af90-ca9785aa2aeb",
      "name": "Upload Audio to Gladia",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        688,
        704
      ],
      "parameters": {
        "url": "https://api.gladia.io/v2/upload",
        "method": "POST",
        "options": {
          "timeout": 120000
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "audio",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 5000
    },
    {
      "id": "285cbe8b-c58e-4fa2-a8d2-292152acaaba",
      "name": "Start Transcription Job",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        928,
        688
      ],
      "parameters": {
        "url": "https://api.gladia.io/v2/pre-recorded",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={{ { \"audio_url\": $json.audio_url } }}",
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 5000
    },
    {
      "id": "9d170652-3c50-4cbe-97f0-df9e34835907",
      "name": "Wait for Processing",
      "type": "n8n-nodes-base.wait",
      "position": [
        1200,
        544
      ],
      "parameters": {
        "unit": "seconds",
        "amount": "={{ $('Prepare Config Values').item.json.wait_seconds }}",
        "resume": "timeInterval"
      },
      "typeVersion": 1.1
    },
    {
      "id": "7279d3f5-ad94-4fe9-ad0e-955a2809eff7",
      "name": "Get Transcription Result",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        1360,
        544
      ],
      "parameters": {
        "url": "=https://api.gladia.io/v2/pre-recorded/{{ $('Start Transcription Job').item.json.id }}",
        "method": "GET",
        "options": {
          "timeout": 30000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 5000
    },
    {
      "id": "7499c9d7-66d7-4ac7-992d-1e7e7099dacf",
      "name": "Route by Status",
      "type": "n8n-nodes-base.switch",
      "position": [
        1568,
        512
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "done"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "error"
                  },
                  {
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $runIndex }}",
                    "rightValue": "={{ $('Prepare Config Values').item.json.max_attempts }}"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Still Processing"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9447b3e3-71f2-4f7a-9471-02e530d36834",
      "name": "Build Transcript File",
      "type": "n8n-nodes-base.code",
      "position": [
        1824,
        496
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const result = $json.result || {};\nconst transcription = result.transcription || {};\nconst fullTranscript = (transcription.full_transcript || '').trim();\nconst utterances = Array.isArray(transcription.utterances) ? transcription.utterances : [];\nconst duration = result.metadata?.audio_duration ?? $json.file?.audio_duration ?? $('Upload Audio to Gladia').item.json.audio_metadata?.audio_duration ?? null;\nconst sourceName = $('Google Drive Audio Trigger').item.json.name || 'audio-file';\nconst dot = sourceName.lastIndexOf('.');\nconst baseName = dot > 0 ? sourceName.slice(0, dot) : sourceName;\nconst stamp = $now.toFormat('yyyyLLdd-HHmmss');\nconst fileName = baseName + '-transcript-' + stamp + '.md';\nconst NL = String.fromCharCode(10);\nconst lines = [];\nlines.push('# Transcript: ' + sourceName);\nlines.push('');\nlines.push('- Source file: ' + sourceName);\nlines.push('- Duration: ' + (duration != null ? duration + ' seconds' : 'unknown'));\nlines.push('- Transcribed: ' + $now.toISO());\nlines.push('');\nlines.push('---');\nlines.push('');\nif (utterances.length) {\n  for (const u of utterances) {\n    const who = (u.speaker !== undefined && u.speaker !== null) ? ('Speaker ' + u.speaker) : 'Speaker';\n    lines.push('**' + who + ':** ' + (u.text || '').trim());\n    lines.push('');\n  }\n} else {\n  lines.push(fullTranscript || '(No transcript text was returned.)');\n}\nconst body = lines.join(NL);\nconst preview = fullTranscript.slice(0, 180);\nreturn { json: { source_file: sourceName, audio_duration: duration, file_name: fileName, preview: preview, status: 'Transcribed' }, binary: { data: { data: Buffer.from(body, 'utf-8').toString('base64'), mimeType: 'text/markdown', fileName: fileName, fileExtension: 'md' } } };"
      },
      "typeVersion": 2
    },
    {
      "id": "691fccab-9fd5-4ba6-8618-8e214e2fb2a1",
      "name": "Save Transcript to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "onError": "continueErrorOutput",
      "position": [
        2016,
        496
      ],
      "parameters": {
        "name": "={{ $json.file_name }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TRANSCRIPTS_FOLDER_ID"
        },
        "resource": "file",
        "operation": "upload",
        "inputDataFieldName": "data"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f1224ff7-e5cf-41a9-9684-5ce4026642f5",
      "name": "Log Transcript in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2208,
        480
      ],
      "parameters": {
        "columns": {
          "value": {
            "Detail": "={{ $('Build Transcript File').item.json.preview }}",
            "Status": "Transcribed",
            "Timestamp": "={{ $now.toISO() }}",
            "Source File": "={{ $('Google Drive Audio Trigger').item.json.name }}",
            "Duration (s)": "={{ $('Build Transcript File').item.json.audio_duration }}",
            "Transcript Link": "={{ $json.webViewLink || 'https://drive.google.com/file/d/' + $json.id + '/view' }}"
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source File",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source File",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Duration (s)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Duration (s)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Transcript Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Transcript Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Detail",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Detail",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_SHEET_TAB",
          "cachedResultName": "Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_YOUR_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "7f6f7a25-e326-448e-804e-26d3b22dea56",
      "name": "Log Failure in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2144,
        864
      ],
      "parameters": {
        "columns": {
          "value": {
            "Detail": "={{ $json.error?.message || ($json.status ? ('Gladia status: ' + $json.status) : 'Transcription failed or timed out. Check the execution log.') }}",
            "Status": "Failed",
            "Timestamp": "={{ $now.toISO() }}",
            "Source File": "={{ $('Google Drive Audio Trigger').first().json.name }}",
            "Duration (s)": "",
            "Transcript Link": ""
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source File",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source File",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Duration (s)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Duration (s)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Transcript Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Transcript Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Detail",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Detail",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_SHEET_TAB",
          "cachedResultName": "Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_YOUR_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5f71244f-9393-4b18-8c2d-640457307d09",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -192
      ],
      "parameters": {
        "width": 1232,
        "height": 532,
        "content": "## Transcribe new audio files from Google Drive using Gladia and Google Sheets\n\n### How it works\n\n1. A Google Drive trigger fires when a new audio or video file lands in a watched folder.\n2. The file is downloaded and sent to Gladia, which transcribes it asynchronously.\n3. The workflow polls Gladia until the transcript is ready, then saves it as a Markdown file in a Drive folder.\n4. Every run is logged to a Google Sheet, and failures are logged with a reason so nothing is lost silently.\n\n### Setup steps\n\n- [ ] Create a Header Auth credential named Gladia with header name x-gladia-key and your Gladia API key, then select it on the three Gladia HTTP nodes.\n- [ ] Set the watched folder on the trigger and the Transcripts folder on Save Transcript to Drive.\n- [ ] Pick the log spreadsheet and tab on both Sheets nodes.\n- [ ] Adjust wait_seconds and max_attempts in Prepare Config Values if your files run long.\n\n### Customization\n\nPoint the trigger at any Drive folder, change the transcript layout in Build Transcript File, or add a Slack node after the log to get a ping when a transcript is ready."
      },
      "typeVersion": 1
    },
    {
      "id": "2e3aa313-7621-4a57-83c7-7afde87e3032",
      "name": "Group Watch And Download",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        544
      ],
      "parameters": {
        "color": 7,
        "width": 668,
        "height": 384,
        "content": "## Watch and download the file\n\nA new file in the Drive folder triggers the run, config values are prepared, then the file is downloaded to binary."
      },
      "typeVersion": 1
    },
    {
      "id": "28504a13-cd04-40b8-bb3b-41b6f0451ae3",
      "name": "Group Send To Gladia",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        544
      ],
      "parameters": {
        "color": 7,
        "width": 472,
        "height": 368,
        "content": "## Send audio to Gladia\n\nUpload the file to Gladia, then start an asynchronous transcription job."
      },
      "typeVersion": 1
    },
    {
      "id": "2380a42a-a9ce-4834-b6fb-ee0d0b3a542b",
      "name": "Group Poll For Result",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 628,
        "height": 416,
        "content": "## Poll until transcription is done\n\nWait, fetch the result, and route by status. Loop back until Gladia returns done or the attempt limit is reached."
      },
      "typeVersion": 1
    },
    {
      "id": "dfe9c1f2-3cab-4721-bfce-b8e3c6d4da03",
      "name": "Group Save And Log",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 308,
        "content": "## Save transcript and log\n\nBuild a Markdown transcript, save it to Drive, and append a row to the log sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "fb183416-6279-4697-acd1-48162079ba8b",
      "name": "Group Handle Failures",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 340,
        "height": 344,
        "content": "## Handle failures\n\nAny API error or a timeout writes a Failed row with a reason, so nothing fails silently."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Route by Status": {
      "main": [
        [
          {
            "node": "Build Transcript File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Failure in Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Processing": {
      "main": [
        [
          {
            "node": "Get Transcription Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Transcript File": {
      "main": [
        [
          {
            "node": "Save Transcript to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Config Values": {
      "main": [
        [
          {
            "node": "Download File from Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Audio to Gladia": {
      "main": [
        [
          {
            "node": "Start Transcription Job",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Failure in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Transcription Job": {
      "main": [
        [
          {
            "node": "Wait for Processing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Failure in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download File from Drive": {
      "main": [
        [
          {
            "node": "Upload Audio to Gladia",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Transcription Result": {
      "main": [
        [
          {
            "node": "Route by Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Failure in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Transcript to Drive": {
      "main": [
        [
          {
            "node": "Log Transcript in Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Failure in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Audio Trigger": {
      "main": [
        [
          {
            "node": "Prepare Config Values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}