{
  "id": "D5XugO8cqbM8kLgx",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "X Tweet & Meta Threads Poster",
  "tags": [
    {
      "id": "HtQShCcCu7P3dXRZ",
      "name": "content engine",
      "createdAt": "2025-06-07T15:33:15.216Z",
      "updatedAt": "2025-06-07T15:33:15.216Z"
    },
    {
      "id": "MN3g7wETylMKdMxN",
      "name": "fix",
      "createdAt": "2024-12-24T02:05:17.036Z",
      "updatedAt": "2024-12-24T02:05:17.036Z"
    }
  ],
  "nodes": [
    {
      "id": "a752b5a3-5e47-4e5e-8f96-c69665b96bc8",
      "name": "Get Topic",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        112,
        -464
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "draft",
              "lookupColumn": "Status"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1602514486,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8/edit#gid=1602514486",
          "cachedResultName": "One Thread"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8/edit?usp=drivesdk",
          "cachedResultName": "SOSMED KONTEN PLANNER"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "6e838349-6c46-4f94-bad3-1a55a2d50549",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        544,
        -432
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cfc73c2c-619d-4323-beab-6c87750b19ad",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json[\"tweet\"].length <= 280 }}",
              "rightValue": ""
            },
            {
              "id": "1012e0ce-d86a-498c-b1ed-c13f2a181942",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json[\"tweet2\"].length <= 280 }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e58a2323-fc41-43e2-aa45-9fa4f755397d",
      "name": "Get Img",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        112,
        -256
      ],
      "parameters": {
        "url": "={{ $('Get Topic').item.json['Img URL'] }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "95a1162e-d2c6-498d-a6e9-c4bd3af996bc",
      "name": "Post Twitter",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        720,
        -432
      ],
      "parameters": {
        "url": "https://getlate.dev/api/v1/posts",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"content\": {{ JSON.stringify((() => {\n    const text = $('Set Tweets').first().json.tweet || \"\";\n    return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n  })()) }},\n  \"mediaItems\": [\n    {\n      \"type\": \"image\",\n      \"url\": {{ JSON.stringify($('Upload IMG').first().json.files[0].url) }}\n    }\n  ],\n  \"platforms\": [\n    {\n      \"platform\": \"twitter\",\n      \"accountId\": \"xxxxxxxxxxxxxxxxxxxxxxx\",\n      \"platformSpecificData\": {\n        \"threadItems\": [\n          { \n            \"content\": {{ JSON.stringify((() => {\n              const text = $('Set Tweets').first().json.tweet || \"\";\n              return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n            })()) }}\n          },\n          { \n            \"content\": {{ JSON.stringify((() => {\n              const text = $json.tweet2 || \"\";\n              return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n            })()) }}\n          }\n        ]\n      }\n    }\n  ],\n  \"publishNow\": true\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6d84bc3f-337d-408f-a57f-64eec3fd5671",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        560,
        -32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cfc73c2c-619d-4323-beab-6c87750b19ad",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json[\"tweet\"].length <= 500 }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c3030289-bf13-412c-9dc6-dc50f2da2d82",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -528
      ],
      "parameters": {
        "color": 5,
        "width": 528,
        "height": 704,
        "content": "# STEP 1"
      },
      "typeVersion": 1
    },
    {
      "id": "2490d7ed-fb11-4d3c-8fc8-45f90a00f63b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -528
      ],
      "parameters": {
        "color": 4,
        "width": 1024,
        "height": 352,
        "content": "# STEP 2 - POST TO X.COM"
      },
      "typeVersion": 1
    },
    {
      "id": "55c17a1d-27b7-4147-8412-d352c43dbbe9",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -160
      ],
      "parameters": {
        "color": 4,
        "width": 1024,
        "height": 336,
        "content": "# STEP 3 - POST TO META THREADS.COM"
      },
      "typeVersion": 1
    },
    {
      "id": "5e816b20-4caf-49c5-9896-f3433dff2b80",
      "name": "Update Data Posted",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        944,
        -32
      ],
      "parameters": {
        "columns": {
          "value": {
            "Kritik": "={{ $('Get Topic').first().json.Kritik }}",
            "Status": "posted",
            "Short URL": "={{ $('Short link').item.json.link }}",
            "row_number": "={{ $('Get Topic').first().json.row_number }}"
          },
          "schema": [
            {
              "id": "No",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "No",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Headline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Headline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Img URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Img URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "hashtags 1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "hashtags 1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "hashtags 2",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "hashtags 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tweet",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tweet",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Short URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Short URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Kritik",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Kritik",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1602514486,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8/edit#gid=1602514486",
          "cachedResultName": "One Thread"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uvhdkxOitQT79-xWJg9k5pOTRH_GGwCsFzeBhVx7Uy8/edit?usp=drivesdk",
          "cachedResultName": "SOSMED KONTEN PLANNER"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "6ed07c3c-76e5-4c72-85bf-a7ae598c29fe",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -528
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 688,
        "content": "## HOW TO USE  \n\n**STEP 1**  \n1. Adjust the settings in the Schedule Trigger node to define when the workflow runs.  \n2. Open this [Google Sheets template](https://docs.google.com/spreadsheets/d/1CtpVHtzu_y9KoELS7Cee3BDivtRN2zVg-Uuy7uZD4ko/edit?usp=sharing), then go to **File \u2192 Make a copy**, and update the settings in the Get Topic node.  \n3. Get your Bitly OAuth or Access Token [here](https://app.bitly.com/settings/api) and add the credentials in the Short Link node.  \n4. Get your API key from [getlate.dev](https://getlate.dev/) and add the credentials in the Upload IMG node.  \n\n**STEP 2**  \n1. Add your Late credentials to the Post Twitter node.  \n2. Get your Twitter account ID from Late, and update it in the JSON Body section of the Post Twitter node.  \n\n**STEP 3**  \n1. Add your Late credentials to the Post Threads node.  \n2. Get your Threads account ID from Late, and update it in the JSON Body section of the Post Threads node.  "
      },
      "typeVersion": 1
    },
    {
      "id": "ead7f7b2-981f-4f0c-bd3a-6aacbebfa8c9",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -96,
        -464
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 */8 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bd311f77-4ac0-47d4-bb29-f444e31541b2",
      "name": "Rename Img",
      "type": "n8n-nodes-base.code",
      "position": [
        -80,
        -32
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  if (item.binary && item.binary.data) {\n    const bin = item.binary.data;\n\n    // Generate timestamp, e.g. 2025-07-25_153045\n    const now = new Date();\n    const pad = n => n.toString().padStart(2, '0');\n    const timestamp = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;\n\n    // Set file extension based on mime type, fallback to .jpg\n    const ext = bin.mimeType?.split('/')[1] || 'jpg';\n\n    // Rename file\n    bin.fileName = `image-${timestamp}.${ext}`;\n\n    return { json: {}, binary: { data: bin } };\n  }\n  return item;\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6309cc1c-c614-46f5-aa67-8da577a65735",
      "name": "Upload IMG",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        112,
        -32
      ],
      "parameters": {
        "url": "https://getlate.dev/api/v1/media",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "files",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "73462736-43a4-4369-a16b-93e93202f423",
      "name": "Set Tweets",
      "type": "n8n-nodes-base.set",
      "notes": "TWEET",
      "position": [
        368,
        -432
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "563ba198-5573-4d97-ba6d-8a66096f9cd6",
              "name": "tweet",
              "type": "string",
              "value": "=\ud83d\udce2 {{ $('Get Topic').item.json.Headline }} \ud83d\udc49 {{ $('Short link').item.json.link }} \ud83e\uddd0 #{{ $('Get Topic').item.json['hashtags 1'] }} #{{ $('Get Topic').item.json['hashtags 2'] }}"
            },
            {
              "id": "74c80466-f00c-44b8-ba09-dfeb8c0a2bf1",
              "name": "tweet2",
              "type": "string",
              "value": "={{ $('Get Topic').item.json.Tweet }}"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "3d82f0ba-0da2-4f60-8b59-4cd500e6c2ff",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        912,
        -432
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "8efac987-69e3-457d-83cc-40e68b4e305f",
      "name": "Set Thread",
      "type": "n8n-nodes-base.set",
      "notes": "THREADS",
      "position": [
        384,
        -32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "563ba198-5573-4d97-ba6d-8a66096f9cd6",
              "name": "tweet",
              "type": "string",
              "value": "=\ud83d\udd25{{ $('Get Topic').item.json.Headline }}. \ud83e\udd14 {{ $('Get Topic').item.json.Kritik }} {{ $('Short link').item.json.link }} #{{ $('Get Topic').item.json['hashtags 1'] }} #{{ $('Get Topic').item.json['hashtags 2'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ce1c09d0-38c6-430e-b2d4-6d5e8bec8d5f",
      "name": "Post Thread",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        752,
        -32
      ],
      "parameters": {
        "url": "https://getlate.dev/api/v1/posts",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"content\": {{ JSON.stringify((() => {\n    const text = $json.tweet || \"\";\n    return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n  })()) }},\n  \"platforms\": [\n    {\n      \"platform\": \"threads\",\n      \"accountId\": \"xxxxxxxxxxxxxxxxxxxxxx\"\n    }\n  ],\n  \"mediaItems\": [\n    {\n      \"type\": \"image\",\n      \"url\": {{ JSON.stringify($('Upload IMG').first().json.files[0].url) }}\n    }\n  ],\n  \"publishNow\": true\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "61c1e0f8-caea-4325-87b2-7c1a3f649a4f",
      "name": "No Operation, do nothing1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1136,
        -32
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "cb54a2b2-4b0d-44a4-957d-c66e072dc279",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -528
      ],
      "parameters": {
        "width": 512,
        "height": 784,
        "content": "## Different X and Threads Content Auto Poster  \n### This n8n template demonstrates how to post different content optimized for X (Twitter) and Meta Threads using the Late API.  \n\nYou can use it for any niche. For example: posting AI news to X and Threads.  \n\n**Possible use cases:**  \n- Schedule your posts to X and Threads.  \n- Use this workflow as a content calendar and automated posting system.  \n- Apply it across different content niches.  \n\n### How it works  \n- The automation runs according to the time defined in the Schedule Trigger node.  \n- Content is pulled from Google Sheets.  \n- Any URL is shortened using your preferred short URL API.  \n- Images are uploaded to Late\u2019s server first.  \n- Content for X is posted in Step 2. The workflow checks that the content length is under 280 characters.  \n- Content for Threads is posted in Step 3. The workflow checks that the content length is under 500 characters.  \n- Posts on X are published as threaded posts, while on Threads they are single posts.  \n- Once posted, the Google Sheets content database is updated.  \n\n### Requirements  \n- Google OAuth credentials with the Google Sheets API enabled  \n- Bitly account and access token (or OAuth)  \n- GetLate API connected to your X and Threads accounts "
      },
      "typeVersion": 1
    },
    {
      "id": "a2d4d406-fe8f-46d6-8be5-d206ed6c3b28",
      "name": "Short link",
      "type": "n8n-nodes-base.bitly",
      "position": [
        -80,
        -256
      ],
      "parameters": {
        "longUrl": "={{ $json.URL }}",
        "additionalFields": {}
      },
      "credentials": {
        "bitlyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "timezone": "Asia/Jakarta",
    "callerPolicy": "workflowsFromSameOwner",
    "executionOrder": "v1"
  },
  "versionId": "91529ea5-98fe-4e25-8573-e9f28d7bcc5c",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Post Twitter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Post Thread",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Img": {
      "main": [
        [
          {
            "node": "Rename Img",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Topic": {
      "main": [
        [
          {
            "node": "Short link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rename Img": {
      "main": [
        [
          {
            "node": "Upload IMG",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Thread": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Tweets": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Short link": {
      "main": [
        [
          {
            "node": "Get Img",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload IMG": {
      "main": [
        [
          {
            "node": "Set Tweets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Set Thread",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Thread": {
      "main": [
        [
          {
            "node": "Update Data Posted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Twitter": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Topic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Data Posted": {
      "main": [
        [
          {
            "node": "No Operation, do nothing1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}