This workflow corresponds to n8n.io template #11930 — we link there as the canonical source.
This workflow follows the Facebookgraphapi → Google Sheets 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 →
{
"nodes": [
{
"id": "119b454f-48fe-4271-96a1-72455f38aca0",
"name": "Schedule Every 15 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-5712,
704
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"typeVersion": 1.3
},
{
"id": "e2990957-17d1-4065-b21a-96e6c49505af",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-5488,
704
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "spreadsheetId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Your Google Sheets Spreadsheet ID__>"
},
{
"id": "id-2",
"name": "sheetName",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Sheet Name (e.g., Posts)__>"
},
{
"id": "id-3",
"name": "instagramAccessToken",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Instagram Graph API Access Token__>"
},
{
"id": "id-4",
"name": "instagramAccountId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Instagram Business Account ID__>"
},
{
"id": "id-5",
"name": "facebookPageId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Facebook Page ID__>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "952ea9f6-0602-4f34-8841-491308cc1e5f",
"name": "Read Pending Posts from Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-5264,
704
],
"parameters": {
"options": {
"returnFirstMatch": false
},
"filtersUI": {
"values": [
{
"lookupValue": "Pending",
"lookupColumn": "Status"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('Workflow Configuration').first().json.sheetName }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.spreadsheetId }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "ae394efb-56b7-4ed5-a09f-3f89aa911e98",
"name": "Filter Posts Due Now",
"type": "n8n-nodes-base.code",
"position": [
-5040,
704
],
"parameters": {
"jsCode": "const now = new Date();\nreturn items.filter(item => {\n const scheduledDateTime = new Date(item.json.ScheduledDateTime);\n return scheduledDateTime <= now;\n});"
},
"typeVersion": 2
},
{
"id": "ab19ef95-4f83-40b3-893a-aed60ff01cfe",
"name": "Check If Image Link Provided",
"type": "n8n-nodes-base.if",
"position": [
-4816,
704
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.ImageLink }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "076daf6b-fbd2-4a50-8fd4-10fdb6613e0b",
"name": "Download Image from Google Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
-4592,
672
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "url",
"value": "={{ $json.ImageLink }}"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "7ddd3c94-f319-4c46-ad41-5b8f2ec64be1",
"name": "Route by Platform",
"type": "n8n-nodes-base.switch",
"position": [
-4368,
688
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Instagram",
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Platform }}",
"rightValue": "Instagram"
}
]
},
"renameOutput": true
},
{
"outputKey": "Facebook",
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Platform }}",
"rightValue": "Facebook"
}
]
},
"renameOutput": true
},
{
"outputKey": "Both",
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Platform }}",
"rightValue": "Both"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "e505e0b7-92bf-4504-a9ec-87192171804e",
"name": "Post to Instagram",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3920,
464
],
"parameters": {
"url": "=https://graph.facebook.com/v24.0/{{ $('Workflow Configuration').first().json.instagramAccountId }}/media",
"method": "POST",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"sendBody": true,
"sendQuery": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"name": "access_token",
"value": "={{ $('Workflow Configuration').first().json.instagramAccessToken }}"
},
{
"name": "caption",
"value": "={{ $json.Caption }}"
},
{
"name": "image_url",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"queryParameters": {
"parameters": [
{
"name": "access_token",
"value": "={{ $('Workflow Configuration').first().json.instagramAccessToken }}"
},
{
"name": "caption",
"value": "={{ $json.Caption }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "6e51c644-4d60-4e3f-bd72-839c3a4f4509",
"name": "Post to Facebook",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
-3920,
944
],
"parameters": {
"edge": "feed",
"node": "={{ $('Workflow Configuration').first().json.facebookPageId }}",
"options": {
"queryParameters": {
"parameter": [
{
"name": "message",
"value": "={{ $json.Caption }}"
}
]
}
},
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "51b2810a-2325-4e08-8aed-7445fe9ed1de",
"name": "Post to Both Platforms - Instagram",
"type": "n8n-nodes-base.httpRequest",
"position": [
-4144,
704
],
"parameters": {
"url": "=https://graph.facebook.com/v24.0/{{ $('Workflow Configuration').first().json.instagramAccountId }}/media",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"name": "access_token",
"value": "={{ $('Workflow Configuration').first().json.instagramAccessToken }}"
},
{
"name": "caption",
"value": "={{ $json.Caption }}"
},
{
"name": "image_url",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "4a266382-ea2d-49c8-be26-4a7086ce964e",
"name": "Post to Both Platforms - Facebook",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
-3920,
704
],
"parameters": {
"edge": "feed",
"node": "={{ $('Workflow Configuration').first().json.facebookPageId }}",
"options": {
"queryParameters": {
"parameter": [
{
"name": "message",
"value": "={{ $json.Caption }}"
}
]
}
},
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "d14cc489-ea19-4a03-8084-5e40681cfd9a",
"name": "Prepare Success Update",
"type": "n8n-nodes-base.set",
"position": [
-3472,
608
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "Status",
"type": "string",
"value": "Success"
},
{
"id": "id-2",
"name": "PublishedAt",
"type": "string",
"value": "={{ $now.toISO() }}"
},
{
"id": "id-3",
"name": "ErrorMessage",
"type": "string",
"value": ""
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f8f130f5-c2a1-4b93-8fe5-020db4308bc7",
"name": "Prepare Error Update",
"type": "n8n-nodes-base.set",
"position": [
-3472,
800
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "Status",
"type": "string",
"value": "Failed"
},
{
"id": "id-2",
"name": "PublishedAt",
"type": "string",
"value": ""
},
{
"id": "id-3",
"name": "ErrorMessage",
"type": "string",
"value": "={{ $json.error.message }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "00c9beaa-db24-4ee4-b838-c13f9e4e268a",
"name": "Merge Success and Error Paths",
"type": "n8n-nodes-base.merge",
"position": [
-3248,
704
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineAll"
},
"typeVersion": 3.2
},
{
"id": "4141cc64-028b-426a-8e7c-e6629bd08f7a",
"name": "Update Sheet with Status",
"type": "n8n-nodes-base.googleSheets",
"position": [
-3024,
704
],
"parameters": {
"columns": {
"value": {
"Status": "={{ $json.Status }}",
"row_number": "={{ $json.row_number }}",
"PublishedAt": "={{ $json.PublishedAt }}",
"ErrorMessage": "={{ $json.ErrorMessage }}"
},
"schema": [
{
"id": "row_number",
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "PublishedAt",
"required": false,
"displayName": "PublishedAt",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "ErrorMessage",
"required": false,
"displayName": "ErrorMessage",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('Workflow Configuration').first().json.sheetName }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.spreadsheetId }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "bc306ff6-3bb4-4bc3-9d1b-150067944a65",
"name": "Check Post Success - Instagram",
"type": "n8n-nodes-base.if",
"position": [
-3696,
464
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "notExists"
},
"leftValue": "={{ $json.error }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "ce967f69-9249-43a4-b702-2596bfbadf2e",
"name": "Check Post Success - Facebook",
"type": "n8n-nodes-base.if",
"position": [
-3696,
944
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "notExists"
},
"leftValue": "={{ $json.error }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "15349ff1-0fa6-494d-b817-e59215a3b554",
"name": "Check Post Success - Both",
"type": "n8n-nodes-base.if",
"position": [
-3696,
704
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "notExists"
},
"leftValue": "={{ $json.error }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "6b490bce-5df4-489c-bf01-4ca160bedd81",
"name": "Section 1 Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5744,
336
],
"parameters": {
"color": 5,
"width": 400,
"height": 324,
"content": "## \ud83d\udcc5 SECTION 1: Trigger & Configuration\n\n**Purpose:** Start workflow and load settings\n\n**Nodes:**\n- Schedule Trigger: Runs every 15 minutes\n- Workflow Configuration: Stores all API credentials and IDs\n\n**What happens:** Timer triggers workflow, configuration node provides credentials to all downstream nodes"
},
"typeVersion": 1
},
{
"id": "6856c96a-08e3-45ad-b28a-674677db15b5",
"name": "Section 2 Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5312,
896
],
"parameters": {
"color": 6,
"width": 592,
"height": 248,
"content": "## \ud83d\udcca SECTION 2: Data Retrieval & Filtering\n\n**Purpose:** Get posts that are ready to publish\n\n**Nodes:**\n- Read Pending Posts: Gets rows with Status=\"Pending\"\n- Filter Posts Due Now: Compares ScheduledDateTime with current time\n\n**What happens:** Only posts scheduled for now or earlier proceed to next section"
},
"typeVersion": 1
},
{
"id": "f60f98f1-631c-4eaf-b687-1563340bbf98",
"name": "Section 3 Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4784,
352
],
"parameters": {
"color": 7,
"width": 448,
"height": 280,
"content": "## \ud83d\uddbc\ufe0f SECTION 3: Image Handling\n\n**Purpose:** Download images\n\n**Nodes:**\n- Check If Image Link Provided: Checks ImageLink field\n- Download Image from Google Drive: Gets file from Drive\n- Route by Platform: Splits flow by Platform value\n\n**What happens:** If image exists, downloads it. Then routes to correct platform(s)"
},
"typeVersion": 1
},
{
"id": "0c9aae6a-b2a1-4aef-9bfe-4003656146db",
"name": "Section 4 Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4416,
928
],
"parameters": {
"color": 2,
"width": 384,
"height": 300,
"content": "## \ud83d\ude80 SECTION 4: Publishing\n\n**Purpose:** Post to social media platforms\n\n**Nodes:**\n- Post to Instagram: Uses Instagram Graph API\n- Post to Facebook: Uses Facebook Graph API\n- Post to Both: Sequential posting to both platforms\n- Check Success nodes: Verify if posting succeeded\n\n**What happens:** Posts content with/without image, checks for errors"
},
"typeVersion": 1
},
{
"id": "8f61e2b9-94dd-44f0-9746-3b38e41ac22c",
"name": "Section 5 Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3728,
112
],
"parameters": {
"color": 3,
"width": 416,
"height": 304,
"content": "## \u2705 SECTION 5: Status Update\n\n**Purpose:** Record results back to Google Sheets\n\n**Nodes:**\n- Prepare Success Update: Sets Status=\"Success\", adds timestamp\n- Prepare Error Update: Sets Status=\"Failed\", captures error message\n- Merge Paths: Combines success/error branches\n- Update Sheet: Writes status back to original row\n\n**What happens:** Sheet is updated with post outcome"
},
"typeVersion": 1
},
{
"id": "9607b611-8880-4e1e-a9b1-b49e9d9ca95a",
"name": "Setup Instructions Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-6368,
416
],
"parameters": {
"width": 480,
"height": 600,
"content": "## \u2699\ufe0f SETUP INSTRUCTIONS\n\n### 1. Google Sheet Structure\nCreate columns:\n- **Caption** (text)\n- **ImageLink** (Google Drive shareable link, optional)\n- **Platform** (\"Instagram\", \"Facebook\", or \"Both\")\n- **ScheduledDateTime** (ISO format: 2024-01-15T10:00:00)\n- **Status** (\"Pending\" for new posts)\n- **PublishedAt** (leave empty)\n- **ErrorMessage** (leave empty)\n- **row_number** (unique ID for each row)\n\n### 2. Configure Workflow Configuration Node\n- spreadsheetId: From Google Sheets URL\n- sheetName: Your sheet name\n- instagramAccessToken: From Facebook Developer\n- instagramAccountId: Your Instagram Business ID\n- facebookPageId: Your Facebook Page ID\n\n### 3. Connect Credentials\n- Google Sheets OAuth2\n- Google Drive OAuth2\n- Facebook Graph API (for Facebook nodes)\n\n### 4. Instagram Requirements\n- Facebook Business account\n- Instagram Business account\n- Linked to Facebook Page\n- Access token with permissions:\n - instagram_basic\n - instagram_content_publish\n - pages_read_engagement"
},
"typeVersion": 1
}
],
"connections": {
"Post to Facebook": {
"main": [
[
{
"node": "Check Post Success - Facebook",
"type": "main",
"index": 0
}
]
]
},
"Post to Instagram": {
"main": [
[
{
"node": "Check Post Success - Instagram",
"type": "main",
"index": 0
}
]
]
},
"Route by Platform": {
"main": [
[
{
"node": "Post to Instagram",
"type": "main",
"index": 0
}
],
[
{
"node": "Post to Facebook",
"type": "main",
"index": 0
}
],
[
{
"node": "Post to Both Platforms - Instagram",
"type": "main",
"index": 0
}
]
]
},
"Filter Posts Due Now": {
"main": [
[
{
"node": "Check If Image Link Provided",
"type": "main",
"index": 0
}
]
]
},
"Prepare Error Update": {
"main": [
[
{
"node": "Merge Success and Error Paths",
"type": "main",
"index": 1
}
]
]
},
"Prepare Success Update": {
"main": [
[
{
"node": "Merge Success and Error Paths",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Read Pending Posts from Sheet",
"type": "main",
"index": 0
}
]
]
},
"Check Post Success - Both": {
"main": [
[
{
"node": "Prepare Success Update",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare Error Update",
"type": "main",
"index": 0
}
]
]
},
"Schedule Every 15 Minutes": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Check If Image Link Provided": {
"main": [
[
{
"node": "Download Image from Google Drive",
"type": "main",
"index": 0
}
],
[
{
"node": "Route by Platform",
"type": "main",
"index": 0
}
]
]
},
"Check Post Success - Facebook": {
"main": [
[
{
"node": "Prepare Success Update",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare Error Update",
"type": "main",
"index": 0
}
]
]
},
"Merge Success and Error Paths": {
"main": [
[
{
"node": "Update Sheet with Status",
"type": "main",
"index": 0
}
]
]
},
"Read Pending Posts from Sheet": {
"main": [
[
{
"node": "Filter Posts Due Now",
"type": "main",
"index": 0
}
]
]
},
"Check Post Success - Instagram": {
"main": [
[
{
"node": "Prepare Success Update",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare Error Update",
"type": "main",
"index": 0
}
]
]
},
"Download Image from Google Drive": {
"main": [
[
{
"node": "Route by Platform",
"type": "main",
"index": 0
}
]
]
},
"Post to Both Platforms - Facebook": {
"main": [
[
{
"node": "Check Post Success - Both",
"type": "main",
"index": 0
}
]
]
},
"Post to Both Platforms - Instagram": {
"main": [
[
{
"node": "Post to Both Platforms - Facebook",
"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.
googleDriveOAuth2ApigoogleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
How it works
Source: https://n8n.io/workflows/11930/ — 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 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
Automate Facebook post scheduling from a Google Sheets content calendar. Runs 4 times daily, reads approved posts scheduled for today, downloads images from Google Drive, schedules via Facebook Graph
This automation enables you to automatically fetch daily campaign data from Facebook Ads without manual exports. It requires connection to the Facebook Graph API and a Google Sheets account where all
This workflow is ideal for social media managers, content creators, marketers, and small businesses who want to automate Instagram Carousel posts using Google Sheets and Google Drive. It is also suita
This workflow is ideal for social media managers, content creators, marketing teams, and automation enthusiasts looking to streamline their Instagram Reels posting from Google Drive using n8n, Google