{
  "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
          }
        ]
      ]
    }
  }
}