Working with Availability

Table of contents:

Introduction

We're going to use the API as a backend for appointment calendars, like an AirBnB for X. Different resources can have their own calendar (just like a mentor has appointment slots). We can then search for available time based on rules that the mentors can set themselves, e.g. only available on Tuesdays from 3-5pm and Fridays from 1-4pm. Rules/filters like these will be applied at runtime and are also Timezone aware - in this case, so customers can find timeslots that are within daytime hours if they're located in another country.

In this exercise, we'll assume our mentor is Doc Brown and our mentee is Marty McFly.

We're going to assume that we already have created a resource (you dont need to actually do this for now). Follow the guide to see how that works.

Let's get to it!

1. Define business logic as filters

First we'll define some business logic, namely availability filters. Filters are passed to the /findtime endpoint as rules that must be satisfied in the query. Filters are quite powerful and can be combined to exclude timeranges - consider it a query language of sorts. Check out the Filters Reference for a complete list and explanation of available filters.

For our mentor (Doc Brown) <=> mentee (Marty McFly) scenario, let's assume that the mentor is located in Los Angeles and the mentee (who performs the availability search) is in Copenhagen. Furthermore, the mentor has defined "opening hours" on Tuesdays from 3-5pm and Fridays from 1-4pm. These constrainst can be written as filters like this:

// Query filters example
"filters": {
  "or": [
    { 
      "specific_day_and_time": {
      	"day": "Tuesday",
      	"start": 15,
      	"end": 17,
      	"timezone": "America/Los_Angeles"
    	}
    },
    {
      "specific_day_and_time": {
        "day": "Friday",
        "start": 13,
        "end": 16,
        "timezone": "America/Los_Angeles"
      }
    }
  ],
  "and": [
    {
      "daytime": {
        "timezone": "Europe/Copenhagen"
      }
    }
  ]
}

Short explanation:
The first two "specific_day_and_time" are inside an OR section, which means that either the first filter or the second filter should be satisfied. The "daytime" filter in the AND section means that all results from the OR should also be within that filter. If we had added more filters in the AND, it would have meant that all those filters should be satisfied at the same time (overlapping).

📘

Note that we are using a 24-hour clock in the start/end time fields (3:00pm is 15:00)

📘

Re-using filters across requests

You can use filter collections to save your filters in Timekit and reference them in your requests.

2. Call the FindTime endpoint

The Find Time algorithm is where the magic happens. It will essentially loop through the resources calendars and find timeslots that satisfy the supplied filters. You can add multiple resources (and their calendars) that the algorithm must take into account (if the mentee Marty McFly for instance connected his own Google Calendar), which is what we are going to do.

So, in lay mans terms, this is what we are querying (take a deep breath):
Find available timeslots within the next 3 weeks where both Doc Brown and Marty McFly are available for 1 hour, which must be either a Tuesday from 3-5pm or a Friday from 1-4pm (in Los Angeles timezone) and must be within daytime (7am to 11pm in Copenhagen timezone). Phew, that was quite a mouthful.

Here's the cURL request:

# Request example
# [POST] /findtime
curl -X POST \
     -H 'Timekit-OutputTimestampFormat: Y-m-d H:i:s' \
     --user :live_api_key_7nzvc7wsBQQISLeFSVhROys9V1bUJ1z7 \
     -d '{
           "emails": [
             "[email protected]",
             "[email protected]"
           ],
           "filters": {
             "or": [
             	 { "specific_day_and_time": {"day": "Tuesday", "start": 15, "end": 17, "timezone": "America/Los_Angeles"}},
               { "specific_day_and_time": {"day": "Friday", "start": 13, "end": 16, "timezone": "America/Los_Angeles"}}
             ],
             "and": [
               { "daytime": {"timezone": "Europe/Copenhagen"}}
             ]
           },
           "future": "4 weeks",
           "length": "1 hour"
         }' \
     https://api.timekit.io/v2/findtime
// Request example
// [POST] /findtime

var timekit = require('timekit-sdk');

timekit.configure({
  app: 'docs'
  outputTimestampFormat: 'Y-m-d H:i:s'
});

timekit.setUser([email protected], FluxCapacitator);

timekit.findTime({
  "emails": [
    "[email protected]",
    "[email protected]"
  ],
  "filters": {
    "or": [
      { "specific_day_and_time": {"day": "Tuesday", "start": 15, "end": 17, "timezone": "America/Los_Angeles"}},
      { "specific_day_and_time": {"day": "Friday", "start": 13, "end": 16, "timezone": "America/Los_Angeles"}}
    ],
	  "and": [
	    { "daytime": {"timezone": "Europe/Copenhagen"}}
    ]
  },
  "future": "4 weeks",
  "length": "1 hour"
  }
}).then(function(response) {
	console.log(response)
})

If it finds any available timeslots, it should return an array of those, looking like this:

// Response example
// [POST] /findtime
{
	"data": [
		{
			"start": "2015-07-17 13:00:00",
      "end": "2015-07-17 14:00:00"
    },
    {
      "start": "2015-07-24 13:00:00",
      "end": "2015-07-24 14:00:00"
    },
    {
      "start": "2015-07-31 13:00:00",
      "end": "2015-07-31 14:00:00"
    }
  ]
}

Now it's just up to Marty to pick one of the timeslots and book Doc Brown at that time.

Good job, Doc.