This workflow corresponds to n8n.io template #5866 — 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 →
{
"id": "e9QKXG6OxvBeE8MA",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "My workflownn",
"tags": [],
"nodes": [
{
"id": "98d6c238-8ab3-4814-8b95-cc9e201e9e0a",
"name": "On form submission",
"type": "n8n-nodes-base.formTrigger",
"position": [
0,
0
],
"parameters": {
"options": {},
"formTitle": "summarize youtube videos from transcript for social media",
"formFields": {
"values": [
{
"fieldLabel": "videoUrl",
"placeholder": "full video url",
"requiredField": true
},
{
"fieldLabel": "language",
"placeholder": "English",
"requiredField": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d9076f8d-d9cd-47da-832c-2ed605675779",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2540,
460
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2f2e8e76-6666-441a-854f-0d108a8f26d1",
"name": "Google Docs",
"type": "n8n-nodes-base.googleDocs",
"position": [
3460,
-140
],
"parameters": {
"actionsUi": {
"actionFields": [
{
"text": "={{ $json.summary }}",
"action": "insert"
}
]
},
"operation": "update",
"documentURL": "",
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "ab9dd3f4-f2aa-4d9f-aef7-72420a1e53f8",
"name": "Mapper",
"type": "n8n-nodes-base.set",
"position": [
420,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a2486ac7-c29c-419e-9cfc-753701723510",
"name": "videoUrl",
"type": "string",
"value": "={{ $json.videoUrl }}"
},
{
"id": "8032743b-0266-488b-83f3-d0a42f35c1e0",
"name": "language",
"type": "string",
"value": "={{ $json.language }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ca6d25dd-0950-4ef2-9b2d-2f105d72fb35",
"name": "Formator",
"type": "n8n-nodes-base.code",
"position": [
1580,
20
],
"parameters": {
"jsCode": "const rawArray = $input.first().json.data;\n\nconsole.log(\"Raw Array Data:\", rawArray); // Log the raw input data\n\n// Step 1: Parse the outer JSON to access the inner data\nlet parsedData;\ntry {\n parsedData = JSON.parse(rawArray);\n console.log(\"Parsed Data:\", parsedData); // Log the parsed data\n} catch (e) {\n console.log(\"Error Parsing Outer Data:\", e);\n return [{\n json: {\n chatInput: \"Failed to parse outer JSON data.\"\n }\n }];\n}\n\n// Step 2: Extract the actual transcript data from the 'data' field\nconst innerData = parsedData.data;\n\n// Step 3: Decode Unicode characters in the string\nconst decodedData = decodeURIComponent(innerData.replace(/\\\\u([0-9A-Fa-f]{4})/g, (match, p1) => {\n return String.fromCharCode(parseInt(p1, 16));\n}));\n\nconsole.log(\"Decoded Data:\", decodedData); // Log the decoded data\n\n// Step 4: Check if the decoded data is a valid transcript\nif (!decodedData || decodedData.trim() === \"\") {\n console.log(\"Invalid or empty transcript data.\");\n return [{\n json: {\n chatInput: \"No valid transcript found.\"\n }\n }];\n}\n\n// Step 5: Return the final transcript text\nreturn [{\n json: {\n chatInput: decodedData\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "7cf36479-c6a8-4763-b691-72d5c03a60f8",
"name": "Optimizer",
"type": "n8n-nodes-base.code",
"position": [
2860,
-80
],
"parameters": {
"jsCode": "const inputText = $input.first().json.output;\n\nfunction getFieldValue(text, field) {\n // Updated to stop at \"---\" or end of string, instead of a non-whitespace line\n const regex = new RegExp(`${field}:\\\\s*([\\\\s\\\\S]*?)(?=\\\\n---|$)`, 'i');\n const match = text.match(regex);\n return match ? match[1].trim() : '';\n}\n\nconst summary = getFieldValue(inputText, '\ud83c\udfac \\\\*\\\\*Summary\\\\*\\\\*');\n\nreturn [{\n json: {\n summary\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "ac71fe03-898c-4cf3-9c98-f8b8f9e81346",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2300,
-80
],
"parameters": {
"options": {
"systemMessage": "=You are a helpful assistant that summarizes YouTube video transcripts. Given a full transcript in {{ $('Mapper').item.json.language }}, summarize the main points, topics, and tone of the video in a concise and natural manner. The summary should be provided in the same language as the transcript. Format your response like this:\n\n---\n\ud83c\udfac **Summary**: \n- [Main idea 1] \n- [Main idea 2] \n- [Optional tone, style, or genre] \n---\n "
}
},
"typeVersion": 1.7
},
{
"id": "16681c25-5398-48f5-abf6-a02d7d4be8f2",
"name": "YouTube Transcript AI",
"type": "n8n-nodes-base.httpRequest",
"position": [
880,
40
],
"parameters": {
"url": "https://youtube-transcriptor-pro.p.rapidapi.com/yt/index.php",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "=videoUrl",
"value": "={{ $json.videoUrl }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "x-rapidapi-host",
"value": "youtube-transcriptor-pro.p.rapidapi.com"
},
{
"name": "x-rapidapi-key"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "3de6995f-d44e-41fe-8cee-ef38e442023f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-980,
-680
],
"parameters": {
"width": 700,
"height": 1060,
"content": "# **YouTube Transcript Summarization Workflow**\n\nThis n8n workflow automates the process of summarizing YouTube video transcripts. It retrieves a video's transcript, formats it, and generates a concise summary in the desired language, which is then stored in a Google Doc for easy sharing.\n\n---\n\n### **Workflow Steps:**\n\n1. **Form Submission (On form submission)** \n - Collects `videoUrl` (YouTube link) and `language` (desired summary language).\n\n2. **Mapping Data (Mapper)** \n - Assigns form data to variables (`videoUrl` and `language`).\n\n3. **Retrieve Transcript (YouTube Transcript AI)** \n - Calls the YouTube Transcript API via RapidAPI to fetch the video transcript.\n\n4. **Format Transcript (Formator)** \n - Decodes and formats the transcript data for further use.\n\n5. **Generate Summary (AI Agent1)** \n - Uses Google Gemini (PaLM model) to generate a summary in the specified language.\n\n6. **Extract and Optimize (Optimizer)** \n - Extracts the summary from the AI response.\n\n7. **Update Google Docs (Google Docs)** \n - Inserts the generated summary into a predefined Google Document.\n\n---\n\n### **Key Features:**\n- **Language Flexibility:** Generates summaries in the specified language.\n- **Automated Process:** From transcript retrieval to Google Docs update, everything is automated.\n"
},
"typeVersion": 1
},
{
"id": "4904624a-f8b2-49d4-8a57-51b35b9e4e0c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-180,
-280
],
"parameters": {
"width": 380,
"height": 440,
"content": "#### 1. **Form Submission (On form submission)**\n- **Purpose:** \n This node collects the YouTube video URL and the desired language for the summary through a form submission.\n- **Details:**\n - **Inputs:**\n - `videoUrl`: Full URL of the YouTube video.\n - `language`: The language for the summary (e.g., English, Spanish, etc.).\n- **Outcome:** \n Passes the form data to the next node (`Mapper`) for further processing.\n"
},
"typeVersion": 1
},
{
"id": "be467ebe-553d-4b95-a56b-7ccf5a717b76",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
260,
-280
],
"parameters": {
"width": 360,
"height": 440,
"content": "#### 2. **Mapping Data (Mapper)**\n- **Purpose:** \n Maps the data from the form into variables, preparing them for the following nodes.\n- **Details:**\n - **Outputs:**\n - `videoUrl`: Assigned from the form.\n - `language`: Assigned from the form.\n- **Outcome:** \n Prepares and passes the form data to the **YouTube Transcript AI** node for API interaction.\n"
},
"typeVersion": 1
},
{
"id": "9e3ce6b1-e419-47e7-9e1b-d21789b384eb",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
-280
],
"parameters": {
"width": 600,
"height": 440,
"content": "#### 3. **Retrieve Transcript (YouTube Transcript AI)**\n- **Purpose:** \n This node sends an API request to the **YouTube Transcript API** to fetch the transcript of the YouTube video provided.\n- **Details:**\n - **Inputs:** \n - `videoUrl`: The URL provided in the form.\n - **API Request:** \n - The node makes a `POST` request to `https://youtube-transcriptor-pro.p.rapidapi.com/yt/index.php`.\n - It sends the `videoUrl` in the request body.\n- **Outcome:** \n The API returns the raw transcript text, which will be passed to the next node for decoding and formatting.\n"
},
"typeVersion": 1
},
{
"id": "a3fb823e-9eb9-447b-b725-2f471294a64a",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1320,
-260
],
"parameters": {
"width": 620,
"height": 400,
"content": "#### 4. **Format Transcript (Formator)**\n- **Purpose:** \n This node processes and formats the transcript data retrieved from the API to ensure it is usable for the AI model.\n- **Details:**\n - **Operations:**\n - Decodes any Unicode characters from the transcript using JavaScript.\n - Checks if the transcript is empty or invalid.\n - **Outcome:** \n - If the transcript is valid, it is returned in a clean format to the next node.\n - If the transcript is invalid, a fallback message is returned instead."
},
"typeVersion": 1
},
{
"id": "a1f79939-cd91-4076-8bfe-7c7e40c49f3f",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
-580
],
"parameters": {
"width": 400,
"height": 720,
"content": "#### 5. **Generate Summary (AI Agent1)**\n- **Purpose:** \n This node uses the **Google Gemini (PaLM model)** to generate a summary from the cleaned transcript text in the specified language.\n- **Details:**\n - **Inputs:**\n - The formatted transcript from the **Formator** node.\n - The `language` variable from the form submission.\n - **Operations:**\n - The model processes the transcript and generates a summary, formatted according to the prompt that ensures the summary is concise and relevant.\n - **Outcome:** \n - The AI generates a concise summary in the specified language, which will be extracted in the next node.\n\n"
},
"typeVersion": 1
},
{
"id": "ac2d887f-2371-4bf1-a054-43df1bd0c090",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2700,
-580
],
"parameters": {
"width": 360,
"height": 700,
"content": "#### 6. **Extract and Optimize (Optimizer)**\n- **Purpose:** \n This node extracts the relevant summary section from the AI response and optimizes it for output.\n- **Details:**\n - **Operations:**\n - Extracts the summary portion labeled `\"\ud83c\udfac **Summary**\"` from the AI's response using a regular expression.\n - **Outcome:** \n - The clean, concise summary is extracted and prepared for insertion into Google Docs.\n\n"
},
"typeVersion": 1
},
{
"id": "cca97d98-4d02-4298-b053-7945ee149794",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
3260,
-460
],
"parameters": {
"width": 560,
"height": 480,
"content": "#### 7. **Update Google Docs (Google Docs)**\n- **Purpose:** \n This node inserts the final summary into a predefined **Google Document**.\n- **Details:**\n - **Inputs:** \n - The summary generated by the AI model.\n - **Operations:**\n - Uses Google Docs API to update the document specified by the `documentURL`.\n - The summary is inserted into the document, making it available for sharing or editing.\n- **Outcome:** \n The summary is now available in the Google Doc and can be accessed or shared as needed.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "fff226c0-4d72-46bc-93f5-4b284a89dee0",
"connections": {
"Mapper": {
"main": [
[
{
"node": "YouTube Transcript AI",
"type": "main",
"index": 0
}
]
]
},
"Formator": {
"main": [
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"AI Agent1": {
"main": [
[
{
"node": "Optimizer",
"type": "main",
"index": 0
}
]
]
},
"Optimizer": {
"main": [
[
{
"node": "Google Docs",
"type": "main",
"index": 0
}
]
]
},
"On form submission": {
"main": [
[
{
"node": "Mapper",
"type": "main",
"index": 0
}
]
]
},
"YouTube Transcript AI": {
"main": [
[
{
"node": "Formator",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}
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.
googleApigooglePalmApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automates the process of: Retrieving YouTube Video Transcripts: It fetches the transcript for any YouTube video URL provided using the YouTube Transcript API from RapidAPI. Generating a Concise Summary in Any Language: The workflow uses Google Gemini (PaLM) to…
Source: https://n8n.io/workflows/5866/ — 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 automates the entire UX research planning process — from gathering context to delivering a ready-to-share Google Doc report. Built for UX researchers and designers, it combines AI-powere
This workflow is a content multiplier. Provide a single video topic via a form, and it automatically researches, outlines, and writes two separate scripts: one for a YouTube Shorts and another for a L
Turn any YouTube video into a short, structured summary using AI — perfect for content creators, marketers, or social media managers.
How it Works
This automated workflow template transforms a single product image into a complete professional advertisement video with dynamic motion and custom soundtrack. Perfect for e-commerce businesses, market