This workflow corresponds to n8n.io template #13759 — we link there as the canonical source.
This workflow follows the Agent → Airtable 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": "MxHLOPQIt80lQZs8",
"name": "Upload reels with AI caption from Google Sheets",
"tags": [],
"nodes": [
{
"id": "e9950b30-dae2-4bad-ae13-deff2f161f50",
"name": "Generate Caption with DeepSeek",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1664,
944
],
"parameters": {
"text": "=Generate an engaging Instagram caption for a video titled \"{{ $('Get Rows').item.json.NAME}}\" \n\nHere's what to include:\n- 2-4 engaging sentences about video based on title \n- 3-5 relevant hashtags based on the video title \n- A clear call-to-action encouraging to check link in bio.\n\nPlease keep the total caption under 150 characters.\n\nYou are skilled at writing clear, engaging, and detailed captions based on just a file name. Help viewers understand and appreciate the post. The tone should be relatable and suitable for an Instagram audience. Avoid using too many whimsical words or excessive adjectives. Focus on giving more details and facts to educate viewers.",
"options": {},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "1bd06991-d24c-4dca-b450-4aad17d080a0",
"name": "Store Caption in Airtable",
"type": "n8n-nodes-base.airtable",
"disabled": true,
"position": [
1984,
944
],
"parameters": {
"base": {
"__rl": true,
"mode": "id",
"value": ""
},
"table": {
"__rl": true,
"mode": "id",
"value": ""
},
"columns": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {
"typecast": false
},
"operation": "create"
},
"typeVersion": 2.1
},
{
"id": "3d2c8eb2-7c71-4507-b1be-3326a00ed31e",
"name": "Publish Reel to Instagram",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
3136,
944
],
"parameters": {
"edge": "media_publish",
"node": " ",
"options": {
"queryParameters": {
"parameter": [
{
"name": "creation_id",
"value": "={{ $json.id }}"
}
]
}
},
"graphApiVersion": "v22.0",
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "55027c1f-90b6-4ef2-bc34-3b93eb8067d6",
"name": "Check Video Processing Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
2688,
880
],
"parameters": {
"url": "=https://graph.facebook.com/v21.0/{{ $('Create container').item.json.id }}?fields=status_code,status",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "facebookGraphApi"
},
"typeVersion": 4.3
},
{
"id": "e24bab82-84ae-48a9-a2e4-913471e70c80",
"name": "Is Video Processed?",
"type": "n8n-nodes-base.if",
"position": [
2912,
944
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8ab5eeec-4edd-4796-8f54-4c7cfccf99e9",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status_code }}",
"rightValue": "FINISHED"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "75cf6c86-22df-4230-852f-8d6840708542",
"name": "Wait for Video Processing",
"type": "n8n-nodes-base.wait",
"position": [
2464,
944
],
"parameters": {
"amount": 90
},
"typeVersion": 1.1
},
{
"id": "0b5e4fb5-e167-41b9-b6aa-98672c84d03b",
"name": "Trigger: New Row in Sheet",
"type": "n8n-nodes-base.googleSheetsTrigger",
"disabled": true,
"position": [
96,
848
],
"parameters": {
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 1
},
{
"id": "53021691-af78-446e-9d1c-24f7fd9a45ac",
"name": "Trigger: Every 12 Hours",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
96,
1040
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 12
}
]
}
},
"typeVersion": 1.3
},
{
"id": "8369241c-2538-4c06-adac-b8a073457f28",
"name": "DeepSeek Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
"position": [
1664,
1232
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "12dde15e-f96c-4eb5-8851-3cdd4248cdcb",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 640,
"height": 624,
"content": "# Upload reels with AI Caption from Google Sheets\n\nThis n8n workflow template automates the entire process of publishing Instagram Reels from content stored in Google Sheets and Google Drive. It's designed for content creators, social media managers, and businesses who maintain a content calendar in spreadsheets and need automated publishing with AI-generated captions.\n\n## How It Works\n\n1. **Trigger**: Runs every 12 hours (or when new rows are added)\n2. **Fetch Content**: Retrieves unposted videos from spreadsheet\n3. **Process Video**: Downloads from Drive and adds custom overlays with FFmpeg\n4. **Generate Caption**: Uses AI to create engaging Instagram captions\n5. **Publish**: Uploads to Instagram and marks as posted\n\n## Setup Steps\n\n- Configure Google Sheets connection and document ID\n- Set up Google Drive access for video files\n- Add Instagram/Facebook Graph API credentials\n- Optional: Configure SSH and Airtable for advanced features"
},
"typeVersion": 1
},
{
"id": "fade781f-50de-47d9-b25d-6e9a9d5c618d",
"name": "## 1. Trigger Phase",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
736
],
"parameters": {
"color": 7,
"width": 352,
"height": 496,
"content": "## Runs every 12 hours or when new rows added to sheet"
},
"typeVersion": 1
},
{
"id": "525aa3a1-1157-4cce-9f64-e2b6a71ca927",
"name": "## 2. Content Preparation",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
784
],
"parameters": {
"color": 7,
"width": 1112,
"height": 400,
"content": "## Download video \u2192 Save file \u2192 Process with FFmpeg \u2192 Load processed video \u2192 Upload via SSH"
},
"typeVersion": 1
},
{
"id": "85fcc9c6-baad-4919-a8da-051839d333fa",
"name": "## 3. Caption Generation",
"type": "n8n-nodes-base.stickyNote",
"position": [
1472,
784
],
"parameters": {
"color": 7,
"width": 688,
"height": 400,
"content": "## Generate AI caption with DeepSeek \u2192 Store in Airtable"
},
"typeVersion": 1
},
{
"id": "43decc38-9a35-4963-9dd7-b63aad24849d",
"name": "## 4. Publishing",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
784
],
"parameters": {
"color": 7,
"width": 1096,
"height": 400,
"content": "## Create media container \u2192 Wait \u2192 Check status \u2192 Publish to Instagram"
},
"typeVersion": 1
},
{
"id": "6fd42f41-81cd-40d6-b74c-20e467b7bd1c",
"name": "## 5. Cleanup",
"type": "n8n-nodes-base.stickyNote",
"position": [
3312,
784
],
"parameters": {
"color": 7,
"width": 394,
"height": 400,
"content": "## Mark as posted and clean videos"
},
"typeVersion": 1
},
{
"id": "34573a90-81bb-4815-ac25-d3d1f26a27dc",
"name": "Process Video with FFmpeg",
"type": "n8n-nodes-base.executeCommand",
"position": [
1024,
944
],
"parameters": {
"command": "=ffmpeg -y -i /data/{{ $execution.id }}_input.mp4 -vf \"scale=1080:1920\" -c:v libx264 -pix_fmt yuv420p /data/{{ $execution.id }}_output.mp4"
},
"typeVersion": 1
},
{
"id": "6be11af9-8b93-4e99-b3ed-4c2808921b16",
"name": "Upload to Server via SSH",
"type": "n8n-nodes-base.ssh",
"position": [
1504,
944
],
"parameters": {
"path": "/var/www/html/uploads/",
"options": {},
"resource": "file",
"authentication": "privateKey"
},
"credentials": {
"sshPrivateKey": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "fbbf2f09-f739-4ddc-90c2-e4b905859a63",
"name": "Fetch Unposted Videos",
"type": "n8n-nodes-base.googleSheets",
"position": [
384,
944
],
"parameters": {
"sheetName": {
"__rl": true,
"mode": "name",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "id",
"value": ""
}
},
"typeVersion": 4.7
},
{
"id": "6db65556-dd93-406b-943d-bceba78faea7",
"name": "Download Video from Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
592,
944
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "url",
"value": "={{ $json.LINK }}"
},
"options": {},
"operation": "download"
},
"typeVersion": 3
},
{
"id": "21ad8e54-2a54-4b48-9865-7bb55193cf3f",
"name": "Save Downloaded File",
"type": "n8n-nodes-base.readWriteFile",
"position": [
816,
944
],
"parameters": {
"options": {},
"fileName": "=/tmp/{{ $execution.id }}_input.mp4",
"operation": "write"
},
"typeVersion": 1
},
{
"id": "ac69610f-d43a-4ebf-94b1-33e7a85191eb",
"name": "Load Processed Video",
"type": "n8n-nodes-base.readWriteFile",
"position": [
1264,
944
],
"parameters": {
"options": {},
"fileSelector": "=/tmp/{{ $execution.id }}_output.mp4"
},
"typeVersion": 1
},
{
"id": "f31d0794-fd0a-4b1b-9487-0322a25b4aa5",
"name": "Create Instagram Media Container",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
2240,
944
],
"parameters": {
"edge": "media",
"node": " ",
"hostUrl": "graph-video.facebook.com",
"options": {
"queryParameters": {
"parameter": [
{
"name": "media_type",
"value": "REELS"
},
{
"name": "caption",
"value": "={{ $('AI Agent').item.json.output }}"
}
]
}
},
"graphApiVersion": "v22.0",
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "4ddb4cbd-0d0a-4f2d-a9a2-9a4fb76e18d6",
"name": "Mark as Posted",
"type": "n8n-nodes-base.googleSheets",
"position": [
3328,
944
],
"parameters": {
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "id",
"value": ""
}
},
"typeVersion": 4.7
},
{
"id": "5430a5a9-f8e9-48e3-9794-8de5c8b3fdb5",
"name": "Execute a command",
"type": "n8n-nodes-base.ssh",
"position": [
3552,
944
],
"parameters": {
"command": "rm -f /var/www/html/uploads/*",
"authentication": "privateKey"
},
"credentials": {
"sshPrivateKey": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "54560e78-454f-4692-8f61-1cd8886370e0",
"connections": {
"Mark as Posted": {
"main": [
[
{
"node": "Execute a command",
"type": "main",
"index": 0
}
]
]
},
"DeepSeek Chat Model": {
"ai_languageModel": [
[
{
"node": "Generate Caption with DeepSeek",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Is Video Processed?": {
"main": [
[
{
"node": "Publish Reel to Instagram",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait for Video Processing",
"type": "main",
"index": 0
}
]
]
},
"Load Processed Video": {
"main": [
[
{
"node": "Upload to Server via SSH",
"type": "main",
"index": 0
}
]
]
},
"Save Downloaded File": {
"main": [
[
{
"node": "Process Video with FFmpeg",
"type": "main",
"index": 0
}
]
]
},
"Fetch Unposted Videos": {
"main": [
[
{
"node": "Download Video from Drive",
"type": "main",
"index": 0
}
]
]
},
"Trigger: Every 12 Hours": {
"main": [
[
{
"node": "Fetch Unposted Videos",
"type": "main",
"index": 0
}
]
]
},
"Upload to Server via SSH": {
"main": [
[
{
"node": "Generate Caption with DeepSeek",
"type": "main",
"index": 0
}
]
]
},
"Download Video from Drive": {
"main": [
[
{
"node": "Save Downloaded File",
"type": "main",
"index": 0
}
]
]
},
"Process Video with FFmpeg": {
"main": [
[
{
"node": "Load Processed Video",
"type": "main",
"index": 0
}
]
]
},
"Publish Reel to Instagram": {
"main": [
[
{
"node": "Mark as Posted",
"type": "main",
"index": 0
}
]
]
},
"Store Caption in Airtable": {
"main": [
[
{
"node": "Create Instagram Media Container",
"type": "main",
"index": 0
}
]
]
},
"Trigger: New Row in Sheet": {
"main": [
[
{
"node": "Fetch Unposted Videos",
"type": "main",
"index": 0
}
]
]
},
"Wait for Video Processing": {
"main": [
[
{
"node": "Check Video Processing Status",
"type": "main",
"index": 0
}
]
]
},
"Check Video Processing Status": {
"main": [
[
{
"node": "Is Video Processed?",
"type": "main",
"index": 0
}
]
]
},
"Generate Caption with DeepSeek": {
"main": [
[
{
"node": "Store Caption in Airtable",
"type": "main",
"index": 0
}
]
]
},
"Create Instagram Media Container": {
"main": [
[
{
"node": "Wait for Video Processing",
"type": "main",
"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.
sshPrivateKey
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow template automates the entire process of publishing Instagram Reels from content stored in Google Sheets and Google Drive. It's designed for content creators, social media managers, and businesses who maintain a content calendar in spreadsheets and need…
Source: https://n8n.io/workflows/13759/ — 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 is perfect for digital content creators, marketers, and social media managers who regularly create engaging short-form videos featuring inspirational or motivational quotes. While the wo
Credentials-Setup. Uses twitter, reddit, googleDocs, googleDrive. Event-driven trigger; 43 nodes.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This n8n workflow automates the process of uploading video and image advertisements to Meta Ads Manager via the Meta Graph API (Facebook Ads) directly from Google Sheets and Google Drive. The workflow
• Downloads videos/music from YouTube using yt-dlp • Merges assets with dynamic text overlays • Automatically uploads to YouTube as Shorts (9:16 format) • Tracks everything in Google Sheets Install yt