{
  "name": "Create a virtual outfit try-on Telegram bot with async polling and Google Sheets",
  "nodes": [
    {
      "id": "0ede88b5-b324-40f3-b0f2-3d38d02f14d9",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -416,
        2128
      ]
    },
    {
      "id": "967cc6cb-ce35-4b6e-9da1-ce97bd9a7c87",
      "name": "Extract Message Info",
      "type": "n8n-nodes-base.set",
      "position": [
        -192,
        2128
      ]
    },
    {
      "id": "ef066042-e44f-4d8b-aab8-813cef499e5c",
      "name": "⚙️ Config",
      "type": "n8n-nodes-base.set",
      "position": [
        32,
        2128
      ]
    },
    {
      "id": "ca083aaa-154d-484f-a721-1094765a7178",
      "name": "Has Photo?",
      "type": "n8n-nodes-base.if",
      "position": [
        256,
        2128
      ]
    },
    {
      "id": "81f8f152-96ab-4d51-a1e3-e5660753d1c6",
      "name": "Send Welcome Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        480,
        2224
      ]
    },
    {
      "id": "2024a886-5e99-4c3e-b09e-2a7b61047388",
      "name": "Is Garment Photo?",
      "type": "n8n-nodes-base.if",
      "position": [
        480,
        2032
      ]
    },
    {
      "id": "1f2bcd45-87fc-46fb-9466-4f6c2f002dd8",
      "name": "Save Person to Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        704,
        1936
      ]
    },
    {
      "id": "5eac99d6-4dcb-4351-8ad3-6cf8e9eaa099",
      "name": "Ask for Garment Photo",
      "type": "n8n-nodes-base.telegram",
      "position": [
        928,
        1936
      ]
    },
    {
      "id": "6c3211b9-78d2-4f98-8026-0e6c18e06fc5",
      "name": "Lookup Person from Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        704,
        2128
      ]
    },
    {
      "id": "b0a6bad7-019c-4ab2-933f-17a9b74c5f86",
      "name": "Has Person Saved?",
      "type": "n8n-nodes-base.if",
      "position": [
        928,
        2128
      ]
    },
    {
      "id": "66b0aa3c-269d-4fad-a698-15e02080430e",
      "name": "Ask for Person First",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1152,
        2224
      ]
    },
    {
      "id": "fba2ab05-ea3e-45b1-aa94-f721bbc7315f",
      "name": "Collect IDs",
      "type": "n8n-nodes-base.set",
      "position": [
        1152,
        2032
      ]
    },
    {
      "id": "c0fff2e6-7cd1-4d00-8b35-3eb1d5a434ae",
      "name": "Send Processing Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1376,
        2032
      ]
    },
    {
      "id": "3041396b-99d2-4999-a979-a6aceb3990cf",
      "name": "Get Person File Path",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1600,
        2032
      ]
    },
    {
      "id": "5f51611e-5e17-46b2-b64b-5f3808f22e47",
      "name": "Set Person Download URL",
      "type": "n8n-nodes-base.set",
      "position": [
        1824,
        2032
      ]
    },
    {
      "id": "cfb00dcf-fd84-4448-89ff-219339443e46",
      "name": "Get Garment File Path",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2048,
        2032
      ]
    },
    {
      "id": "f4096aba-fb45-47f4-b02b-c1a0ba2d5620",
      "name": "Set Garment Download URL",
      "type": "n8n-nodes-base.set",
      "position": [
        2272,
        2032
      ]
    },
    {
      "id": "f8cd2136-e962-4408-84ee-b5b701c4410d",
      "name": "Download Person Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2496,
        2032
      ]
    },
    {
      "id": "354a10f6-9cdd-453e-ab96-e63b0d2ef7c8",
      "name": "Download Garment Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2720,
        2032
      ]
    },
    {
      "id": "eb8542fb-91a8-462c-b191-c2e01fa905e7",
      "name": "Submit Try-On Job",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2944,
        2032
      ]
    },
    {
      "id": "0d24662f-aa0c-46f6-b3b3-35bc774f7811",
      "name": "Extract Job ID",
      "type": "n8n-nodes-base.set",
      "position": [
        3168,
        2032
      ]
    },
    {
      "id": "b3afa4b4-4b7d-4df8-8af3-92a973cbc1f8",
      "name": "Wait 15 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        3392,
        2032
      ]
    },
    {
      "id": "f90cce7f-857e-4260-ae86-81efd01f9d7e",
      "name": "Check Job Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3616,
        1904
      ]
    },
    {
      "id": "1b0f1b09-a081-424a-98a3-d689cc6fd71a",
      "name": "Merge State",
      "type": "n8n-nodes-base.set",
      "position": [
        3840,
        1904
      ]
    },
    {
      "id": "6a7c9814-d81a-4106-b75b-8b56f4415409",
      "name": "Is Job Complete?",
      "type": "n8n-nodes-base.if",
      "position": [
        4064,
        1904
      ]
    },
    {
      "id": "52b6967f-8093-4a97-b8d3-c801a6146ba9",
      "name": "Is Job Failed?",
      "type": "n8n-nodes-base.if",
      "position": [
        4288,
        2128
      ]
    },
    {
      "id": "bb7c6f29-0712-4300-ab39-5bb342b52f9f",
      "name": "Send Result Photo",
      "type": "n8n-nodes-base.telegram",
      "position": [
        4512,
        1840
      ]
    },
    {
      "id": "2bf9864a-9db8-4f40-8928-6ddb4f395239",
      "name": "Delete Row from Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4752,
        1840
      ]
    },
    {
      "id": "c6a72a21-b298-4e46-8fdf-ae7a9f36844e",
      "name": "Send Error Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        4512,
        2128
      ]
    },
    {
      "id": "d7b6dbe0-b0ed-45b2-b1df-dea70af43b84",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4288,
        1840
      ]
    },
    {
      "id": "10b68de2-086f-44c4-a7ef-8520f54bb553",
      "name": "Sticky Note - Config",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        1808
      ],
      "parameters": {
        "width": 284,
        "height": 482,
        "content": "## ⚙️ Config — Edit This First\n\nSet these 2 values before activating:\n\n* `botToken` - Your Telegram bot token from @BotFather\n* `sheetId` - ID from your Google Sheets URL\n\nAll other nodes reference va"
      }
    },
    {
      "id": "bff60fff-9cf5-47be-babe-b7acf67ea595",
      "name": "Sticky Note - State Management1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        1616
      ],
      "parameters": {
        "width": 688,
        "height": 292,
        "content": "## 📋 State Management via Google Sheets\n\n**The problem:** Each Telegram message triggers a separate workflow execution with no shared memory.\n\n**The fix:** Google Sheets acts as a bridge.\n\n- **Save Pe"
      }
    },
    {
      "id": "8bca4062-f765-4e5b-a36f-7c97d97c4e12",
      "name": "Sticky Note - Collect IDs1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        1760
      ],
      "parameters": {
        "width": 456,
        "height": 230,
        "content": "## 📁 Collect IDs\n\nCarries all required data forward into the rest of the workflow:\n- `chatId` — who to reply to\n- `personFileId` — Telegram file ID of person photo\n- `garmentFileId` — Telegram file ID"
      }
    },
    {
      "id": "971a0a2c-acef-448f-8ed5-8adbe810f6c8",
      "name": "Sticky Note - File URL Resolution1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2048,
        1760
      ],
      "parameters": {
        "width": 792,
        "height": 226,
        "content": "## 🔗 Telegram File URL Resolution\n\nTelegram does **not** give you a direct download URL in the message. It only gives a `file_id`.\n\nTo get the actual image you must:\n1. Call `getFile?file_id=...` → re"
      }
    },
    {
      "id": "97a0e691-7408-40dd-ad9a-bf058cc45fda",
      "name": "Sticky Note - Polling Loop1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3536,
        2048
      ],
      "parameters": {
        "width": 668,
        "height": 252,
        "content": "## ⏱️ Polling Loop\n\nThe Try-On API is **asynchronous** — submitting a job returns a `jobId`, not the result immediately.\n\nThis loop:\n1. Waits 15 seconds\n2. Calls the status endpoint with the `jobId`\n3"
      }
    },
    {
      "id": "c794ec17-2a15-4624-b401-80edc061c511",
      "name": "Sticky Note - Download Result1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4240,
        1600
      ],
      "parameters": {
        "width": 436,
        "height": 222,
        "content": "## ⬇️ Download Result Image\n\nThe Try-On API returns an `imageUrl` (a signed URL). Telegram's `sendPhoto` with a URL can fail if the URL expires or requires auth headers.\n\nThis node downloads the image"
      }
    },
    {
      "id": "33934043-0a35-4283-8917-9e8fd4a06a92",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1536,
        1792
      ],
      "parameters": {
        "width": 1068,
        "height": 580,
        "content": "# 👗 Virtual Try-On Telegram Bot\n\n## What this workflow does\nThis bot lets users virtually try on clothing via Telegram. A user sends a **person photo**, then a **garment photo** (with caption `garment"
      }
    }
  ],
  "connections": {
    "Has Photo?": {
      "main": [
        [
          {
            "node": "Is Garment Photo?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Welcome Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Collect IDs": {
      "main": [
        [
          {
            "node": "Send Processing Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge State": {
      "main": [
        [
          {
            "node": "Is Job Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Send Result Photo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⚙️ Config": {
      "main": [
        [
          {
            "node": "Has Photo?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Job ID": {
      "main": [
        [
          {
            "node": "Wait 15 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Job Failed?": {
      "main": [
        [
          {
            "node": "Send Error Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 15 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 15 Seconds": {
      "main": [
        [
          {
            "node": "Check Job Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Job Status": {
      "main": [
        [
          {
            "node": "Merge State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Job Complete?": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Is Job Failed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Extract Message Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Person Saved?": {
      "main": [
        [
          {
            "node": "Collect IDs",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ask for Person First",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Garment Photo?": {
      "main": [
        [
          {
            "node": "Lookup Person from Sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save Person to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Result Photo": {
      "main": [
        [
          {
            "node": "Delete Row from Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit Try-On Job": {
      "main": [
        [
          {
            "node": "Extract Job ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Message Info": {
      "main": [
        [
          {
            "node": "⚙️ Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Person File Path": {
      "main": [
        [
          {
            "node": "Set Person Download URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Person to Sheet": {
      "main": [
        [
          {
            "node": "Ask for Garment Photo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Person Image": {
      "main": [
        [
          {
            "node": "Download Garment Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Garment File Path": {
      "main": [
        [
          {
            "node": "Set Garment Download URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Garment Image": {
      "main": [
        [
          {
            "node": "Submit Try-On Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Processing Message": {
      "main": [
        [
          {
            "node": "Get Person File Path",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Person Download URL": {
      "main": [
        [
          {
            "node": "Get Garment File Path",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Person from Sheet": {
      "main": [
        [
          {
            "node": "Has Person Saved?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Garment Download URL": {
      "main": [
        [
          {
            "node": "Download Person Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}