{
  "name": "Track BlueSky post engagement metrics in Google Sheets automatically",
  "nodes": [
    {
      "id": "fb306bc5-06c1-43f9-847e-e137508e8425",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1232,
        -16
      ]
    },
    {
      "id": "c36fba80-c89f-42ea-ae06-20ff592a8bfc",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -432,
        -16
      ]
    },
    {
      "id": "86c103ad-5359-4d8b-a977-12dc2252eac2",
      "name": "Get Post Stats",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        560,
        0
      ]
    },
    {
      "id": "276afa3f-3de1-4a9c-ad98-02e5a58b8d60",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        944,
        0
      ]
    },
    {
      "id": "bd75f8c6-b009-43b0-8f46-9714c9309fc2",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -1024,
        -16
      ]
    },
    {
      "id": "4f57d122-012f-4185-8f23-812acc87e00d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        -240
      ],
      "parameters": {
        "width": 640,
        "height": 496,
        "content": "# 📈 Analytics Bot - How To Use\n**Goal:** Keep your engagement stats (Likes, Reposts, Replies) updated automatically in the same Google Sheet that you use for content scheduling . Make sure your Google"
      }
    },
    {
      "id": "ad79671f-e383-4456-9cd8-d55bc58b29dd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -224
      ],
      "parameters": {
        "width": 256,
        "height": 192,
        "content": "### 4- The Gatekeeper\nChecks that 'Posted At' and 'Post Link' are not empty to prevent errors on blank or failed rows.\n\nThen it only allows posts where 'Posted At' date is within the last 14 days.\n"
      }
    },
    {
      "id": "78a1f0b3-2661-413f-8aea-d3cf8103f02d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        -224
      ],
      "parameters": {
        "width": 288,
        "height": 176,
        "content": "### 1- START HERE \nEnter your BlueSky Handle (e.g., steve.bsky.social), App Password and timezone (eg: America/Los_Angeles or Europe/Berlin etc) here.\n\n[Find your timezone name here](https://en.wikipe"
      }
    },
    {
      "id": "a2d78b89-7a98-473a-abc4-c052346f1094",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        144
      ],
      "parameters": {
        "width": 256,
        "height": 144,
        "content": "### 2- Get access token\nAuthenticates with BlueSky to retrieve an Access Token. This token is used for all subsequent API calls."
      }
    },
    {
      "id": "73cc8432-0844-428a-9e60-11cd573ae9f2",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -176
      ],
      "parameters": {
        "width": null,
        "height": 144,
        "content": "### 3- Google sheets rows \nFetches all rows where Status is 'Posted'. To test, ensure your sheet has at least one row marked as 'Posted'."
      }
    },
    {
      "id": "9474744d-e05d-4ce5-93eb-9decda6b5e53",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -224
      ],
      "parameters": {
        "width": 272,
        "height": 192,
        "content": "### 6- Resilient Fetcher\nFetches post metrics from BlueSky.\nConfigured to \"Continue on Error\". If a post was deleted from BlueSky, this node returns an error JSON instead of crashing the workflow."
      }
    },
    {
      "id": "69564433-dd8d-49b6-bc1d-f9645be6095c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -224
      ],
      "parameters": {
        "width": 272,
        "height": 192,
        "content": "### 7- Safe Updater \nUpdates the Google Sheet.\nUses special \"Safe Logic\" (|| 0). If the post was deleted (returns 404), it writes 0 into the stats columns instead of breaking the automation."
      }
    },
    {
      "id": "f49c2556-07eb-44be-b21a-f3a7fd248912",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        144
      ],
      "parameters": {
        "width": 320,
        "height": 192,
        "content": "### 5- The Batch Processor \nThis node takes the filtered list of \"Active Posts\" (from the last 14 days) and processes them one by one.\n\nIt ensures that if one post fails (e.g., deleted), it doesn't st"
      }
    },
    {
      "id": "5706bed9-7b6d-446c-99cf-e336ca958260",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -336
      ],
      "parameters": {
        "width": 672,
        "height": 704,
        "content": "# Input"
      }
    },
    {
      "id": "f945d73e-f59a-44b5-98a1-9bd1094f9957",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -336
      ],
      "parameters": {
        "width": 944,
        "height": 704,
        "content": "# Processing"
      }
    },
    {
      "id": "972cd0de-e7e7-41e9-ae39-35f2583d623d",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        240,
        -16
      ]
    },
    {
      "id": "141f80a2-7974-405a-85f3-d1601af95ad3",
      "name": "Filter1",
      "type": "n8n-nodes-base.filter",
      "position": [
        -112,
        -16
      ]
    },
    {
      "id": "9d4160cc-fc59-4ccf-aa1d-bd96c9d5ccbd",
      "name": "BlueSky Auth",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -784,
        -16
      ]
    }
  ],
  "connections": {
    "Filter1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BlueSky Auth": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configuration": {
      "main": [
        [
          {
            "node": "BlueSky Auth",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Post Stats": {
      "main": [
        [
          {
            "node": "Update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Get Post Stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Filter1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update row in sheet": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}