{
  "name": "Generate and post Apple App Store review replies with Anthropic Claude",
  "nodes": [
    {
      "id": "8730f723-83fa-4dcb-8324-bbdc095efa29",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -32
      ],
      "parameters": {
        "width": 640,
        "height": 928,
        "content": "## Generate and post Apple App Store review replies with Anthropic Claude, Google Drive and App Store Connect API \nThis workflow empowers app developers and community management teams by automating th"
      }
    },
    {
      "id": "e53b3d28-02d2-40b2-9108-2e19b4f9f082",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -64
      ],
      "parameters": {
        "width": 256,
        "height": 240,
        "content": "## FIRST STEP: GENERATE AI RESPONSES\nAt 10 am, download the previous day's reviews from Apple App Store and generate AI responses in a spreadsheet in *ToReview* folder. Send a Slack message with the u"
      }
    },
    {
      "id": "49138ab4-878a-434a-bf9d-29a4027375d8",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        336
      ],
      "parameters": {
        "width": 256,
        "height": 224,
        "content": "## SECOND STEP: HUMAN IN THE LOOP\nA human reviews the spreadsheet, makes any required adjustments to the responses and moves the spreadsheet to a different folder called *ToSubmit*"
      }
    },
    {
      "id": "4aac0d74-1e71-4104-8032-e956d9b3cbf5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        704
      ],
      "parameters": {
        "width": 256,
        "height": 224,
        "content": "## THIRD STEP: POST RESPONSES\nAt 5pm, fetch the spreadsheets in *ToSubmit* folder, post the responses using the Apple App Store Connect API, create execution logs and move the processed spreadsheets t"
      }
    },
    {
      "id": "e20d885f-8c4f-479c-874a-bef5845079ed",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        704
      ],
      "parameters": {
        "width": 192,
        "height": 240,
        "content": "Search the files in *ToSubmit* folder"
      }
    },
    {
      "id": "a2b60e1f-7cd5-4f4f-8e73-dd9b221d6293",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        704
      ],
      "parameters": {
        "width": 192,
        "height": 240,
        "content": "Download responses sheet"
      }
    },
    {
      "id": "617041ff-cab9-49b6-92e1-49c68d65be21",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2064,
        688
      ],
      "parameters": {
        "width": 384,
        "height": 256,
        "content": "Post responses using App Store Connect API: https://developer.apple.com/documentation/appstoreconnectapi/post-v1-customerreviewresponses"
      }
    },
    {
      "id": "f852eebe-7a34-427a-9896-dcb5e9cf5eba",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2480,
        528
      ],
      "parameters": {
        "width": 368,
        "height": 544,
        "content": "### Data table fields\n* reviewID: App Store Identifier for each review.\n* app_id: Corresponding application's app id.\n* successful: Boolean status indicating the posting success."
      }
    },
    {
      "id": "e10dd702-4236-44c7-a92e-5584fb611090",
      "name": "Trigger posting responses",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1200,
        768
      ]
    },
    {
      "id": "c3a99a3c-d3aa-4089-865a-de1791889dc8",
      "name": "JWT",
      "type": "n8n-nodes-base.jwt",
      "position": [
        2160,
        144
      ]
    },
    {
      "id": "6ade90b9-751a-4f1f-aa06-ceedf052c626",
      "name": "Fetch app id and name",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        -16
      ]
    },
    {
      "id": "49b71085-3bc1-4991-ad9e-dbcce799a205",
      "name": "HTTP Request - App Store Reviews",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2368,
        144
      ]
    },
    {
      "id": "1154b9d7-77ad-46cb-8274-ed9d796a96a7",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        -192
      ],
      "parameters": {
        "width": 448,
        "height": 352,
        "content": "### Data table fields \n* app_id: Apple app id for each app. App id can be found in the Apple App Store url of the app. For example the app id of the app with url https://apps.apple.com/us/app/claude-b"
      }
    },
    {
      "id": "548e6542-150b-43e9-bb0e-aa3c1563584d",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        -224
      ],
      "parameters": {
        "width": 624,
        "height": 224,
        "content": "Collect all the reviews and responses in a spreadsheet, sorted by rating"
      }
    },
    {
      "id": "cc9bbad3-9cf5-4ae7-a8cf-52ddabf29251",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2752,
        -224
      ],
      "parameters": {
        "width": 208,
        "height": 224,
        "content": "Upload the spreadsheet to \"ToReview* folder"
      }
    },
    {
      "id": "59b82ea7-7228-4f32-8717-53b99fa5b3fc",
      "name": "Send to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        3024,
        -160
      ]
    },
    {
      "id": "be34c4db-073c-488e-85a1-0de8bf5a5cf6",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2976,
        -224
      ],
      "parameters": {
        "width": 224,
        "height": 224,
        "content": "Send the Google Drive url of the file in a Slack message"
      }
    },
    {
      "id": "4a3091d3-3d2f-4e9a-ab59-cbedceb60366",
      "name": "Sticky Note18",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        48
      ],
      "parameters": {
        "width": 416,
        "height": 240,
        "content": "Fetch reviews from App Store Connect API: https://developer.apple.com/documentation/appstoreconnectapi/get-v1-apps-_id_-customerreviews"
      }
    },
    {
      "id": "abdde680-74ae-4030-9e18-8c1dadd069d2",
      "name": "Split Out fetched reviews",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2592,
        144
      ]
    },
    {
      "id": "69752f2d-a82c-42b8-bf10-4e03ad23a36e",
      "name": "Sticky Note19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2960,
        32
      ],
      "parameters": {
        "width": 192,
        "height": 256,
        "content": "If there are no reviews for the app from yesterday, continue the loop with the next app "
      }
    },
    {
      "id": "9aac9cb5-2770-4fd5-9528-0664b1a74140",
      "name": "Fetch list of applications",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1440,
        -16
      ]
    },
    {
      "id": "625eb4c8-1d01-4505-a158-2ca5a64e9edb",
      "name": "Loop over apps",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1888,
        -16
      ]
    },
    {
      "id": "076db3bc-2b0f-4fc9-9c7f-637cda4cd507",
      "name": "Get rid of empty items",
      "type": "n8n-nodes-base.filter",
      "position": [
        2160,
        -160
      ]
    },
    {
      "id": "df97eb53-a4d4-4655-a4b5-e9781c252ef1",
      "name": "Sort",
      "type": "n8n-nodes-base.sort",
      "position": [
        2368,
        -160
      ]
    },
    {
      "id": "e7c03979-0c11-4775-8835-4ed88bcc468f",
      "name": "Convert to File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        2592,
        -160
      ]
    },
    {
      "id": "2a843a6f-d36b-40db-907d-9b4e7ae0014b",
      "name": "Upload file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2816,
        -160
      ]
    },
    {
      "id": "67e1ba4d-46a3-4257-af6f-9e4552a3fd1c",
      "name": "Fetch yesterday's reviews",
      "type": "n8n-nodes-base.filter",
      "position": [
        2816,
        144
      ]
    },
    {
      "id": "aeb78c41-9235-422d-897b-8f742411e9f3",
      "name": "Any reviews yesterday?",
      "type": "n8n-nodes-base.if",
      "position": [
        3008,
        144
      ]
    },
    {
      "id": "ad840df5-221a-436d-b734-2080ad620816",
      "name": "Fetch fields required by LLM",
      "type": "n8n-nodes-base.set",
      "position": [
        3248,
        128
      ]
    },
    {
      "id": "e409e93c-a51e-48d9-82fb-be178b89659a",
      "name": "Aggregate reviews for LLM use",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3456,
        128
      ]
    },
    {
      "id": "5f6cdf29-e9ee-42ef-9c78-cbc51f587f4a",
      "name": "LLM Response Generator",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        3664,
        128
      ]
    },
    {
      "id": "6f5fc2f9-82db-4c1b-a716-4bd89ce376b7",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        3664,
        352
      ]
    },
    {
      "id": "5742ae4d-66d9-42ef-93be-52e61b83e8cc",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        3824,
        352
      ]
    },
    {
      "id": "dca8dcf4-f7f8-4e87-b208-ca52a72c7d46",
      "name": "Split responses",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3984,
        128
      ]
    },
    {
      "id": "1f488681-a855-4173-a024-3feb0570bb75",
      "name": "Trigger download",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1200,
        -16
      ]
    },
    {
      "id": "8935b8c3-b1d4-4125-b195-7487a6d5c6ec",
      "name": "JWT1",
      "type": "n8n-nodes-base.jwt",
      "position": [
        2096,
        768
      ]
    },
    {
      "id": "87eb3f9f-b743-49db-a967-7aee526bb63b",
      "name": "HTTP Request - Respond to App Store reviews",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2288,
        768
      ]
    },
    {
      "id": "2ddb4501-0666-4c89-9b8f-cf473dc01269",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        944
      ],
      "parameters": {
        "width": 192,
        "height": 272,
        "content": "After posting all responses, move the spreadsheet to Archived folder"
      }
    },
    {
      "id": "3e5ede65-72ed-4593-89e4-0313d196fe04",
      "name": "Search responses ready to be posted",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1424,
        768
      ]
    },
    {
      "id": "446dc214-1342-4baa-bbf6-5f1772b601ef",
      "name": "Download file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1648,
        768
      ]
    },
    {
      "id": "adf83d9e-1c59-4dd0-b1e6-1c76b578c62b",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1872,
        768
      ]
    },
    {
      "id": "60b7ee93-9e28-4914-9e92-ef285ee27654",
      "name": "Move spreadsheet to Archived folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1872,
        1040
      ]
    },
    {
      "id": "0fd8bee9-f926-45a9-a094-2deb0748012f",
      "name": "Create a success log for the review",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2560,
        688
      ]
    },
    {
      "id": "b701bacd-df4a-4608-a74d-b918936bd4d3",
      "name": "Create an errror log for the review",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2560,
        880
      ]
    }
  ],
  "connections": {
    "JWT": {
      "main": [
        [
          {
            "node": "HTTP Request - App Store Reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JWT1": {
      "main": [
        [
          {
            "node": "HTTP Request - Respond to App Store reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Send to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Move spreadsheet to Archived folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop over apps": {
      "main": [
        [
          {
            "node": "Get rid of empty items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "JWT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split responses": {
      "main": [
        [
          {
            "node": "Loop over apps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger download": {
      "main": [
        [
          {
            "node": "Fetch list of applications",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "JWT1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "LLM Response Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Fetch app id and name": {
      "main": [
        [
          {
            "node": "Loop over apps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Any reviews yesterday?": {
      "main": [
        [
          {
            "node": "Fetch fields required by LLM",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop over apps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get rid of empty items": {
      "main": [
        [
          {
            "node": "Sort",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM Response Generator": {
      "main": [
        [
          {
            "node": "Split responses",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop over apps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "LLM Response Generator",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Fetch yesterday's reviews": {
      "main": [
        [
          {
            "node": "Any reviews yesterday?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out fetched reviews": {
      "main": [
        [
          {
            "node": "Fetch yesterday's reviews",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop over apps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger posting responses": {
      "main": [
        [
          {
            "node": "Search responses ready to be posted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch list of applications": {
      "main": [
        [
          {
            "node": "Fetch app id and name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch fields required by LLM": {
      "main": [
        [
          {
            "node": "Aggregate reviews for LLM use",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate reviews for LLM use": {
      "main": [
        [
          {
            "node": "LLM Response Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - App Store Reviews": {
      "main": [
        [
          {
            "node": "Split Out fetched reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search responses ready to be posted": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Respond to App Store reviews": {
      "main": [
        [
          {
            "node": "Create a success log for the review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create an errror log for the review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}