n8n tutorial - Lesson 18: Upload Videos to YouTube Automatically with n8n

Hi everyone, in this post I'll walk you through building a complete n8n YouTube upload automation pipeline that pulls videos from Google Drive, matches metadata from a Google Sheet, uploads to YouTube, updates the Sheet, and archives the file — all in 8 nodes. This is Session 18 of the n8n Workflow Automation Tutorial series, and it covers one of the most practical patterns you'll use: end-to-end binary file handling from Drive to YouTube.

How to do:

Step 1 — Set Up Google Drive Folders and Expand the Metadata Sheet

Before building any nodes, prepare the two Drive folders and extend your tracking Sheet with three new columns.
  1. Create a Drive folder named T5-Pending-Upload — this is where you drop video files before running the workflow. Note the folder ID from the URL (e.g., 1uCnBkM2k4ar40UulQ0UzSMMDgfSQwPkw).
  2. Create a second Drive folder named T5-Uploaded — the workflow moves files here after a successful upload to prevent duplicates. Note its folder ID (e.g., 17a9D1f_Tp5rF3XPSWJh146ED5l-EasNE).
  3. Open your Google Sheet T5-Video-Metadata and add three new columns:
    • Column G: youtube_video_id (Plain Text)
    • Column H: upload_status — values will be pending, uploaded, or failed
    • Column I: uploaded_at — ISO timestamp filled in by the workflow
  4. Upload at least one test video file into T5-Pending-Upload and set its upload_status in the Sheet to pending.

Step 2 — Add a Manual Trigger Node

This workflow is designed to run on-demand, not on a schedule, so a Manual Trigger is the correct starting node.
  1. In n8n, create a new workflow named T5-B6-Video-Uploader.
  2. Add a Manual Trigger node as the first node. Do not toggle the workflow to Active — you will run it manually each time you have a new video to upload.

Note — Keeping this workflow inactive prevents accidental runs. Because each upload costs 1,600 YouTube API quota units, an unintended execution wastes your daily quota fast (default quota = 10,000 units, roughly 6 uploads per day).

Step 3 — List Pending Videos from Drive (with File Types Fix)

Connect a Google Drive node to search for files in the pending folder — but use the correct file type setting to avoid a common MIME mismatch bug.
  1. Add a Google Drive node, set the operation to Search Files.
  2. Set Drive to your account and set the Folder to T5-Pending-Upload (use the folder ID).
  3. For File Types, select Allnot Video.

Production tip — The newer n8n UI exposes a Video option directly in the File Types dropdown, which looks convenient. However, when a video file is uploaded to Drive from an external source, Drive may record a non-standard MIME type, causing the Video filter to miss it entirely. Set File Types to All and filter by extension in the next Code node instead.

Step 4 — Fetch All Sheet Metadata

Pull the full contents of your metadata Sheet so the next node can match filenames to their metadata rows.
  1. Add a Google Sheets node, set the operation to Get Row(s).
  2. Point it to T5-Video-Metadata Sheet.
  3. Enable Always Output Data — this ensures the node passes data downstream even when no rows are found, preventing the workflow from silently stopping.

Tip — Always Output Data is used here as a reference lookup node, not as a trigger. You want all rows fetched every run so the Code node can build a lookup map from them.

Step 5 — Match Filenames with a Code Node

This is the core logic step: match each Drive file to its Sheet row, filter out already-uploaded videos, and merge the data into a single output item per video.
  1. Add a Code node named Match Filename.
  2. Write code that performs these actions in sequence:
    • Build a titleMap object from the Sheet rows: key = video_title, value = the full Sheet row object.
    • For each Drive file, strip the .mp4 extension from the filename to get the base title.
    • Look up that base title in titleMap.
    • Filter out any items where upload_status is not pending.
    • Output a merged object containing both Drive file info (especially the Drive file ID) and the Sheet metadata fields.
  3. This lookup pattern is O(1) per file — much faster than looping through Sheet rows for every Drive file.

Note — Filtering upload_status !== 'pending' early here is the idempotency guard for this workflow. Files already marked uploaded will never be sent downstream, preventing duplicate YouTube uploads.

Step 6 — Download the Video File from Drive

Download the matched video as binary data so it can be passed directly to the YouTube Upload node.
  1. Add a Google Drive node, set the operation to Download File.
  2. Set the File ID field using a cross-node expression referencing the previous Code node: ${'Match Filename'}.item.json.id (drag from the input panel to get the exact expression).
  3. After execution, verify the output contains both:
    • JSON passthrough fields (Drive metadata)
    • A binary field named data containing the video file bytes

Tip — The Drive Download node automatically names the binary output field data. Remember this name — you must enter exactly data in the YouTube Upload node's Input Binary Field setting in the next step.

Step 7 — Upload the Video to YouTube

Use n8n's native YouTube node to upload the binary video file. Two fields are mandatory and will cause the node to fail if left blank.
  1. Add a YouTube node, set the operation to Upload a Video.
  2. Configure these fields:
    • Title: use a cross-node expression referencing Match Filename — e.g., ${'Match Filename'}.item.json.video_title
    • Region Code: set to your target region (e.g., VN for Vietnam) — this field is mandatory
    • Category: select a category (e.g., People & Blogs) — this field is mandatory
    • Input Binary Field: enter data (matches the Drive Download output)
    • Privacy Status: set to Unlisted
  3. Under Additional Fields, add Description and reference it from Match Filename as well.
  4. Run a test upload and check the output JSON — the uploaded video's ID is returned in a field named uploadId, not id.
  5. Verify the video appears on YouTube Studio as an Unlisted video — do not trust the node output alone.

Production tip — The n8n YouTube Upload node returns uploadId as a custom field name, which differs from the standard YouTube Data API response field id. If you reference $json.id in downstream nodes, it will return undefined. Always paste and inspect the actual node output before writing cross-node expressions that reference it.

Step 8 — Mark the Sheet Row as Uploaded

Update the Sheet row to record the YouTube video ID, set the status to uploaded, and log the timestamp.
  1. Add a Google Sheets node, set the operation to Update Row.
  2. Set Match Column to video_title — this identifies which row to update.
  3. Set the following column values:
    • youtube_video_id: ${'Upload to YouTube'}.item.json.uploadId
    • upload_status: uploaded
    • uploaded_at: $now.toISO()
  4. After running, confirm the Sheet row shows all three new column values filled in correctly.

Step 9 — Move the File to the Uploaded Folder

Move the source file from T5-Pending-Upload to T5-Uploaded to archive it and prevent it from being picked up in future runs.
  1. Add a Google Drive node, set the operation to Move File.
  2. Set File ID using the cross-node expression from Match Filename: the Drive file ID field.
  3. Set Destination Folder to the T5-Uploaded folder ID (17a9D1f_Tp5rF3XPSWJh146ED5l-EasNE).
  4. After running, verify:
    • T5-Pending-Upload folder is empty
    • T5-Uploaded folder contains the moved file

Note — This move step is the second idempotency layer in this workflow. Even if the Sheet status check in the Code node fails for any reason, the file being absent from T5-Pending-Upload means the workflow will not pick it up again on the next manual run.

Step 10 — Run the Full End-to-End Test

With all 8 nodes connected, do a complete pipeline test with one real video file.
  1. Confirm one video file is in T5-Pending-Upload and its Sheet row has upload_status = pending.
  2. Click Execute Workflow on the Manual Trigger.
  3. Check each node's output in sequence to confirm data flows correctly through all 8 nodes.
  4. Verify three outcomes:
    • YouTube Studio shows the video as Unlisted
    • The Sheet row has upload_status = uploaded, a valid youtube_video_id, and an uploaded_at timestamp
    • The file has moved from T5-Pending-Upload to T5-Uploaded

Key Lessons from This Session

  1. Drive File Types=Video is not reliable for externally uploaded files. Use File Types=All and filter by .mp4 extension in a Code node instead.
  2. The YouTube Upload node returns uploadId, not id. Always inspect the actual node output before referencing it in downstream expressions — do not assume standard API field names.
  3. Drive → YouTube binary handling follows a fixed pattern. Drive Download outputs binary in a field called data; set YouTube Upload's Input Binary Field to exactly data.
  4. YouTube Data API upload costs 1,600 quota units per upload. With the default 10,000 daily quota, you can upload approximately 6 videos per day before hitting the limit.
  5. Use two idempotency layers for upload pipelines. Filter by upload_status = pending in the Code node (layer 1) and move the file out of the source folder after upload (layer 2).
  6. Always verify uploads in YouTube Studio directly. Node output confirms the API accepted the request — Studio confirms the video actually exists on the channel.
  7. Cross-node expressions using $('Node Name') are essential in multi-branch pipelines. After the Download node, use $('Match Filename').item.json to reach metadata that is not in the immediately previous node's output.
  8. Always Output Data should be ON for reference lookup nodes. It prevents silent workflow halts when a lookup node returns no rows.

Conclusion:

In this n8n tutorial, you built a complete 8-node n8n YouTube upload automation pipeline covering Drive file search, metadata matching, binary file download, YouTube upload, Sheet status tracking, and file archiving — all triggered manually on demand. The key patterns here — binary passthrough, cross-node expressions, and dual idempotency layers — are reusable in any file-processing workflow you build as you advance through this n8n workflow automation series. The next session focuses on building a Weekly Digest workflow that pulls data from four Sheets, generates an AI summary, and sends it to Telegram every Sunday.

If you have any questions, feel free to leave a comment below. Thank you!

Tags: n8n youtube upload automation, n8n tutorial, n8n workflow automation, google drive to youtube n8n, n8n binary file handling, youtube api quota n8n, n8n google sheets automation, n8n upload video workflow

Maybe you are interested!