{
  "name": "nashir.ai — Universal Publisher",
  "nodes": [
    {
      "id": "cb2b2d88-d5b3-4c28-ac8d-adaf8c3a1280",
      "name": "Setup Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 4,
        "width": 600,
        "height": 600,
        "content": "## 🚀 SETUP — nashir.ai Universal Publisher\n\n**STEP 1: Install the community package**\n  n8n Settings → Community Nodes → Install\n  Package: `n8n-nodes-nashir` (v0.10.0+ required for Threads)\n\n**STEP 2: Add your nashir.ai credential**\n  Any nashir node → Credentials → Create New → nashir.ai API\n  Paste your API key from: nashir.ai → Settings → API Keys\n  One credential works for all platform nodes (incl. the TikTok pre-check).\n\n**STEP 3: Select accounts in each node**\n  Open each platform node → click the Account dropdown\n  → choose your connected account.\n  Nodes with no account configured will be skipped.\n  This is how you control which platforms get the post.\n\n**STEP 4: Activate and test**\n  Toggle workflow ON → open the Form URL → submit a test post.\n\n**Media priority:**\n  Uploaded file takes priority over URL.\n  You may provide either — not both.\n  Threads also accepts text-only submissions (no media required).\n\n**Thumbnail (YouTube, Facebook, Telegram, Instagram Reels):**\n  The optional Video Thumbnail field is wired to YouTube, Facebook, Telegram, and Instagram Reels.\n  The other 5 platforms (LinkedIn, both Stories, TikTok, Threads) ignore it — their node packages or APIs don't accept a customer-supplied cover."
      },
      "typeVersion": 1
    },
    {
      "id": "a9814465-4ffa-4804-8822-0d1827fb171b",
      "name": "Accounts Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 360,
        "height": 140,
        "content": "### 🔗 Connecting Accounts\nEach nashir node has an **Account** dropdown.\nClick the node → select the connected page\nor profile you want to post from.\n\nnashir.ai → Accounts → Add Account"
      },
      "typeVersion": 1
    },
    {
      "id": "71bd778f-4f24-4917-b6c6-9cdfdebefd26",
      "name": "Instagram Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        160
      ],
      "parameters": {
        "color": 3,
        "width": 360,
        "height": 120,
        "content": "### 🟣 Instagram\nInstagram **always requires** an image or video.\nThe Skip? gate auto-routes around Instagram on text-only submits."
      },
      "typeVersion": 1
    },
    {
      "id": "f779adf9-8301-4a8e-9097-57f5a4dca0bc",
      "name": "YouTube Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        320
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "content": "### ▶️ YouTube\nYouTube requires a **video file**.\nThe first line of your caption becomes the video title.\n\n**Custom thumbnails** (optional Video Thumbnail field) — applied on YouTube, Facebook, Telegram, and Instagram Reels. YouTube requires a verified channel; unverified channels keep the auto-thumbnail.\n\n**TikTok** can't accept a custom cover image (API limit) — it uses a frame from the video as the cover, defaulting to **2 seconds in**. Change which frame via the *Cover Frame (ms)* field on the Post to TikTok (Video) node.\n\nLinkedIn, Stories, and Threads use their platform-default cover (custom cover support deferred per-platform)."
      },
      "typeVersion": 1
    },
    {
      "id": "f1f5693d-089c-4eb8-b8bf-23a0690ba2d3",
      "name": "TikTok Gate Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        1312
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 200,
        "content": "### 🎵 TikTok approval gate\nBefore posting to TikTok, this workflow queries\nTikTok's `creator_info` endpoint via nashir.ai\nto verify the account is approved for posting.\n\nIf TikTok's review is still pending, the\nworkflow skips TikTok cleanly with a clear\nreason in the summary — no API error."
      },
      "typeVersion": 1
    },
    {
      "id": "fa0fb26f-28b5-4ea8-bec6-273feb3fada1",
      "name": "Stories & TikTok Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        1312
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 180,
        "content": "### 📖 Stories & TikTok\nFacebook Story, Instagram Story, and TikTok all require media.\n- Stories: image or video\n- TikTok: 1 photo, a photo carousel (2+), or a video\n\nThey'll be auto-skipped via the per-platform Skip? gates if your post doesn't include compatible media."
      },
      "typeVersion": 1
    },
    {
      "id": "e63056fb-2446-4779-952f-4d5e304aa3db",
      "name": "Threads Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        1296
      ],
      "parameters": {
        "color": 5,
        "width": 360,
        "height": 220,
        "content": "### 🧵 Threads\nThreads is **Meta's text-first platform** and accepts text-only posts (no media required) — unique among the 9 destinations.\n\nLimits enforced by the node:\n- 500 characters per post (Meta hard limit)\n- 5 links per post (Meta returns THREADS_API__LINK_LIMIT_EXCEEDED above this)\n\nCustom video covers are not supported by Meta's Threads API."
      },
      "typeVersion": 1
    },
    {
      "id": "7eaddb76-b944-4620-b63a-cfcb84f43f48",
      "name": "Form Trigger",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        272,
        640
      ],
      "parameters": {
        "options": {},
        "formTitle": "nashir.ai — Publish Everywhere",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "Post Caption",
              "placeholder": "Write your post caption here...",
              "requiredField": true
            },
            {
              "fieldType": "file",
              "fieldLabel": "Upload Image or Video"
            },
            {
              "fieldLabel": "Image or Video URL",
              "placeholder": "https://example.com/image.jpg (optional, used if no file uploaded)"
            },
            {
              "fieldType": "file",
              "fieldLabel": "Video Thumbnail (optional, for YouTube)"
            }
          ]
        },
        "responseMode": "lastNode",
        "formDescription": "Publish to Facebook, Instagram, LinkedIn, Telegram, YouTube, Stories, TikTok, and Threads — all at once. Upload an image or video OR paste a URL. Threads accepts text-only; other platforms requiring media will be skipped if none is provided."
      },
      "typeVersion": 2.2
    },
    {
      "id": "5c999127-31e2-4312-8f3c-b727dddd83b8",
      "name": "Has Uploaded File?",
      "type": "n8n-nodes-base.if",
      "position": [
        512,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-upload-condition",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ Object.keys($binary || {}).length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "df759022-316c-4829-937f-f03b8861ba37",
      "name": "Normalize Upload",
      "type": "n8n-nodes-base.code",
      "position": [
        752,
        448
      ],
      "parameters": {
        "jsCode": "const item = $input.first();\nconst bin = { ...(item.binary || {}) };\nconst out = {};\nconst thumbKey = Object.keys(bin).find(k => /thumb/i.test(k));\nif (thumbKey) out.thumbnail = bin[thumbKey];\nconst mediaKeys = Object.keys(bin)\n  .filter(k => k !== thumbKey)\n  .sort((a, b) => (Number((a.match(/_(\\d+)$/) || [])[1] || 0)) - (Number((b.match(/_(\\d+)$/) || [])[1] || 0)));\nmediaKeys.forEach((k, idx) => { out['media_' + idx] = bin[k]; });\nreturn [{ json: { ...item.json }, binary: out }];"
      },
      "typeVersion": 2
    },
    {
      "id": "852956f7-5b96-4c4b-a8c6-f06a8b2e60a4",
      "name": "Has URL?",
      "type": "n8n-nodes-base.if",
      "position": [
        672,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-url-condition",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('Form Trigger').first().json['Image or Video URL'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4952be8b-bf81-43ab-b8a5-d2c5e567fbeb",
      "name": "Download Media",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        864,
        864
      ],
      "parameters": {
        "url": "={{ $('Form Trigger').first().json['Image or Video URL'] }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "media_0"
            }
          }
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "a6ef132f-d297-4edc-993b-053b0cda74b3",
      "name": "Parse Platforms",
      "type": "n8n-nodes-base.code",
      "position": [
        1008,
        640
      ],
      "parameters": {
        "jsCode": "const formData = $('Form Trigger').first().json;\nconst caption = formData['Post Caption'] || '';\nconst binary = $input.first().binary || {};\nconst mediaKeys = Object.keys(binary)\n  .filter(k => /^media_\\d+$/.test(k))\n  .sort((a, b) => Number(a.match(/_(\\d+)$/)[1]) - Number(b.match(/_(\\d+)$/)[1]));\nconst mimes = mediaKeys.map(k => binary[k].mimeType || '');\nconst hasV = mimes.some(m => m.startsWith('video/'));\nconst hasI = mimes.some(m => m.startsWith('image/'));\nconst mediaType = hasV && hasI ? 'mixed' : hasV ? 'video' : hasI ? 'image' : 'none';\nreturn [{ json: { caption, has_media: mediaKeys.length > 0, mediaCount: mediaKeys.length, mediaType }, binary }];"
      },
      "typeVersion": 2
    },
    {
      "id": "092d3071-52f0-4a60-8d9b-93492701ad64",
      "name": "Validate Media",
      "type": "n8n-nodes-base.code",
      "position": [
        1152,
        640
      ],
      "parameters": {
        "jsCode": "const item = $input.first();\nconst json = item.json;\nconst binary = item.binary || {};\nconst errors = [];\nif (json.mediaType === 'mixed') throw new Error('Upload images OR a single video, not both — a carousel is images-only.');\nfor (const k of Object.keys(binary).filter(x => /^media_\\d+$/.test(x))) {\n  const b = binary[k]; const mime = b.mimeType || ''; const mb = (Number(b.fileSize) || 0) / (1024 * 1024);\n  if (mime.startsWith('image/')) { if (mb > 8) errors.push(k + ' image too large: ' + mb.toFixed(1) + 'MB (max 8MB)'); }\n  else if (mime.startsWith('video/')) { if (mb > 100) errors.push(k + ' video too large: ' + mb.toFixed(1) + 'MB (max 100MB)'); }\n  else if (mime) errors.push('Unsupported media type for ' + k + ': ' + mime);\n}\nconst thumb = binary.thumbnail;\nconst has_thumbnail = !!(thumb && json.mediaType === 'video');\nif (has_thumbnail) { const tmb = (Number(thumb.fileSize) || 0) / (1024 * 1024); if (tmb > 2) errors.push('Thumbnail too large: ' + tmb.toFixed(1) + 'MB (max 2MB)'); }\nif (errors.length) throw new Error(errors.join('; '));\nreturn [{ json: { ...json, has_thumbnail }, binary }];"
      },
      "typeVersion": 2
    },
    {
      "id": "52c92796-01be-40ba-accc-fa0a70108cb4",
      "name": "Skip? Facebook",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-facebook-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.facebook }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "aac2f706-efd2-4983-84cf-92a9ebf35afb",
      "name": "Skip? Instagram",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-instagram-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.instagram }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "af18b76a-6833-41d2-be0d-eb8ea59a93e4",
      "name": "Skip? LinkedIn",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-linkedin-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.linkedin }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9bc6a441-ba99-4f23-ae96-64e8c49fe4a6",
      "name": "Skip? Telegram",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-telegram-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.telegram }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ada52369-7056-46a1-bb6f-f523c746f0b5",
      "name": "Skip? YouTube",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-youtube-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.youtube }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "827c3095-4c22-4e13-97b8-abe80f39bd98",
      "name": "Skip? Facebook Story",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        960
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-fb-story-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.facebook_story }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "fe184b1b-79d5-4700-9521-e9fcef9df4a1",
      "name": "Skip? Instagram Story",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        1120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-ig-story-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.instagram_story }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "d75bc1f7-5dd3-4e54-863c-1972e5d45c9c",
      "name": "Skip? TikTok",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        1360
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-tiktok-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.tiktok }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "7eac70ae-991e-4add-ac85-45c74ed1ce9d",
      "name": "Skip? Threads",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        1520
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "skip-threads-cond",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.threads }}",
              "rightValue": "skip"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "c93c7a52-1775-4af6-95ae-2000c0b93ffb",
      "name": "Post to Facebook",
      "type": "n8n-nodes-nashir.nashirFacebook",
      "position": [
        1824,
        160
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "hasMedia": "={{ $('Parse Platforms').first().json.has_media }}",
        "postType": "={{ $('Build Routing Plan').first().json.plan.facebook }}",
        "binaryPropertyName": "media_0",
        "thumbnailBinaryPropertyName": "={{ $('Validate Media').first().json.has_thumbnail ? 'thumbnail' : '' }}"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "d1184666-5666-4187-8ea1-03be765297d4",
      "name": "Post to Instagram",
      "type": "n8n-nodes-nashir.nashirInstagram",
      "position": [
        1824,
        320
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "postType": "={{ $('Build Routing Plan').first().json.plan.instagram }}",
        "binaryPropertyName": "media_0",
        "thumbnailBinaryPropertyName": "={{ $('Validate Media').first().json.has_thumbnail ? 'thumbnail' : '' }}"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "b12089de-25d2-4fbb-bb07-4ea071c3a726",
      "name": "Post to LinkedIn",
      "type": "n8n-nodes-nashir.nashirLinkedIn",
      "position": [
        1824,
        464
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "hasMedia": "={{ $('Parse Platforms').first().json.has_media }}",
        "postType": "={{ $('Build Routing Plan').first().json.plan.linkedin }}",
        "binaryPropertyName": "media_0"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "3d0d4694-d389-4283-a41b-d029d3746093",
      "name": "Post to Telegram",
      "type": "n8n-nodes-nashir.nashirTelegram",
      "position": [
        1824,
        640
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "hasMedia": "={{ $('Parse Platforms').first().json.has_media }}",
        "binaryPropertyName": "media_0",
        "thumbnailBinaryPropertyName": "={{ $('Validate Media').first().json.has_thumbnail ? 'thumbnail' : '' }}"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "1b10ea87-c8dd-45bb-b898-64d9d49376ed",
      "name": "Post to YouTube",
      "type": "n8n-nodes-nashir.nashirYouTube",
      "position": [
        1824,
        800
      ],
      "parameters": {
        "title": "={{ $('Form Trigger').first().json['Post Caption'].split('\\n')[0].substring(0, 100) }}",
        "description": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "binaryPropertyName": "media_0",
        "thumbnailBinaryPropertyName": "={{ $('Validate Media').first().json.has_thumbnail ? 'thumbnail' : '' }}"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "a05869de-691d-49ab-8039-8ac91677e226",
      "name": "Post to Facebook Story",
      "type": "n8n-nodes-nashir.nashirFacebook",
      "position": [
        1824,
        960
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "hasMedia": "={{ $('Validate Media').first().json.has_media }}",
        "postType": "story",
        "binaryPropertyName": "media_0"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "3da409ec-acd5-4df5-9584-2c051792d2da",
      "name": "Post to Instagram Story",
      "type": "n8n-nodes-nashir.nashirInstagram",
      "position": [
        1824,
        1120
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "postType": "story",
        "binaryPropertyName": "media_0"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "b801c924-ff21-4382-9d28-04df7101b29a",
      "name": "Post to TikTok (Photos)",
      "type": "n8n-nodes-nashir.nashirTikTok",
      "position": [
        2304,
        1360
      ],
      "parameters": {
        "operation": "publishPhotos",
        "photoAccount": "",
        "photoCaption": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "photoAllowComment": true,
        "photoAutoAddMusic": true
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "a82cbc2e-edf2-47b3-a781-e722d02d08ff",
      "name": "Post to Threads",
      "type": "n8n-nodes-nashir.nashirThreads",
      "position": [
        1824,
        1520
      ],
      "parameters": {
        "account": "",
        "content": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "hasMedia": "={{ $('Parse Platforms').first().json.has_media }}",
        "binaryPropertyName": "media_0"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "id": "0500c65a-bf06-4c34-b257-24f3b6867a9e",
      "name": "Merge Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        2544,
        640
      ],
      "parameters": {
        "numberInputs": 9
      },
      "typeVersion": 3
    },
    {
      "id": "fe9336c3-f56b-45ad-baf8-2c384305fd26",
      "name": "Build Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        2704,
        752
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst plan = $('Build Routing Plan').first().json.plan;\nconst platforms = [\n  { name: 'Facebook', emoji: '🔵', key: 'facebook' },\n  { name: 'Instagram', emoji: '🟣', key: 'instagram' },\n  { name: 'LinkedIn', emoji: '🔷', key: 'linkedin' },\n  { name: 'Telegram', emoji: '✈️', key: 'telegram' },\n  { name: 'YouTube', emoji: '▶️', key: 'youtube' },\n  { name: 'Facebook Story', emoji: '📘', key: 'facebook_story' },\n  { name: 'Instagram Story', emoji: '📸', key: 'instagram_story' },\n  { name: 'TikTok', emoji: '🎵', key: 'tiktok' },\n  { name: 'Threads', emoji: '🧵', key: 'threads' },\n];\nconst lines = platforms.map((p, idx) => {\n  if (plan[p.key] === 'skip') return p.emoji + ' ' + p.name + ': ⏭️ skipped';\n  const item = items[idx];\n  if (!item) return p.emoji + ' ' + p.name + ': ❌ no response';\n  if (item.json && item.json.can_publish === false) return p.emoji + ' ' + p.name + ': ⏭️ skipped — ' + (item.json.reason || 'TikTok account not approved');\n  const isError = item.json.error !== undefined || (item.json.statusCode && item.json.statusCode >= 400);\n  return p.emoji + ' ' + p.name + ': ' + (isError ? '❌ failed' : '✅ published');\n});\nreturn [{ json: { summary: 'nashir.ai Publish Results\\n\\n' + lines.join('\\n') } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "4c064c8a-3801-4dcc-acdd-4501d4e8b5d2",
      "name": "Respond to Form",
      "type": "n8n-nodes-base.form",
      "position": [
        2880,
        752
      ],
      "webhookId": "9c085700-d427-46bf-b2ab-9082fc2746ef",
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "8d040d66-90f5-4f02-9cac-8056b76e2670",
      "name": "Build Routing Plan",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        640
      ],
      "parameters": {
        "jsCode": "const json = $input.first().json;\nconst n = json.mediaCount || 0;\nconst t = json.mediaType;\nconst carousel = t === 'image' && n >= 2;\nconst oneImg = t === 'image' && n === 1;\nconst video = t === 'video';\nconst plan = {\n  facebook:        carousel ? 'carousel' : oneImg ? 'feed' : video ? 'feed' : 'skip',\n  instagram:       carousel ? 'carousel' : oneImg ? 'feed' : video ? 'reel' : 'skip',\n  linkedin:        carousel ? 'carousel' : (oneImg || video) ? 'feed' : 'skip',\n  telegram:        (oneImg || video || carousel) ? 'single' : 'skip',\n  threads:         (oneImg || video || carousel) ? 'single' : 'skip',\n  youtube:         video ? 'video' : 'skip',\n  facebook_story:  n >= 1 ? 'story' : 'skip',\n  instagram_story: n >= 1 ? 'story' : 'skip',\n  tiktok:          (carousel || oneImg) ? 'publishPhotos' : video ? 'publishVideo' : 'skip',\n};\nreturn [{ json: { ...json, plan }, binary: $input.first().binary }];"
      },
      "typeVersion": 2
    },
    {
      "id": "aad2e86e-a5ff-4e29-91fe-3de911554d85",
      "name": "Post to TikTok (Video)",
      "type": "n8n-nodes-nashir.nashirTikTok",
      "position": [
        2304,
        1520
      ],
      "parameters": {
        "account": "",
        "caption": "={{ $('Form Trigger').first().json['Post Caption'] }}",
        "allow_comment": true,
        "binaryPropertyName": "media_0"
      },
      "credentials": {
        "nashirApi": {
          "id": "nashir-cred",
          "name": "nashir.ai API"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "66e669fe-2f44-49e9-9434-f9147cf709d9",
      "name": "TikTok Video?",
      "type": "n8n-nodes-base.if",
      "position": [
        2112,
        1424
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3e6db615-d0c7-40ab-a15c-d6c2e0aca98c",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Build Routing Plan').first().json.plan.tiktok }}",
              "rightValue": "publishVideo"
            }
          ]
        }
      },
      "typeVersion": 2
    }
  ],
  "_readme": "nashir.ai — Universal Publisher. Upload media once; it publishes the right content type to every connected platform automatically. AFTER IMPORT: (1) open each \"Post to ...\" node and select your nashir.ai API credential, (2) pick your account in each node, (3) activate, then open the Form. 1 image = single post; 2+ images = carousel (FB grid / IG+LinkedIn swipeable / TikTok photo carousel); 1 video = video/Reel (TikTok video too). EVERY post ALSO goes to Facebook + Instagram Stories (cover image). To turn that off, deactivate or delete the two \"Post to ... Story\" nodes. TikTok publishes single photos, photo carousels, and single videos (auto-routed); PNGs are auto-converted to JPEG for TikTok. Telegram/Threads post the cover image for carousels.",
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Has URL?": {
      "main": [
        [
          {
            "node": "Download Media",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Parse Platforms",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form Trigger": {
      "main": [
        [
          {
            "node": "Has Uploaded File?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip? TikTok": {
      "main": [
        [
          {
            "node": "TikTok Video?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Summary": {
      "main": [
        [
          {
            "node": "Respond to Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Results": {
      "main": [
        [
          {
            "node": "Build Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip? Threads": {
      "main": [
        [
          {
            "node": "Post to Threads",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 8
          }
        ]
      ]
    },
    "Skip? YouTube": {
      "main": [
        [
          {
            "node": "Post to YouTube",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 4
          }
        ]
      ]
    },
    "TikTok Video?": {
      "main": [
        [
          {
            "node": "Post to TikTok (Video)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Post to TikTok (Photos)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Media": {
      "main": [
        [
          {
            "node": "Parse Platforms",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip? Facebook": {
      "main": [
        [
          {
            "node": "Post to Facebook",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip? LinkedIn": {
      "main": [
        [
          {
            "node": "Post to LinkedIn",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Skip? Telegram": {
      "main": [
        [
          {
            "node": "Post to Telegram",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Validate Media": {
      "main": [
        [
          {
            "node": "Build Routing Plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Platforms": {
      "main": [
        [
          {
            "node": "Validate Media",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Threads": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 8
          }
        ]
      ]
    },
    "Post to YouTube": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 4
          }
        ]
      ]
    },
    "Skip? Instagram": {
      "main": [
        [
          {
            "node": "Post to Instagram",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Upload": {
      "main": [
        [
          {
            "node": "Parse Platforms",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Facebook": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to LinkedIn": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Post to Telegram": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Post to Instagram": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Build Routing Plan": {
      "main": [
        [
          {
            "node": "Skip? Facebook",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? Instagram",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? LinkedIn",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? Telegram",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? YouTube",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? Facebook Story",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? Instagram Story",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? TikTok",
            "type": "main",
            "index": 0
          },
          {
            "node": "Skip? Threads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Uploaded File?": {
      "main": [
        [
          {
            "node": "Normalize Upload",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Has URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip? Facebook Story": {
      "main": [
        [
          {
            "node": "Post to Facebook Story",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 5
          }
        ]
      ]
    },
    "Skip? Instagram Story": {
      "main": [
        [
          {
            "node": "Post to Instagram Story",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 6
          }
        ]
      ]
    },
    "Post to Facebook Story": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 5
          }
        ]
      ]
    },
    "Post to TikTok (Video)": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Instagram Story": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 6
          }
        ]
      ]
    },
    "Post to TikTok (Photos)": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 7
          }
        ]
      ]
    }
  }
}