John Stuart
John Stuart

Reputation: 33

JavaScript in Zapier to loop API calls using pagination

I have a GET request in Zapier using this API to get a list of yoga classes from booking system MindBody; https://developers.mindbodyonline.com/PublicDocumentation/V6#get-classes

Zapier does have a feature to automatically GET ‘all’ results even the max Limit is 200 and the Zap needs to GET the next page of results. By default, I can get a Limit of 200 results with offset of 0.

I need Zapier to Get the first 200, increase the offset by 200, get results 200-400, and so on. The end result would could be 650 results all combined in the Zap that I can then use in another task (Count, sum, find, etc)

How do I use Zapier Code task to incrementally loop/GET all items in a JSON list using these parameters:

Example pagination information returned in the response body:

https://developers.mindbodyonline.com/PublicDocumentation/V6#pagination

{ "PaginationResponse": { "RequestedLimit": 10, "RequestedOffset": 20, "PageSize": 10, "TotalResults": 128 }, "Classes": [ . . . ] }

Sample GET and response in Zapier today;

SAMPLE DATA IN (GET Request)

json_key:Visits unflatten:yes headers: Content-Type:application/json SiteId:xxx API-Key:xxx Name:xxx url:https://api.mindbodyonline.com/public/v6/client/clientvisits data: Limit:200 StartDate:2015-01-01T00:00:00 EndDate:2099-01-01T00:00:00 ClientID:xxx Offset:0 As_json:no

SAMPLE DATA RETURNED

Visits: 1: ClassId:xxx LastModifiedDateTime:0001-01-01T00:00:00Z MakeUp:false AppointmentId:0 ServiceName: AppointmentGenderPreference:None EndDateTime:2019-12-11T08:15:00 ClientId:xxx LateCancelled:false Action:None ServiceId: SiteId:xxx SignedIn:true StartDateTime:2019-12-11T07:15:00 StaffId:x LocationId:x WebSignup:false ProductId: AppointmentStatus:None Id:xxx Name:xxx 2: ClassId:xxx LastModifiedDateTime:0001-01-01T00:00:00Z MakeUp:false AppointmentId:0 ServiceName: AppointmentGenderPreference:None EndDateTime:2019-12-11T09:30:00 ClientId:xxx LateCancelled:false Action:None ServiceId: SiteId:xxx SignedIn:true StartDateTime:2019-12-11T08:30:00 StaffId:xxx LocationId:xx WebSignup:false ProductId: AppointmentStatus: None Id:xxx Name:xxx

PaginationResponse: TotalResults:2 PageSize:2 RequestedOffset:0 RequestedLimit:

UPDATE 12/19/2019: 1) Call endpoint; https://api.mindbodyonline.com/public/v6/client/clientvisits with query params; StartDate: 2015-01-01T00:00:00 EndDate: 2099-01-01T00:00:00 Offset: 0 ClientID: XXX Limit: 200 Headers; Name: xxx SiteId: xxx Api-Key: xxx Content-Type: application/json

Sample Response in Postman: { "PaginationResponse": { "RequestedLimit": 200, "RequestedOffset": 0, "PageSize": 2, "TotalResults": 2 }, "Visits": [ { "AppointmentId": 0, "AppointmentGenderPreference": "None", "AppointmentStatus": "None", "ClassId": xxx, "ClientId": "xxx", "StartDateTime": "2019-04-27T09:45:00", "EndDateTime": "2019-04-27T10:45:00", "Id": xxx, "LastModifiedDateTime": "0001-01-01T00:00:00Z", "LateCancelled": false, "LocationId": 1, "MakeUp": false, "Name": "Yoga Barre", "ServiceId": null, "SignedIn": true, "StaffId": xxx, "WebSignup": false, "Action": "None" }, { "AppointmentId": 0, "AppointmentGenderPreference": "None", "AppointmentStatus": "None", "ClassId": xxx, "ClientId": "xxx", "StartDateTime": "2019-07-19T16:45:00", "EndDateTime": "2019-07-19T17:45:00", "Id": 273726, "LastModifiedDateTime": "0001-01-01T00:00:00Z", "LateCancelled": false, "LocationId": 1, "MakeUp": false, "Name": "Meditation", "ServiceId": null, "SignedIn": true, "StaffId": xxx, "WebSignup": false, "Action": "None" } ] }

IF the TotalResults = 201 or more, the requested offset should be set to 200 and loop again, and so on. The only data I need in the response is "SignedIn" which I can have zapier count or sum in a later step if all of the ClientVisits are collected together. Hope that makes sense!

Upvotes: 1

Views: 649

Answers (1)

Michael Case
Michael Case

Reputation: 518

I would recommend using the Python code module offered by Zapier to achieve this. From what you have described thus far it seems like you are using the webhooks zap which is very useful for quickly making HTTP requests but can lack in fine tuning aspects.

I am not sure what trigger you would like to use to have this zap flow execute so I will just assume you would like it to happen at a specific time once per day. So we use the scheduler zap as the trigger. The action step will be code by Zapier using the Python module. Please see the code below:

import requests

def send_request(url):

    headers = {
        "Api-Key" : "yourApiKey",
        "SiteId" : "yourSiteID",
        "Authorization" : "staffUserToken"
        }

    result = requests.get(url, headers=headers)
    return result



def main():

    offset = 0
    limit = 50
    total_results = 0
    class_data = []

    while True:
        result = send_request(f"api.mindbodyonline.com/public/v6/ckass/classes?limit={limit}&offset={offset}")

        if not result.ok: # Bad request
            break

        result = result.json()

        if not total_results:
            total_results = result.get('PaginationResponse', {}).get('TotalResults', 0)

        if offset >= total_results: # We have exceeded the total number of results available
            break

        temp_class_data = result.get('Classes')
        for data in temp_class_data:
            class_data.append({
                    "ClassScheduleID" : data.get("ClassScheduleID"),
                    "Clients" : data.get("Clients"),
                    "MaxCapacity" : data.get("MaxCapacity"),
                    "TotalBooked" : data.get("TotalBooked")
                    })

        offset += limit

    return class_data

return main()

Using Python's requests library you can formulate your own HTTP requests. We can paginate through the results using a while loop to increment our offset variable. I don't use this service so I chose some arbitrary data points to return for whatever step you would like to use next. With the code above I am returning a list of dictionary objects. Because of this any subsequent action steps will execute on each unique result. So if after running the above code my class_data list holds 3 separate results the following action steps will execute on each of those steps individually.

Hopefully this helps. I made a few assumptions about what you are trying to achieve. Let me know if anything is unclear or you have any additional questions.

Upvotes: 1

Related Questions