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