This workflow corresponds to n8n.io template #17758 — we link there as the canonical source.
This workflow follows the Gmail → 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 →
{
"id": "NToMW6sFTYKqdLrT",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "New Video \u2192 Thumbnail + Quotes \u2192 Gmail Draft",
"tags": [],
"nodes": [
{
"id": "d9039857-2345-4988-bb96-c741efb21b7f",
"name": "When Video Added to Drive",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
37312,
13920
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 1
},
{
"id": "8028cf25-595d-40a3-a4dc-41cd4f63e3ef",
"name": "Download Video",
"type": "n8n-nodes-base.googleDrive",
"position": [
37536,
13920
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "download"
},
"typeVersion": 3
},
{
"id": "b863266a-cbbe-4b56-affd-9fbb1745b84b",
"name": "Transcribe Audio",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
37744,
13920
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"typeVersion": 1.8
},
{
"id": "9e1dbf9e-0495-4c00-9f07-56842ffd2823",
"name": "Extract Thumbnail + Quotes",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
37952,
13920
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {},
"messages": {
"values": [
{
"content": "=From this video transcript, return STRICT JSON only: {\"headline\": \"a punchy 4-7 word thumbnail headline\", \"quotes\": [\"quote 1\", \"quote 2\", \"quote 3\"]}. Transcript: {{ $('Transcribe Audio').item.json.text }}"
}
]
}
},
"typeVersion": 1.8
},
{
"id": "db28979f-4dd3-4b30-bd07-2ab5142c368c",
"name": "Parse Concept",
"type": "n8n-nodes-base.code",
"position": [
38208,
13920
],
"parameters": {
"jsCode": "const raw = $json.message?.content ?? $json.text ?? $json.content ?? '';\nlet a; try { a = JSON.parse(raw); } catch(e){ const m=String(raw).match(/\\{[\\s\\S]*\\}/); a=m?JSON.parse(m[0]):{headline:'',quotes:[]}; }\nconst content = `${a.headline}\\n\\n` + (a.quotes||[]).map(q=>`\\u201C${q}\\u201D`).join('\\n');\nreturn [{ json: { headline: a.headline, content } }];"
},
"typeVersion": 2
},
{
"id": "47c43fde-e672-4f6c-acb8-2651d7229e75",
"name": "Post to Canvora",
"type": "n8n-nodes-base.httpRequest",
"position": [
38512,
13920
],
"parameters": {
"url": "https://api.canvora.ai/api/generations",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({\n inputType: 'text',\n inputContent: $('Parse Concept').item.json.content,\n title: 'Video kit: ' + $('Parse Concept').item.json.headline,\n outputFormats: ['youtube_thumbnail', 'quote_card']\n}) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "9b2983c5-4ac5-4798-b692-b1dae61680f2",
"name": "Wait 30s",
"type": "n8n-nodes-base.wait",
"position": [
38864,
13920
],
"parameters": {
"amount": 30
},
"typeVersion": 1.1
},
{
"id": "82236fd0-6fca-49e1-9915-dd6af9e9a241",
"name": "Fetch Generation Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
39072,
13920
],
"parameters": {
"url": "=https://api.canvora.ai/api/generations/{{ $('Post to Canvora').item.json.generation.id }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "096092d2-db6e-4fb9-bdb6-b486e4600c14",
"name": "If Generation Done",
"type": "n8n-nodes-base.if",
"position": [
39280,
13920
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t41",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ ['completed','failed','partial','cancelled'].includes($json.generation.status) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "147a22c8-7711-4402-a427-c5fb7955770e",
"name": "If Timed Out",
"type": "n8n-nodes-base.if",
"position": [
39280,
14128
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t42",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $runIndex >= 20 }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "332b1880-06c2-48a3-8fe5-d0cbc0250255",
"name": "If Generation Succeeded",
"type": "n8n-nodes-base.if",
"position": [
39632,
13920
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t43",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ ['completed','partial'].includes($json.generation.status) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "3f11304a-c621-47e8-9f08-a8a6cbf34f90",
"name": "Build Review Email",
"type": "n8n-nodes-base.code",
"position": [
39840,
13920
],
"parameters": {
"jsCode": "const g = $input.first().json.generation;\nconst outs = g.outputs || [];\nconst imgs = outs.map(o => `<p><b>${o.format}</b><br><img src=\"${o.fileUrl}\" width=\"480\"/></p>`).join('\\n');\nconst html = `<h2>${$('Parse Concept').item.json.headline}</h2>\\n${imgs}\\n<p>Edit: https://canvora.ai/generations/${g.id}</p>`;\nreturn [{ json: { subject: 'Video visuals ready: ' + $('Parse Concept').item.json.headline, html } }];"
},
"typeVersion": 2
},
{
"id": "8aefe662-1fda-4a58-ab2c-eb84eb121f6b",
"name": "Create Gmail Draft",
"type": "n8n-nodes-base.gmail",
"position": [
40048,
13920
],
"parameters": {
"message": "={{ $json.html }}",
"options": {},
"subject": "={{ $json.subject }}",
"resource": "draft"
},
"typeVersion": 2.1
},
{
"id": "fcf7569f-3eea-48fa-8f77-2c90ea2141a2",
"name": "Generation Failed (credits auto-refunded)",
"type": "n8n-nodes-base.noOp",
"position": [
39952,
14336
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1af8e5b9-ac06-4858-820c-2b8492d23c90",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
36592,
13648
],
"parameters": {
"color": 7,
"width": 560,
"height": 1056,
"content": "## New Video \u2192 Thumbnail + Quote Cards \u2192 Drive + Gmail Draft\n\n### How it works\nDrop a video into a watched Google Drive folder. The workflow transcribes it,\nan AI model pulls a punchy **thumbnail headline** and three **pull-quotes**,\nand Canvora designs a **YouTube thumbnail** plus **quote cards** \u2014 on brand.\nThe finished visuals are assembled into a **Gmail draft** for a quick review\nbefore you publish (no auto-send, no Slack).\n\n### Setup steps\n- Create a free Canvora account at canvora.ai \u2014 free credits, no card \u2014 and\n copy an API key from Integrations \u2192 API Keys (all plans).\n- In each Canvora HTTP Request node, add a **Header Auth** credential:\n name `X-API-Key`, value your `vd_...` key.\n- Connect your Google Drive and Gmail credentials.\n- Add your OpenAI credential (used for transcription + concept extraction).\n- In the trigger, pick the Drive folder you'll drop videos into.\n\n### Customization\n- Add `instagram_reel` or `twitter_post` to `outputFormats` for more clip\n art (100+ formats: GET https://api.canvora.ai/api/formats).\n- Pass a `brandId` (GET /api/brands) to lock visuals to your brand kit.\n- Change \"Create Gmail Draft\" to \"send\" to skip review, or upload the images\n to Drive instead.\n- Cost: 2 visuals = 20 credits per video.\n"
},
"typeVersion": 1
},
{
"id": "47956295-1c4e-4932-9602-0e3bb45481aa",
"name": "Sticky Note100",
"type": "n8n-nodes-base.stickyNote",
"position": [
37216,
13760
],
"parameters": {
"color": 7,
"width": 1134,
"height": 406,
"content": "## Transcribe the video\n\nWhen a video lands in the watched Drive folder, it's downloaded, transcribed, and an AI model pulls a headline + pull-quotes."
},
"typeVersion": 1
},
{
"id": "5193d698-7f5e-49ce-8117-d8e6370f1742",
"name": "Sticky Note101",
"type": "n8n-nodes-base.stickyNote",
"position": [
38464,
13680
],
"parameters": {
"color": 7,
"height": 390,
"content": "## Design the visuals\n\nSends the concept to Canvora, which designs a YouTube thumbnail and quote cards."
},
"typeVersion": 1
},
{
"id": "0bf70099-1a75-485c-940e-a2d500655de3",
"name": "Sticky Note102",
"type": "n8n-nodes-base.stickyNote",
"position": [
38768,
13760
],
"parameters": {
"color": 7,
"width": 698,
"height": 626,
"content": "## Poll generation status\n\nWaits between checks, fetches the state, and loops until the visuals finish or it times out."
},
"typeVersion": 1
},
{
"id": "0954989e-68f7-4a3c-86ad-c66237276a74",
"name": "Sticky Note103",
"type": "n8n-nodes-base.stickyNote",
"position": [
39568,
13760
],
"parameters": {
"color": 7,
"width": 666,
"height": 310,
"content": "## Deliver for review\n\nOn success, assembles the visuals into a Gmail draft for a quick review before publishing."
},
"typeVersion": 1
},
{
"id": "8b1b2211-9214-4f1f-ac60-7dbaef7c43f7",
"name": "Sticky Note104",
"type": "n8n-nodes-base.stickyNote",
"position": [
39888,
14112
],
"parameters": {
"color": 7,
"width": 256,
"height": 390,
"content": "## Handle failure\n\nIf generation fails or times out, credits are refunded automatically."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "ed4825e8-4163-493b-9b51-1a1e92bcbf2f",
"nodeGroups": [],
"connections": {
"Wait 30s": {
"main": [
[
{
"node": "Fetch Generation Status",
"type": "main",
"index": 0
}
]
]
},
"If Timed Out": {
"main": [
[
{
"node": "Generation Failed (credits auto-refunded)",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait 30s",
"type": "main",
"index": 0
}
]
]
},
"Parse Concept": {
"main": [
[
{
"node": "Post to Canvora",
"type": "main",
"index": 0
}
]
]
},
"Download Video": {
"main": [
[
{
"node": "Transcribe Audio",
"type": "main",
"index": 0
}
]
]
},
"Post to Canvora": {
"main": [
[
{
"node": "Wait 30s",
"type": "main",
"index": 0
}
]
]
},
"Transcribe Audio": {
"main": [
[
{
"node": "Extract Thumbnail + Quotes",
"type": "main",
"index": 0
}
]
]
},
"Build Review Email": {
"main": [
[
{
"node": "Create Gmail Draft",
"type": "main",
"index": 0
}
]
]
},
"If Generation Done": {
"main": [
[
{
"node": "If Generation Succeeded",
"type": "main",
"index": 0
}
],
[
{
"node": "If Timed Out",
"type": "main",
"index": 0
}
]
]
},
"Fetch Generation Status": {
"main": [
[
{
"node": "If Generation Done",
"type": "main",
"index": 0
}
]
]
},
"If Generation Succeeded": {
"main": [
[
{
"node": "Build Review Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Generation Failed (credits auto-refunded)",
"type": "main",
"index": 0
}
]
]
},
"When Video Added to Drive": {
"main": [
[
{
"node": "Download Video",
"type": "main",
"index": 0
}
]
]
},
"Extract Thumbnail + Quotes": {
"main": [
[
{
"node": "Parse Concept",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow watches a Google Drive folder for new videos, transcribes the audio with OpenAI, generates a thumbnail headline and pull quotes, sends them to Canvora to design a YouTube thumbnail and quote cards, then creates a Gmail draft with the results for review. Triggers…
Source: https://n8n.io/workflows/17758/ — 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.
The Problem That it Solves
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.
What it is An automated LinkedIn content system that takes a simple form (idea + optional file), generates LinkedIn posts with OpenAI, stores them in Notion, builds Google Slides carousels, and auto-p
This workflow automatically turns any audio file uploaded to Google Drive into a complete podcast episode. It handles transcription, content generation, blog drafting, social copy creation, thumbnail
AI Expense Tracker. Uses gmailTrigger, openAi, googleDrive, googleSheets. Event-driven trigger; 31 nodes.