This workflow corresponds to n8n.io template #15493 — we link there as the canonical source.
This workflow follows the Agent → Form 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "e56bf8e3-16cb-4791-b44a-14efe667f8a7",
"name": "Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-880,
-400
],
"parameters": {
"color": 4,
"width": 492,
"height": 1060,
"content": "## Webinar Recording to 5-Day Drip Email Course Creator \u2014 WayinVideo AI Clipping + GPT-4o-mini + Google Sheets\n\nFor course creators, coaches, educators, and marketing teams who run webinars and want to automatically repurpose them into a 5-day email mini-course. Submit any webinar recording URL via the form. WayinVideo AI Clipping API extracts the top 5 most engaging teaching moments ranked by engagement score \u2014 sorted highest first so the best content becomes Day 1. GPT-4o-mini writes a complete standalone email lesson for each clip \u2014 Day 1 is welcoming and introduces the course, the final day wraps up and points to next steps, middle days continue naturally. Each email includes a subject line (40\u201355 chars), preview text (85\u2013100 chars), email body (200\u2013300 words), key takeaway, CTA text, and a CTA URL placeholder. All 5 email lessons are saved to Google Sheets as a ready-to-use drip course with Draft status.\n\n## How it works\n- **1. Form \u2014 Webinar URL + Course Details** collects the recording URL, webinar title, mini-course name, target audience, brand name, and email tone\n- **2. WayinVideo \u2014 Submit AI Clipping** submits the URL for AI clipping with 60\u201390 second target clip duration, limit 5, export disabled\n- **3. Wait \u2014 90 Seconds** gives the API initial processing time\n- **4. WayinVideo \u2014 Get Clip Results** polls the clips results endpoint\n- **5. IF \u2014 Clipping Complete?** checks for SUCCEEDED \u2014 if not, retries via 30-second wait\n- **7. Code \u2014 Extract Clips + Assign Days** sorts clips by score descending, assigns Day 1\u20135, and returns one item per clip\n- **8. AI Agent \u2014 Write Email Lesson** uses GPT-4o-mini with 10 email writing rules to produce 6 labeled output sections per day\n- **10. Code \u2014 Parse Email Output** extracts all 6 sections via regex and computes word count\n- **11. Google Sheets \u2014 Save Email Course** appends one row per day with all 16 fields and Status set to Draft\n\n## Set up steps\n1. In **2. WayinVideo \u2014 Submit AI Clipping** and **4. WayinVideo \u2014 Get Clip Results** \u2014 replace `YOUR_WAYINVIDEO_API_KEY`\n2. In **9. OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI credential\n3. In **11. Google Sheets \u2014 Save Email Course** \u2014 connect your Google Sheets OAuth2 credential and replace `YOUR_GOOGLE_SHEET_ID`\n4. Create a Google Sheet tab named Drip Email Course with columns: Webinar Title, Course Name, Day Number, Email Subject, Preview Text, Email Body, Key Takeaway, CTA Text, CTA URL Placeholder, Word Count, Clip Title, Clip Score, Clip Timestamp, Webinar URL, Generated On, Status"
},
"typeVersion": 1
},
{
"id": "c4b220b8-eabc-4119-8239-7df05b628186",
"name": "Section \u2014 Form Input",
"type": "n8n-nodes-base.stickyNote",
"position": [
-368,
-272
],
"parameters": {
"color": 5,
"width": 324,
"height": 388,
"content": "## Form Input\nUser submits webinar recording URL, webinar title, mini-course name, target audience, brand name, and email tone. All six fields feed into clip extraction and the AI email writing prompt."
},
"typeVersion": 1
},
{
"id": "98957452-0dc2-477a-bfef-9a46b52f3ac7",
"name": "Section \u2014 WayinVideo AI Clipping Submit and Poll",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-320
],
"parameters": {
"color": 6,
"width": 660,
"height": 468,
"content": "## WayinVideo AI Clipping Submit and Poll\nSubmits the webinar URL for AI clipping \u2014 60\u201390 second clips, limit 5, export disabled. Waits 90 seconds for initial processing. Polls the clips results endpoint until status equals SUCCEEDED."
},
"typeVersion": 1
},
{
"id": "aea56429-c57a-437b-893c-96fc730658f9",
"name": "Section \u2014 Clipping Status Check and Retry Loop",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
-384
],
"parameters": {
"color": 6,
"width": 404,
"height": 772,
"content": "## Clipping Status Check and Retry Loop\nIF checks for SUCCEEDED status. TRUE proceeds to clip extraction. FALSE waits 30 seconds and polls again. Loop continues until clips are ready."
},
"typeVersion": 1
},
{
"id": "58eddf42-6940-45dc-b7c7-a083f58cef0f",
"name": "Section \u2014 Clip Extraction and AI Email Lesson Writing",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
-304
],
"parameters": {
"color": 6,
"width": 612,
"height": 628,
"content": "## Clip Extraction and AI Email Lesson Writing\nSorts clips by engagement score descending and assigns Day 1\u20135. GPT-4o-mini writes a complete email lesson per clip \u2014 Day 1 is welcoming, last day is a conclusion, middle days continue naturally."
},
"typeVersion": 1
},
{
"id": "d5a2bb01-ed24-47dc-aabe-5ddb6d79d391",
"name": "Section \u2014 Email Parse and Google Sheets Save",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
-272
],
"parameters": {
"color": 4,
"width": 532,
"height": 404,
"content": "## Email Parse and Google Sheets Save\nRegex extracts 6 labeled sections and computes word count. Google Sheets appends one row per day with all 16 fields including CTA URL placeholder and Status set to Draft."
},
"typeVersion": 1
},
{
"id": "6ac2645e-376a-4fa5-ace3-84bc8e22660d",
"name": "1. Form \u2014 Webinar URL + Course Details",
"type": "n8n-nodes-base.formTrigger",
"position": [
-272,
-112
],
"parameters": {
"options": {},
"formTitle": "Webinar to 5-Day Drip Email Course Creator",
"formFields": {
"values": [
{
"fieldLabel": "Webinar Recording URL",
"placeholder": "https://www.youtube.com/watch?v=xxxxxxx or Zoom/Vimeo link",
"requiredField": true
},
{
"fieldLabel": "Webinar / Course Title",
"placeholder": "e.g. Mastering SEO in 2025 \u2014 Full Webinar",
"requiredField": true
},
{
"fieldLabel": "Mini-Course Name",
"placeholder": "e.g. 5-Day SEO Crash Course, Your Free Marketing Masterclass",
"requiredField": true
},
{
"fieldLabel": "Target Audience",
"placeholder": "e.g. Small business owners, digital marketers, freelancers",
"requiredField": true
},
{
"fieldLabel": "Brand / Sender Name",
"placeholder": "e.g. Incrementors, John Smith, The Marketing Lab",
"requiredField": true
},
{
"fieldLabel": "Email Tone",
"placeholder": "e.g. Professional and educational / Casual and friendly / Motivational",
"requiredField": true
}
]
},
"formDescription": "Paste your webinar recording URL. AI will extract the top 5 teaching moments and write a complete 5-day email mini-course ready to send to your audience."
},
"typeVersion": 2.2
},
{
"id": "e0cf4ae2-be44-49f7-a406-82a4220fe35b",
"name": "2. WayinVideo \u2014 Submit AI Clipping",
"type": "n8n-nodes-base.httpRequest",
"position": [
32,
-112
],
"parameters": {
"url": "https://wayinvideo-api.wayin.ai/api/v2/clips",
"method": "POST",
"options": {},
"jsonBody": "={\n \"video_url\": \"{{ $json['Webinar Recording URL'] }}\",\n \"project_name\": \"Drip Course \u2014 {{ $json['Mini-Course Name'] }}\",\n \"target_duration\": \"DURATION_60_90\",\n \"limit\": 5,\n \"enable_export\": false,\n \"target_lang\": \"en\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "x-wayinvideo-api-version",
"value": "v2"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "197abd47-dee3-481d-b182-ca85bdd6172d",
"name": "3. Wait \u2014 90 Seconds",
"type": "n8n-nodes-base.wait",
"position": [
272,
-112
],
"parameters": {
"amount": 90
},
"typeVersion": 1.1
},
{
"id": "e9bb960a-3582-4e35-89ae-ba22cb565407",
"name": "4. WayinVideo \u2014 Get Clip Results",
"type": "n8n-nodes-base.httpRequest",
"position": [
512,
-112
],
"parameters": {
"url": "=https://wayinvideo-api.wayin.ai/api/v2/clips/results/{{ $('2. WayinVideo \u2014 Submit AI Clipping').item.json.data.id }}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "x-wayinvideo-api-version",
"value": "v2"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "7b6adaf7-d2aa-489c-bd9f-3abe9feb226b",
"name": "5. IF \u2014 Clipping Complete?",
"type": "n8n-nodes-base.if",
"position": [
784,
-112
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "status-check",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.data.status }}",
"rightValue": "SUCCEEDED"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "e2b5d9d4-f649-4361-984b-04be84745e54",
"name": "6. Wait \u2014 30 Seconds Retry",
"type": "n8n-nodes-base.wait",
"position": [
800,
128
],
"parameters": {
"amount": 30
},
"typeVersion": 1.1
},
{
"id": "8acd0759-839a-4955-a92a-413393887511",
"name": "7. Code \u2014 Extract Clips + Assign Days",
"type": "n8n-nodes-base.code",
"position": [
1184,
-128
],
"parameters": {
"jsCode": "// Extract clips from WayinVideo results\nconst clips = $('4. WayinVideo \u2014 Get Clip Results').item.json.data?.clips || [];\n\nif (clips.length === 0) {\n throw new Error('No clips returned from WayinVideo \u2014 check if the video URL is valid and publicly accessible.');\n}\n\n// Get form data\nconst webinarTitle = $('1. Form \u2014 Webinar URL + Course Details').item.json['Webinar / Course Title'];\nconst courseName = $('1. Form \u2014 Webinar URL + Course Details').item.json['Mini-Course Name'];\nconst targetAudience = $('1. Form \u2014 Webinar URL + Course Details').item.json['Target Audience'];\nconst brandName = $('1. Form \u2014 Webinar URL + Course Details').item.json['Brand / Sender Name'];\nconst emailTone = $('1. Form \u2014 Webinar URL + Course Details').item.json['Email Tone'];\nconst webinarUrl = $('1. Form \u2014 Webinar URL + Course Details').item.json['Webinar Recording URL'];\n\n// Sort clips by score descending \u2014 best clips first\nconst sortedClips = clips.sort((a, b) => (b.score || 0) - (a.score || 0));\n\n// Take top 5 \u2014 one per day\nconst topClips = sortedClips.slice(0, 5);\n\n// Return one item per clip \u2014 each becomes one email day\nreturn topClips.map((clip, index) => ({\n json: {\n dayNumber: index + 1,\n totalDays: topClips.length,\n clipTitle: clip.title || `Day ${index + 1} Lesson`,\n clipDescription: clip.desc || '',\n clipScore: clip.score || 0,\n clipTags: Array.isArray(clip.tags) ? clip.tags.join(', ') : '',\n beginMs: clip.begin_ms || 0,\n endMs: clip.end_ms || 0,\n timestampStart: `${Math.floor((clip.begin_ms || 0) / 60000)}:${String(Math.floor(((clip.begin_ms || 0) % 60000) / 1000)).padStart(2, '0')}`,\n timestampEnd: `${Math.floor((clip.end_ms || 0) / 60000)}:${String(Math.floor(((clip.end_ms || 0) % 60000) / 1000)).padStart(2, '00')}`,\n webinarTitle,\n courseName,\n targetAudience,\n brandName,\n emailTone,\n webinarUrl\n }\n}));"
},
"typeVersion": 2
},
{
"id": "361eb8d7-9c46-4880-87d4-a2c7a36a1212",
"name": "8. AI Agent \u2014 Write Email Lesson",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1424,
-128
],
"parameters": {
"text": "={{ $json.clipDescription }}",
"options": {
"systemMessage": "=You are an expert email copywriter who specializes in writing high-converting educational email courses from video content.\n\nA webinar has been automatically clipped into key teaching moments. Your job is to write a complete standalone email lesson for Day {{ $json.dayNumber }} of a {{ $json.totalDays }}-day mini email course \u2014 based on this specific clip.\n\n---\n\n## COURSE CONTEXT\n- Webinar Title: {{ $json.webinarTitle }}\n- Mini-Course Name: {{ $json.courseName }}\n- Target Audience: {{ $json.targetAudience }}\n- Brand / Sender: {{ $json.brandName }}\n- Email Tone: {{ $json.emailTone }}\n- Day: {{ $json.dayNumber }} of {{ $json.totalDays }}\n\n## THIS CLIP (Day {{ $json.dayNumber }} Lesson)\n- Clip Title: {{ $json.clipTitle }}\n- Description: {{ $json.clipDescription }}\n- Engagement Score: {{ $json.clipScore }}/100\n- Tags: {{ $json.clipTags }}\n- Timestamp in Recording: {{ $json.timestampStart }} \u2014 {{ $json.timestampEnd }}\n\n---\n\n## EMAIL WRITING RULES\n1. Write based ONLY on the clip content provided \u2014 no invented information\n2. Match the tone specified \u2014 keep it consistent throughout\n3. Day 1 email should feel welcoming \u2014 introduce the course briefly before the lesson\n4. Final day email should feel like a conclusion \u2014 celebrate completion and point to next step\n5. Middle days should feel like natural continuation\n6. Subject line: 40-55 characters \u2014 curiosity or benefit driven \u2014 no clickbait\n7. Preview text: 85-100 characters \u2014 complements subject, not a repeat\n8. Email body: 200-300 words \u2014 short, punchy paragraphs, easy to read\n9. One clear CTA at the end \u2014 action-oriented\n10. Key takeaway: one sentence \u2014 the single most important thing to remember\n\n---\n\n## OUTPUT FORMAT\nReturn in this exact structure:\n\nSUBJECT_LINE:\n[Write subject line here \u2014 40-55 characters]\n\nPREVIEW_TEXT:\n[Write preview text here \u2014 85-100 characters]\n\nEMAIL_BODY:\n[Write full email body here \u2014 200-300 words \u2014 short paragraphs \u2014 conversational]\n\nKEY_TAKEAWAY:\n[Write one sentence takeaway here]\n\nCTA_TEXT:\n[Write the CTA button text \u2014 3-6 words \u2014 action oriented]\n\nCTA_URL_PLACEHOLDER:\n[Write a placeholder for the CTA URL \u2014 e.g. YOUR_COURSE_LINK or YOUR_WEBSITE_LINK]\n\n---\n\nNow write the Day {{ $json.dayNumber }} email lesson:"
},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "3433e652-265e-472b-b9a4-ac84d4267749",
"name": "9. OpenAI \u2014 GPT-4o-mini Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1424,
64
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"typeVersion": 1.3
},
{
"id": "85080ab7-6638-45c1-8760-9cafe4cdef84",
"name": "10. Code \u2014 Parse Email Output",
"type": "n8n-nodes-base.code",
"position": [
1904,
-128
],
"parameters": {
"jsCode": "// Parse AI email output into structured fields\nconst output = $input.first().json.output || '';\n\n// Extract each section\nconst subjectMatch = output.match(/SUBJECT_LINE:\\s*([\\s\\S]*?)(?=\\nPREVIEW_TEXT:|$)/);\nconst previewMatch = output.match(/PREVIEW_TEXT:\\s*([\\s\\S]*?)(?=\\nEMAIL_BODY:|$)/);\nconst bodyMatch = output.match(/EMAIL_BODY:\\s*([\\s\\S]*?)(?=\\nKEY_TAKEAWAY:|$)/);\nconst takeawayMatch = output.match(/KEY_TAKEAWAY:\\s*([\\s\\S]*?)(?=\\nCTA_TEXT:|$)/);\nconst ctaTextMatch = output.match(/CTA_TEXT:\\s*([\\s\\S]*?)(?=\\nCTA_URL_PLACEHOLDER:|$)/);\nconst ctaUrlMatch = output.match(/CTA_URL_PLACEHOLDER:\\s*([\\s\\S]*)$/);\n\nconst subjectLine = subjectMatch ? subjectMatch[1].trim() : '';\nconst previewText = previewMatch ? previewMatch[1].trim() : '';\nconst emailBody = bodyMatch ? bodyMatch[1].trim() : '';\nconst keyTakeaway = takeawayMatch ? takeawayMatch[1].trim() : '';\nconst ctaText = ctaTextMatch ? ctaTextMatch[1].trim() : '';\nconst ctaUrl = ctaUrlMatch ? ctaUrlMatch[1].trim() : 'YOUR_LINK_HERE';\n\nif (!subjectLine || !emailBody) {\n throw new Error('Could not parse email from AI output. Check the prompt output format.');\n}\n\n// Get clip data from step 7\nconst clipData = $('7. Code \u2014 Extract Clips + Assign Days').item.json;\n\nreturn [{\n json: {\n dayNumber: clipData.dayNumber,\n subjectLine,\n previewText,\n emailBody,\n keyTakeaway,\n ctaText,\n ctaUrl,\n wordCount: emailBody.split(/\\s+/).length,\n clipTitle: clipData.clipTitle,\n clipScore: clipData.clipScore,\n timestamp: `${clipData.timestampStart} \u2014 ${clipData.timestampEnd}`,\n webinarTitle: clipData.webinarTitle,\n courseName: clipData.courseName,\n targetAudience: clipData.targetAudience,\n brandName: clipData.brandName,\n webinarUrl: clipData.webinarUrl\n }\n}];"
},
"typeVersion": 2
},
{
"id": "1bd428f3-2632-43d1-9c3f-354390ea047e",
"name": "11. Google Sheets \u2014 Save Email Course",
"type": "n8n-nodes-base.googleSheets",
"position": [
2144,
-128
],
"parameters": {
"columns": {
"value": {
"Status": "Draft",
"CTA Text": "={{ $json.ctaText }}",
"Clip Score": "={{ $json.clipScore }}",
"Clip Title": "={{ $json.clipTitle }}",
"Day Number": "={{ $json.dayNumber }}",
"Email Body": "={{ $json.emailBody }}",
"Word Count": "={{ $json.wordCount }}",
"Course Name": "={{ $json.courseName }}",
"Webinar URL": "={{ $json.webinarUrl }}",
"Generated On": "={{ $now.toFormat('dd MMMM yyyy HH:mm') }}",
"Key Takeaway": "={{ $json.keyTakeaway }}",
"Preview Text": "={{ $json.previewText }}",
"Email Subject": "={{ $json.subjectLine }}",
"Webinar Title": "={{ $json.webinarTitle }}",
"Clip Timestamp": "={{ $json.timestamp }}",
"CTA URL Placeholder": "={{ $json.ctaUrl }}"
},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Drip Email Course"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"typeVersion": 4.5
}
],
"connections": {
"3. Wait \u2014 90 Seconds": {
"main": [
[
{
"node": "4. WayinVideo \u2014 Get Clip Results",
"type": "main",
"index": 0
}
]
]
},
"5. IF \u2014 Clipping Complete?": {
"main": [
[
{
"node": "7. Code \u2014 Extract Clips + Assign Days",
"type": "main",
"index": 0
}
],
[
{
"node": "6. Wait \u2014 30 Seconds Retry",
"type": "main",
"index": 0
}
]
]
},
"6. Wait \u2014 30 Seconds Retry": {
"main": [
[
{
"node": "4. WayinVideo \u2014 Get Clip Results",
"type": "main",
"index": 0
}
]
]
},
"10. Code \u2014 Parse Email Output": {
"main": [
[
{
"node": "11. Google Sheets \u2014 Save Email Course",
"type": "main",
"index": 0
}
]
]
},
"9. OpenAI \u2014 GPT-4o-mini Model": {
"ai_languageModel": [
[
{
"node": "8. AI Agent \u2014 Write Email Lesson",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"4. WayinVideo \u2014 Get Clip Results": {
"main": [
[
{
"node": "5. IF \u2014 Clipping Complete?",
"type": "main",
"index": 0
}
]
]
},
"8. AI Agent \u2014 Write Email Lesson": {
"main": [
[
{
"node": "10. Code \u2014 Parse Email Output",
"type": "main",
"index": 0
}
]
]
},
"2. WayinVideo \u2014 Submit AI Clipping": {
"main": [
[
{
"node": "3. Wait \u2014 90 Seconds",
"type": "main",
"index": 0
}
]
]
},
"7. Code \u2014 Extract Clips + Assign Days": {
"main": [
[
{
"node": "8. AI Agent \u2014 Write Email Lesson",
"type": "main",
"index": 0
}
]
]
},
"1. Form \u2014 Webinar URL + Course Details": {
"main": [
[
{
"node": "2. WayinVideo \u2014 Submit AI Clipping",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Submit any webinar recording URL using a simple form along with your course name, target audience, brand name, and preferred email tone and the workflow builds a complete 5-day drip email course automatically. WayinVideo AI Clipping extracts the top 5 most engaging teaching…
Source: https://n8n.io/workflows/15493/ — 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.
🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.
Digistars - Scrape & Crawl. Uses httpRequest, n8n-nodes-firecrawl-scraper, googleSheets, lmChatOpenAi. Event-driven trigger; 63 nodes.
🧠 Automate end-to-end SEO blog creation and WordPress publishing using a GPT-5 multi-agent workflow with real-time research, metadata generation, and optional featured images.
The workflow runs every hour with a randomized delay of 5–20 minutes to help distribute load. It records the exact date and time a lead is emailed so you can track outreach. Follow-ups are automatical
This n8n workflow automates turning short user ideas into production-ready real-estate marketing assets (photorealistic images and optional 360° videos). A form submission seeds a prompt board → an LL