使用Meta Graph API从Google表格自动化Instagram故事发布
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 19 个节点。主要使用 If, Set, Sort, Wait, HttpRequest 等节点。 使用Meta Graph API从Google表格自动化Instagram故事发布
前置要求
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
- •Facebook Graph API 凭证
使用的节点 (19)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "c86cef8a4808edf0fbf0288e26f131ef9d9ffb9633fdc6fda13cbd82ffdc8203",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ca8d9fd3-1e78-4e59-8038-c3e240e1a933",
"name": "📖 设置指南",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-112
],
"parameters": {
"width": 736,
"height": 384,
"content": "🎬 **Instagram Story 自动化模板**"
},
"notesInFlow": false,
"typeVersion": 1
},
{
"id": "2bc10b0a-49c6-438b-be8d-39dcecc210bc",
"name": "⚙️ 配置中心",
"type": "n8n-nodes-base.set",
"notes": "🔧 **SETUP REQUIRED** - Replace these values:\n\n• **IG_BUSINESS_ID**: Your Instagram Business Account ID\n → Find in Facebook Business Manager > Instagram Accounts\n → It's a long number (e.g., 17841450311185426)\n\n• **GRAPH_VERSION**: Facebook API version (usually v21.0 or newer)\n → Check https://developers.facebook.com/docs/graph-api\n\n• **SHEET_DOC_ID**: Your Google Sheet ID from the URL\n → Copy from: docs.google.com/spreadsheets/d/[THIS_PART]/edit\n\n• **SHEET_TAB_NAME**: The exact name of your sheet tab\n → Default: \"Instagram Videos\" (case-sensitive)\n\n⚠️ **Important**: Only change these values once during setup!",
"position": [
368,
352
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cfg-1",
"name": "IG_BUSINESS_ID",
"type": "string",
"value": "Your Instagram ID"
},
{
"id": "cfg-2",
"name": "GRAPH_VERSION",
"type": "string",
"value": "v23.0"
},
{
"id": "cfg-3",
"name": "SHEET_DOC_ID",
"type": "string",
"value": "Google Sheet ID (you can see it in the url of your sheet)"
},
{
"id": "cfg-4",
"name": "SHEET_TAB_NAME",
"type": "string",
"value": "Instagram Videos"
}
]
}
},
"notesInFlow": true,
"typeVersion": 3.4
},
{
"id": "9df8e039-b164-45e7-9555-58d8435e6c55",
"name": "🚀 手动启动",
"type": "n8n-nodes-base.manualTrigger",
"notes": "🎯 **FOR TESTING**\n\nClick the ▶️ button to test your workflow immediately.\n\n**When to use:**\n• First-time setup testing\n• Checking if credentials work\n• Testing new videos before scheduling\n\n**Non-technical tip**: Always test manually before enabling the schedule!",
"position": [
0,
288
],
"parameters": {},
"notesInFlow": true,
"typeVersion": 1
},
{
"id": "5f866e09-81ce-474f-965d-905f0bf7aae5",
"name": "⏰ 自动计划",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "🕐 **AUTOMATIC POSTING**\n\nCurrently set to run daily at 8:30 PM.\n\n**To change the time:**\n1. Click this node\n2. Adjust 'triggerAtHour' (0-23, where 20 = 8 PM)\n3. Adjust 'triggerAtMinute' (0-59)\n\n**Examples:**\n• 9:00 AM = Hour: 9, Minute: 0\n• 2:30 PM = Hour: 14, Minute: 30\n• 11:45 PM = Hour: 23, Minute: 45\n\n**Tip**: Choose times when your audience is most active!",
"position": [
0,
496
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 20,
"triggerAtMinute": 30
}
]
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "047a3a06-0dc3-4ab1-bdc9-7a39ab2c9c24",
"name": "📊 表格要求",
"type": "n8n-nodes-base.stickyNote",
"position": [
752,
-112
],
"parameters": {
"width": 480,
"height": 384,
"content": "📋 **Google Sheet 格式要求**"
},
"notesInFlow": false,
"typeVersion": 1
},
{
"id": "fa49cbfe-4746-4bad-acb7-f3db282bf84b",
"name": "📊 从表格获取视频",
"type": "n8n-nodes-base.googleSheets",
"notes": "📥 **CREDENTIAL SETUP REQUIRED**\n\n**What it does:** Reads all videos from your Google Sheet\n\n**Setup Steps:**\n1. Click the 'Credential for Google Sheets' dropdown\n2. Select 'Create New Credential'\n3. Choose 'Google Sheets OAuth2 API'\n4. Click 'Connect my account' and sign in\n5. Grant permissions to access your sheets\n\n**Troubleshooting:**\n• Error 403: Check sheet sharing permissions\n• 'Sheet not found': Verify SHEET_TAB_NAME in Config\n• No data: Ensure sheet has headers 'Path' and 'Posted'",
"position": [
800,
448
],
"parameters": {
"options": {},
"sheetName": {
"mode": "name",
"value": "={{ $json.SHEET_TAB_NAME }}"
},
"documentId": {
"mode": "list",
"value": "={{ $json.SHEET_DOC_ID }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "ZcotjdhaT5mLuV86",
"name": "Google Sheets account"
}
},
"notesInFlow": true,
"typeVersion": 4.5,
"alwaysOutputData": true
},
{
"id": "e98b5339-cd2a-454f-980d-6585c79a67af",
"name": "🎲 随机排序",
"type": "n8n-nodes-base.sort",
"notes": "🔀 **SMART SELECTION**\n\n**What it does:** Shuffles your video list randomly\n\n**Why this helps:**\n• Prevents always posting the first video\n• Creates variety in your content schedule\n• Ensures fair rotation of all videos\n\n**No setup needed** - this works automatically!\n\n**Note:** The workflow will still skip videos already marked as 'Posted'",
"position": [
1040,
448
],
"parameters": {
"type": "random"
},
"notesInFlow": true,
"typeVersion": 1
},
{
"id": "7f427af0-2f29-43c8-9fbf-59e8e0fe60fc",
"name": "🔄 处理每个视频",
"type": "n8n-nodes-base.splitInBatches",
"notes": "🔍 **VIDEO PROCESSOR**\n\n**What it does:** Checks each video one by one to find unposted content\n\n**How it works:**\n1. Takes the shuffled list\n2. Examines each video's 'Posted' status\n3. Finds the first video that hasn't been posted\n4. Processes only that video\n\n**No configuration needed** - this is automatic!\n\n**Result:** Only posts one new video per run",
"position": [
1280,
448
],
"parameters": {
"options": {}
},
"notesInFlow": true,
"typeVersion": 3
},
{
"id": "46174ca9-894c-47f2-9a3c-1a2176bcb8b0",
"name": "❓ 已发布检查",
"type": "n8n-nodes-base.if",
"notes": "🚦 **SMART FILTER**\n\n**What it does:** Checks if this video was already posted\n\n**Logic:**\n• **If Posted = 'true'** → Skip this video, check next one\n• **If Posted is empty/false** → Continue to post this video\n\n**Why this matters:**\n• Prevents duplicate posts\n• Automatically tracks what's been shared\n• Saves you from manual tracking\n\n**No setup needed** - works automatically!",
"position": [
1568,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-posted",
"operator": {
"type": "string",
"operation": "notContains"
},
"leftValue": "={{ $json.posted_story }}",
"rightValue": "true"
}
]
}
},
"notesInFlow": true,
"typeVersion": 2.2
},
{
"id": "c446ed83-b373-4887-b639-f30bb4a50721",
"name": "🎯 准备视频数据",
"type": "n8n-nodes-base.set",
"notes": "📋 **DATA PREPARATION**\n\n**What it does:** Organizes the video information for Instagram\n\n**Variables created:**\n• **instagram_business_id**: Your Instagram account ID\n• **video_url**: The video file location\n• **api_version**: Facebook API version to use\n\n**Why this step:** Makes the data clean and ready for Instagram's API\n\n**No configuration needed** - uses values from your Config node automatically!",
"position": [
1808,
320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a1",
"name": "instagram_business_id",
"type": "string",
"value": "={{ $json.IG_BUSINESS_ID || $('⚙️ Configuration Hub').item.json.IG_BUSINESS_ID }}"
},
{
"id": "a2",
"name": "video_url",
"type": "string",
"value": "={{ $json.source_url }}"
},
{
"id": "a3",
"name": "api_version",
"type": "string",
"value": "={{ $json.GRAPH_VERSION || $('⚙️ Configuration Hub').item.json.GRAPH_VERSION }}"
}
]
}
},
"notesInFlow": true,
"typeVersion": 3.4
},
{
"id": "7b86b176-296f-4e7b-8525-a0f42c53f8f8",
"name": "📱 视频要求",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
-112
],
"parameters": {
"width": 400,
"height": 376,
"content": "📱 **Instagram Story 要求**"
},
"typeVersion": 1
},
{
"id": "7182482a-dc7a-477f-ad28-8fbee137029c",
"name": "📤 创建 Story 容器",
"type": "n8n-nodes-base.httpRequest",
"notes": "🏗️ **CREDENTIAL SETUP REQUIRED**\n\n**What it does:** Creates an Instagram Story container (not published yet)\n\n**Setup Steps:**\n1. Click 'Credential for Facebook Graph API'\n2. Select 'Create New Credential'\n3. Enter your Facebook App credentials:\n • App ID (from Facebook Developers)\n • App Secret (from Facebook Developers)\n4. Grant Instagram permissions\n\n**What happens:** Instagram downloads and processes your video\n\n**Result:** Returns a container ID for the next step",
"position": [
2080,
368
],
"parameters": {
"url": "={{ 'https://graph.facebook.com/' + $('⚙️ Configuration Hub').item.json.GRAPH_VERSION + '/' + $('🎯 Prepare Video Data').item.json['instagram_business_id'] + '/media' }}",
"method": "POST",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "media_type",
"value": "STORIES"
},
{
"name": "video_url",
"value": "={{ $json['video_url'] }}"
}
]
},
"nodeCredentialType": "facebookGraphApi"
},
"credentials": {
"facebookGraphApi": {
"id": "UO25G0tgMnT1nQgI",
"name": "Facebook Graph accounts"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "5063827b-044c-42c4-be40-81cb50f1b643",
"name": "🔍 检查处理状态",
"type": "n8n-nodes-base.httpRequest",
"notes": "⏳ **STATUS MONITOR**\n\n**What it does:** Checks if Instagram finished processing your video\n\n**Possible statuses:**\n• **IN_PROGRESS**: Still processing (wait more)\n• **FINISHED**: Ready to publish ✅\n• **ERROR**: Something went wrong ❌\n\n**Why this step:** Instagram needs time to encode/validate your video\n\n**No configuration needed** - uses the same Facebook credentials as previous step",
"position": [
2368,
368
],
"parameters": {
"url": "={{ 'https://graph.facebook.com/' + $('⚙️ Configuration Hub').item.json.GRAPH_VERSION + '/' + $('📤 Create Story Container').item.json.id }}",
"options": {
"response": {
"response": {
"fullResponse": true,
"responseFormat": "json"
}
}
},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "fields",
"value": "status_code,status"
}
]
},
"nodeCredentialType": "facebookGraphApi"
},
"credentials": {
"facebookGraphApi": {
"id": "UO25G0tgMnT1nQgI",
"name": "Facebook Graph accounts"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "3520c4de-e2dc-4739-8ed5-5c6f15e805cd",
"name": "✅ 准备发布?",
"type": "n8n-nodes-base.if",
"notes": "🚦 **PUBLISH GATE**\n\n**What it checks:** Is the video ready for publishing?\n\n**Two paths:**\n• **TRUE (status = FINISHED)** → Proceed to publish\n• **FALSE (still processing)** → Wait 30 seconds and check again\n\n**Why this matters:**\n• Publishing too early = failure\n• This ensures your video is properly processed\n\n**Automatic loop:** Will keep checking until ready or timeout",
"position": [
2640,
368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-finished",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.status_code }}",
"rightValue": "FINISHED"
}
]
}
},
"notesInFlow": true,
"typeVersion": 2.2
},
{
"id": "5b05c0c2-34cf-413d-bad9-87a35bfd5935",
"name": "⏰ 等待 30 秒",
"type": "n8n-nodes-base.wait",
"notes": "⏸️ **PATIENCE IS KEY**\n\n**What it does:** Waits 30 seconds before checking status again\n\n**Why 30 seconds:**\n• Gives Instagram time to process\n• Prevents overwhelming their servers\n• Most videos process within 1-3 minutes\n\n**Adjustable:** You can change the wait time if needed\n• Smaller videos: 15-20 seconds\n• Larger videos: 45-60 seconds\n\n**Note:** The workflow will loop until processing is complete",
"position": [
2688,
896
],
"webhookId": "8a695322-e5bf-4b2c-bfb9-892f2cb0d8e6",
"parameters": {
"amount": 30
},
"notesInFlow": true,
"typeVersion": 1.1
},
{
"id": "1dc888c6-26a9-48a2-b7d4-47a65a264ea2",
"name": "🎉 发布到 Instagram",
"type": "n8n-nodes-base.facebookGraphApi",
"notes": "🚀 **THE MOMENT OF TRUTH**\n\n**What it does:** Publishes your video as an Instagram Story\n\n**This step:**\n• Takes the processed video container\n• Makes it live on your Instagram account\n• Your followers can now see the story\n\n**Success indicators:**\n• Returns a media ID\n• No error messages\n• Story appears on your Instagram profile\n\n**Uses the same Facebook credentials** as previous steps",
"position": [
2928,
368
],
"parameters": {
"edge": "media_publish",
"node": "={{ $('🎯 Prepare Video Data').item.json['instagram_business_id'] }}",
"options": {
"queryParameters": {
"parameter": [
{
"name": "creation_id",
"value": "={{ $('📤 Create Story Container').item.json.id }}"
}
]
}
},
"graphApiVersion": "={{ $('⚙️ Configuration Hub').item.json.GRAPH_VERSION }}",
"httpRequestMethod": "POST"
},
"credentials": {
"facebookGraphApi": {
"id": "UO25G0tgMnT1nQgI",
"name": "Facebook Graph accounts"
}
},
"notesInFlow": true,
"typeVersion": 1
},
{
"id": "08e727a9-baa5-4028-8d5d-c1d62b7b0d40",
"name": "✏️ 标记为已发布",
"type": "n8n-nodes-base.googleSheets",
"notes": "📝 **RECORD KEEPING**\n\n**What it does:** Updates your Google Sheet to mark this video as posted\n\n**How it works:**\n1. Finds the row with the matching video URL\n2. Sets the 'Posted' column to 'true'\n3. Prevents the same video from being posted again\n\n**Why this matters:**\n• Automatic tracking\n• No duplicate posts\n• Clear record of what's been shared\n\n**Uses the same Google Sheets credentials** as the fetch step",
"position": [
3200,
368
],
"parameters": {
"columns": {
"value": {
"source_url": "={{ $('🎯 Prepare Video Data').item.json.video_url }}",
"posted_story": "\"true\""
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "title",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "media_type",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "media_type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "mime_type",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "mime_type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "source_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "source_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posted_reels",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "posted_reels",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posted_story",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "posted_story",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"source_url"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"mode": "name",
"value": "={{ $('⚙️ Configuration Hub').item.json.SHEET_TAB_NAME }}"
},
"documentId": {
"mode": "list",
"value": "={{ $('⚙️ Configuration Hub').item.json.SHEET_DOC_ID }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "ZcotjdhaT5mLuV86",
"name": "Google Sheets account"
}
},
"notesInFlow": true,
"typeVersion": 4.5
},
{
"id": "9b340387-74b9-4245-a20c-7a5f4074f4c2",
"name": "🔧 故障排除",
"type": "n8n-nodes-base.stickyNote",
"position": [
2896,
528
],
"parameters": {
"width": 500,
"height": 560,
"content": "🚨 **故障排除指南**"
},
"typeVersion": 1
},
{
"id": "9dab79de-3039-4330-94fe-d7fc02bfb5a4",
"name": "✅ 设置检查清单",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
560
],
"parameters": {
"width": 440,
"height": 536,
"content": "🎓 **非技术用户设置检查清单**"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"⏰ Auto Schedule": {
"main": [
[
{
"node": "⚙️ Configuration Hub",
"type": "main",
"index": 0
}
]
]
},
"🚀 Manual Start": {
"main": [
[
{
"node": "⚙️ Configuration Hub",
"type": "main",
"index": 0
}
]
]
},
"⏰ Wait 30 Seconds": {
"main": [
[
{
"node": "🔍 Check Processing Status",
"type": "main",
"index": 0
}
]
]
},
"🎲 Randomize Order": {
"main": [
[
{
"node": "🔄 Process Each Video",
"type": "main",
"index": 0
}
]
]
},
"✅ Ready to Publish?": {
"main": [
[
{
"node": "🎉 Publish to Instagram",
"type": "main",
"index": 0
}
],
[
{
"node": "⏰ Wait 30 Seconds",
"type": "main",
"index": 0
}
]
]
},
"🎯 Prepare Video Data": {
"main": [
[
{
"node": "📤 Create Story Container",
"type": "main",
"index": 0
}
]
]
},
"🔄 Process Each Video": {
"main": [
[],
[
{
"node": "❓ Already Posted Check",
"type": "main",
"index": 0
}
]
]
},
"⚙️ Configuration Hub": {
"main": [
[
{
"node": "📊 Fetch Videos from Sheet",
"type": "main",
"index": 0
}
]
]
},
"❓ Already Posted Check": {
"main": [
[
{
"node": "🎯 Prepare Video Data",
"type": "main",
"index": 0
}
],
[
{
"node": "🔄 Process Each Video",
"type": "main",
"index": 0
}
]
]
},
"🎉 Publish to Instagram": {
"main": [
[
{
"node": "✏️ Mark as Posted",
"type": "main",
"index": 0
}
]
]
},
"📤 Create Story Container": {
"main": [
[
{
"node": "🔍 Check Processing Status",
"type": "main",
"index": 0
}
]
]
},
"📊 Fetch Videos from Sheet": {
"main": [
[
{
"node": "🎲 Randomize Order",
"type": "main",
"index": 0
}
]
]
},
"🔍 Check Processing Status": {
"main": [
[
{
"node": "✅ Ready to Publish?",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
LinkedIn和X病毒内容自动引擎
使用AI生成和发布自动创建LinkedIn和X的病毒内容
If
Set
Wait
+26
156 节点Diptamoy Barman
内容创作
公共SEO - Google和Bing索引自动化
使用Google索引API和Bing IndexNow提交变更站点地图URL的工作流
If
Set
Xml
+9
28 节点Geoffroy
内容创作
适用于WooCommerce Nano Banana的AI虚拟试穿
使用Fal.ai Nano Banana为WooCommerce自动生成虚拟AI试穿图像
If
Set
Wait
+7
20 节点Davide
内容创作
Apollo 数据抓取与触达流程 1 ✅
使用 Apollo、AI 解析和定时邮件跟进自动生成潜在客户
If
Code
Wait
+13
39 节点Deniz
内容创作
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
内容创作
基于 YouTube 视频的自主博客发布
使用 ChatGPT、Sheets、Apify、Pexels 和 WordPress 从 YouTube 视频自主发布博客
If
Set
Code
+18
80 节点Oriol Seguí
内容创作