AutomationFlowsData & Sheets › Post Scheduled Threads Updates From Google Sheets with Error Tracking

Post Scheduled Threads Updates From Google Sheets with Error Tracking

ByOrchiv @orchiv on n8n.io

This workflow runs hourly to read the next pending post from Google Sheets, publishes it to Threads via the Threads Graph API, and then updates the sheet with published or failed status plus timestamps and error details. Runs every hour on a schedule. Reads the first row in…

Cron / scheduled trigger★★★★☆ complexity18 nodesGoogle SheetsHTTP Request
Data & Sheets Trigger: Cron / scheduled Nodes: 18 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #16392 — we link there as the canonical source.

This workflow follows the Google Sheets → HTTP Request 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 →

Download .json
{
  "id": "I84nJ5M1AcvUvzyI",
  "name": "Auto-Publish Threads Posts from Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "9c6ed362-84fa-45ac-87d3-8281d89608fe",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        960
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Auto-Publish Threads Posts from Google Sheets\n\n### How it works\n\n1. Triggers every hour to check for pending posts.\n2. Reads pending post details from Google Sheets.\n3. If there are pending posts, retrieves Threads User ID.\n4. Creates a post container and publishes the post to Threads.\n5. Marks posts as published or failed based on publishing success.\n\n### Setup steps\n\n- [ ] Configure Google Sheets credentials for reading and updating post statuses.\n- [ ] Set up HTTP requests to interact with Threads API, ensuring all endpoint URLs and credentials are accurate.\n\n### Customization\n\nYou can adjust the scheduling frequency from hourly to daily, or as needed, by modifying the schedule settings in the 'Every Hour' node."
      },
      "typeVersion": 1
    },
    {
      "id": "55c62bb8-4693-4e0d-a425-2d554ddf1a4a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2768,
        1216
      ],
      "parameters": {
        "color": 7,
        "height": 320,
        "content": "## Hourly trigger\n\nTriggers the workflow every hour to initiate the process."
      },
      "typeVersion": 1
    },
    {
      "id": "be5bfaf5-790e-4b58-8574-fe89c14b8783",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3040,
        1248
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Read pending posts\n\nFetches pending posts from Google Sheets and checks if any posts need publishing."
      },
      "typeVersion": 1
    },
    {
      "id": "78e815c1-dd09-4ef7-9bf9-6439c29b0e4b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3488,
        1152
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 400,
        "content": "## Retrieve user ID and create post\n\nRetrieves Threads user ID and prepares post container for publishing."
      },
      "typeVersion": 1
    },
    {
      "id": "0a3f0d03-cc0e-475e-86d7-dbf275424977",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3936,
        960
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 400,
        "content": "## Publish post and handle success\n\nPublishes the Threads post and marks it as published if successful."
      },
      "typeVersion": 1
    },
    {
      "id": "048125fd-8447-4e9d-8895-81db107f65ca",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4112,
        1392
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 688,
        "content": "## Error handling and logging\n\nCaptures errors during user ID retrieval, post creation, and publishing, marking the post as failed if any occur."
      },
      "typeVersion": 1
    },
    {
      "id": "3c9965fe-c2c7-44af-bde6-fb546ef15bb8",
      "name": "When Every Hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        2816,
        1376
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "cd94033d-8f9d-4172-90aa-291096c3fcf8",
      "name": "Read Pending Posts in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3088,
        1376
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "pending",
              "lookupColumn": "status"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Your Google Sheet ID (e.g., 1RXt_v3xE_CekfHHUa_ONw2YV5ZjNeK95t6ahkkn42VQ)__>"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "812d97c1-c7df-4055-b1b5-6d5c7adf57e8",
      "name": "If Has Pending Post",
      "type": "n8n-nodes-base.if",
      "position": [
        3312,
        1376
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "716f3515-f4ba-48c4-b3dd-69bc456496e1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "pending"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7fa2711d-58eb-417c-a24f-eb1e2cb3cfc4",
      "name": "Fetch Threads User ID",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3536,
        1376
      ],
      "parameters": {
        "url": "https://graph.threads.net/v1.0/me?fields=id,username",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "22880a87-49c3-426c-a6b6-fddc96d5209e",
      "name": "Post Threads Container",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3760,
        1280
      ],
      "parameters": {
        "url": "=https://graph.threads.net/v1.0/{{ $('Fetch Threads User ID').item.json.id }}/threads",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "media_type",
              "value": "TEXT"
            },
            {
              "name": "text",
              "value": "={{ $('Read Pending Posts in Sheets').item.json.content }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "a10322f7-fe01-4a3e-b585-fd98f8aea16c",
      "name": "Post Threads Content",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3984,
        1184
      ],
      "parameters": {
        "url": "=https://graph.threads.net/v1.0/{{ $('Fetch Threads User ID').item.json.id }}/threads_publish",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"creation_id\": \"{{ $json.id }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "4cb02443-810d-41a9-be77-6efd9e32ca98",
      "name": "Update Sheets Published Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4208,
        1088
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "published",
            "posted_at": "={{ $now.toISO() }}",
            "row_number": "={{ $('Read Pending Posts in Sheets').item.json.row_number }}",
            "updated_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "posted_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "posted_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "updated_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Your Google Sheet ID (same as Read node)__>"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "7e14703c-c040-43cf-8ff1-a86103788c17",
      "name": "Set Get User ID Error Details",
      "type": "n8n-nodes-base.set",
      "position": [
        4160,
        1904
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "error_message",
              "name": "error_message",
              "type": "string",
              "value": "Failed to get Threads User ID"
            },
            {
              "id": "row_number",
              "name": "row_number",
              "type": "number",
              "value": "={{ $('Read Pending Posts in Sheets').item.json.row_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0ffabaf4-abbd-4546-97b0-ae54903f7a9f",
      "name": "Merge All Error Details",
      "type": "n8n-nodes-base.merge",
      "position": [
        4384,
        1696
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "d73533f1-1e78-4bc3-94bb-414e2107994f",
      "name": "Set Container Error Details",
      "type": "n8n-nodes-base.set",
      "position": [
        4160,
        1712
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "error_message",
              "name": "error_message",
              "type": "string",
              "value": "Failed to create Threads container"
            },
            {
              "id": "row_number",
              "name": "row_number",
              "type": "number",
              "value": "={{ $('Read Pending Posts in Sheets').item.json.row_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ee6a75e4-2457-4438-9614-e61cd594ecbc",
      "name": "Set Publish Error Details",
      "type": "n8n-nodes-base.set",
      "position": [
        4160,
        1520
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "error_message",
              "name": "error_message",
              "type": "string",
              "value": "Failed to publish Threads post"
            },
            {
              "id": "row_number",
              "name": "row_number",
              "type": "number",
              "value": "={{ $('Read Pending Posts in Sheets').item.json.row_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a30a4ead-dd53-4b31-8bdb-c4d92d4dee47",
      "name": "Update Sheets Failed Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4608,
        1712
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "failed",
            "row_number": "={{ $json.row_number }}",
            "updated_at": "={{ $now.toISO() }}",
            "error_message": "={{ $json.error_message }}"
          },
          "schema": [
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "updated_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Your Google Sheet ID (same as Read node)__>"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "2c5314d1-c2d2-4e43-872f-1ef2151f68bd",
  "nodeGroups": [],
  "connections": {
    "When Every Hour": {
      "main": [
        [
          {
            "node": "Read Pending Posts in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Has Pending Post": {
      "main": [
        [
          {
            "node": "Fetch Threads User ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Threads Content": {
      "main": [
        [
          {
            "node": "Update Sheets Published Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Publish Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Threads User ID": {
      "main": [
        [
          {
            "node": "Post Threads Container",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Get User ID Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Threads Container": {
      "main": [
        [
          {
            "node": "Post Threads Content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Container Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Error Details": {
      "main": [
        [
          {
            "node": "Update Sheets Failed Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Publish Error Details": {
      "main": [
        [
          {
            "node": "Merge All Error Details",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Set Container Error Details": {
      "main": [
        [
          {
            "node": "Merge All Error Details",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Read Pending Posts in Sheets": {
      "main": [
        [
          {
            "node": "If Has Pending Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Get User ID Error Details": {
      "main": [
        [
          {
            "node": "Merge All Error Details",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow runs hourly to read the next pending post from Google Sheets, publishes it to Threads via the Threads Graph API, and then updates the sheet with published or failed status plus timestamps and error details. Runs every hour on a schedule. Reads the first row in…

Source: https://n8n.io/workflows/16392/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Complaint Triage Orchestrator (S2.3). Uses httpRequest, googleSheets. Scheduled trigger; 65 nodes.

HTTP Request, Google Sheets
Data & Sheets

This workflow automates video distribution to 9 social platforms simultaneously using Blotato's API. It includes both a scheduled publisher (checks Google Sheets for videos marked "Ready") and a subwo

Google Sheets, HTTP Request, Form Trigger +2
Data & Sheets

YogiAI. Uses googleSheets, googleSheetsTool, httpRequest, stopAndError. Scheduled trigger; 61 nodes.

Google Sheets, Google Sheets Tool, HTTP Request +1
Data & Sheets

This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev

Google Calendar, Google Sheets, HTTP Request +1
Data & Sheets

ofn hook v0.24.0 beta. Uses start, httpRequest, functionItem, itemLists. Scheduled trigger; 42 nodes.

Start, HTTP Request, Function Item +3