This workflow follows the Gmail → Googlegemini 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 →
{
"name": "MacWhisper Transcript Processor",
"nodes": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
250,
300
],
"parameters": {
"path": "transcript-processor",
"httpMethod": "POST",
"responseMode": "lastNode",
"options": {}
}
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Fragment Selection",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1,
"position": [
550,
300
],
"parameters": {
"model": {
"__rl": true,
"value": "gemini-2.0-flash-exp",
"mode": "list",
"cachedResultName": "gemini-2.0-flash-exp"
},
"options": {
"systemMessage": "You are an expert content analyzer. Your task is to analyze podcast/stream transcripts and identify the 3-5 most engaging, emotional, or impactful fragments.\n\nFor each fragment, provide:\n- Start timecode in [HH:MM] format\n- End timecode in [HH:MM] format\n- Brief reason why this fragment is engaging\n\nFormat your response EXACTLY as:\n[HH:MM] -- [HH:MM]: Brief description of why this fragment is engaging\n\nSeparate each fragment with a blank line. Focus on moments with high emotional impact, insights, humor, or controversy."
},
"prompt": "=Analyze this transcript and identify the 3-5 most engaging fragments:\n\nTitle: {{ $json.body.title }}\n\nTranscript:\n{{ $json.body.transcript }}"
}
},
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"name": "Get Fragment Text",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1,
"position": [
850,
300
],
"parameters": {
"model": {
"__rl": true,
"value": "gemini-2.0-flash-exp",
"mode": "list",
"cachedResultName": "gemini-2.0-flash-exp"
},
"options": {
"systemMessage": "You are a precise transcript extractor. Your task is to extract the EXACT verbatim text for each fragment based on the provided timecodes.\n\nFor each fragment, output:\n[START_TIME] -- [END_TIME]\nEXACT VERBATIM TEXT FROM TRANSCRIPT\n---\n\nSeparate each fragment with '---' on its own line. Preserve all speaker names, pauses, and exact wording from the original transcript."
},
"prompt": "=Extract the exact verbatim text for these fragments from the transcript:\n\nFragments to extract:\n{{ $('Fragment Selection').item.json.message.content }}\n\nFull transcript:\n{{ $('Webhook').item.json.body.transcript }}\n\nProvide the exact text for each fragment, separated by '---'"
}
},
{
"id": "d4e5f6a7-b8c9-0123-def1-234567890123",
"name": "Split Fragments",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1150,
300
],
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "const fragmentText = $input.item.json.message.content;\n\n// Split by --- delimiter\nconst fragments = fragmentText.split('---').filter(f => f.trim());\n\n// Parse each fragment\nconst parsedFragments = fragments.map((fragment, index) => {\n const trimmed = fragment.trim();\n \n // Extract timecodes using regex [HH:MM] -- [HH:MM]\n const timecodeMatch = trimmed.match(/\\[(\\d{2}:\\d{2})\\]\\s*--\\s*\\[(\\d{2}:\\d{2})\\]/);\n \n if (!timecodeMatch) {\n return null;\n }\n \n const start = timecodeMatch[1];\n const end = timecodeMatch[2];\n \n // Extract content (everything after the timecode line)\n const contentStart = trimmed.indexOf('\\n', timecodeMatch.index);\n const content = contentStart !== -1 ? trimmed.substring(contentStart + 1).trim() : '';\n \n return {\n json: {\n fragmentIndex: index + 1,\n start: start,\n end: end,\n content: content,\n timecodeRange: `${start} -- ${end}`\n }\n };\n}).filter(f => f !== null);\n\nreturn parsedFragments;"
}
},
{
"id": "e5f6a7b8-c9d0-1234-ef12-345678901234",
"name": "Create Subtitles",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1,
"position": [
1450,
200
],
"parameters": {
"model": {
"__rl": true,
"value": "gemini-2.0-flash-exp",
"mode": "list",
"cachedResultName": "gemini-2.0-flash-exp"
},
"options": {
"systemMessage": "You are an expert subtitle creator. Convert the provided text into SRT subtitle format.\n\nRules:\n- Use ~140 words per minute timing\n- Each subtitle should be 1-2 lines maximum\n- Start from 00:00:00,000\n- Use proper SRT format:\n1\n00:00:00,000 --> 00:00:03,000\nFirst subtitle text\n\n2\n00:00:03,000 --> 00:00:06,000\nSecond subtitle text\n\nProvide ONLY the SRT content, nothing else."
},
"prompt": "=Convert this text into SRT subtitle format at ~140 words per minute:\n\n{{ $json.content }}"
}
},
{
"id": "f6a7b8c9-d0e1-2345-f123-456789012345",
"name": "Convert to SRT",
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
1750,
200
],
"parameters": {
"mode": "jsonToText",
"options": {
"fileName": "=fragment_{{ $json.fragmentIndex }}.srt",
"mimeType": "text/plain"
},
"jsonToText": {
"inputDataFieldName": "={{ $('Create Subtitles').item.json.message.content }}"
}
}
},
{
"id": "a7b8c9d0-e1f2-3456-1234-567890123456",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1450,
400
],
"parameters": {
"mode": "manual",
"assignments": {
"assignments": [
{
"id": "b8c9d0e1-f2a3-4567-2345-678901234567",
"name": "formattedText",
"value": "=Fragment {{ $json.fragmentIndex }}\nTimecode: {{ $json.timecodeRange }}\n\n{{ $json.content }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "b8c9d0e1-f2a3-4567-2345-678901234567",
"name": "Convert to TXT",
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
1750,
400
],
"parameters": {
"mode": "jsonToText",
"options": {
"fileName": "=timecodes_{{ $json.fragmentIndex }}.txt",
"mimeType": "text/plain"
},
"jsonToText": {
"inputDataFieldName": "={{ $json.formattedText }}"
}
}
},
{
"id": "c9d0e1f2-a3b4-5678-3456-789012345678",
"name": "Gmail",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2050,
200
],
"parameters": {
"operation": "send",
"sendTo": "={{ $('Webhook').item.json.body.email || 'user@example.com' }}",
"subject": "=Fragments - {{ $('Webhook').item.json.body.title }}",
"message": "=Please find attached the SRT subtitle file for fragment {{ $json.fragmentIndex }}.\n\nTimecode: {{ $('Split Fragments').item.json.timecodeRange }}\n\nThis fragment was selected as one of the most engaging moments from the transcript.",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "data"
}
]
}
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Fragment Selection",
"type": "main",
"index": 0
}
]
]
},
"Fragment Selection": {
"main": [
[
{
"node": "Get Fragment Text",
"type": "main",
"index": 0
}
]
]
},
"Get Fragment Text": {
"main": [
[
{
"node": "Split Fragments",
"type": "main",
"index": 0
}
]
]
},
"Split Fragments": {
"main": [
[
{
"node": "Create Subtitles",
"type": "main",
"index": 0
},
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Create Subtitles": {
"main": [
[
{
"node": "Convert to SRT",
"type": "main",
"index": 0
}
]
]
},
"Convert to SRT": {
"main": [
[
{
"node": "Gmail",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Convert to TXT",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
MacWhisper Transcript Processor. Uses googleGemini, gmail. Webhook trigger; 9 nodes.
Source: https://github.com/AI-agents-incubator/n8n-pilot/blob/main/tests/acceptance/output/macwhisper-generated.json — 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.
This workflow captures new leads via webhook, enriches and scores them with Apollo and Google Gemini, logs everything in Google Sheets, and automates outreach, reply handling, follow-ups, meeting prep
This workflow receives income and financial-goal data via webhook, stores enriched metrics in Google Sheets, generates a tailored plan with Google Gemini, converts it to a PDF via PDFShift, uploads it
When a buyer or seller leaves a voicemail, this workflow transcribes it automatically, qualifies their intent using Gemini AI, sends an instant SMS acknowledgment, and alerts the agent for Hot leads —
Master. Uses gmail, googleGemini, googleCloudStorage. Webhook trigger; 19 nodes.
Monitor LINE activity and Gemini sentiment with Google Sheets for elderly care. Uses googleGemini, gmail, googleSheets. Webhook trigger; 15 nodes.