DEV Community 👩‍💻👨‍💻

Cover image for How to build a Calendly clone using Airkit's low code platform
Ismaen Aboubakare 🥑 for Airkit

Posted on

How to build a Calendly clone using Airkit's low code platform

I use Calendly a lot in my day to day to book meetings that fit within my schedule, and as I continued to use it, I wanted to see if I could build the core functionality of the tool in Airkit. There were a few things I wanted to make sure we could do in Airkit, which is connect to both google calendar and zoom, be able to programmatically get all of the free slots on my calendar in 30 minute increments, and programmatically generate zoom links attached to calendar invites.

With that in mind, this tutorial will walk through the steps on how to build a Calendly clone, integrated with Google Calendar and Zoom.

Application Overview

When a user visits the application, they will see a calendar with an availability list of 30 minute appointment slots where they can choose and confirm an appointment time of their choice.

This image has an empty alt attribute; its file name is Calendly-Application-Overview-1.png

Once the user selects the time slot. They will be presented with a form where they enter details about themselves (name and email address), add additional guests, and a message for the meeting. When they click on Schedule Event, Airkit will then create an appointment, send out meeting invitations to all participants along with a Zoom Meeting link.

You can check the application out here: https://app.airkit.com/calendly

Prerequisites

To build along with this tutorial, you will need a few things to get started:

Creating APIs for the Google Calendar and Zoom Meetings

Let’s start with the Google Calendar API. One of the first things you will need to do to get started is create a project in the Google Developer Console. You will need to create a new project called Calendly Airkit and then select it. Next add the Google Calendar API.

This image has an empty alt attribute; its file name is MvuuRfsXFwe6eyrx1LSCS-5_aPrx9JMCfVewvs5A5R0gZFLRzzFvHgrOocYr1xye_JOqMbQMACZXfALK57vVqSvJJtzENlIeNJuRhhL9s5iQ5F14O95OQiNKAZQkUGwDqqz7hc6nHMGygnkmo45wzOJuLthEtZ7-aXp2LBJh20E62aOLuPi1VQMlYQ

After enabling the Google Calendar API, you will need to configure the Credentials with an OAuth client id.

This image has an empty alt attribute; its file name is W4jKyNXZM5NY52GJ-MqpohrPPpjYf8kPtHWuU2cwF2DanW-EO-V8GxLFjreTvZa9PYMo2yX9wkESQRWlRcG7krs2bradoZaanw5yaPnHIu5uou2CmTRb36Rzs8a6ztg3xRJhF4Zohnf8UVmEPwJHUzLwSuGF7axT7QW3UOVVdJglLkpa3GXnV43E-Q

Provide the OAuth consent screen with the appropriate information and then you will need configure any scopes which are necessary for the Google Calendar API to work with this newly established Project:

  • Google Calendar API – /auth/calendar
  • Google Calendar API – /auth/calendar.readonly
  • Google Calendar API – /auth/calendar.events

This image has an empty alt attribute; its file name is 3zOMPQiEKrc3Ichm1AAiCW9rqslGpshTv31kKKZApaRLloboTsfN04_dlKKiKHSWIjidDdHgFldjkdFA1PASO9V_YMfh-08OyVmPMAXxBd1TFO0XnVzoHxOIiQRUkaasrdHl2ky7YB5o2YsLstutQo9gsB6l6LJ4zYgfcn9jHNj6E8pEYLKhC0YWPQ

Now are you able to create the OAuth Credential. You will need the redirect URI which can be found in this doc. Because my organization is in the US region, I use the below redirect URI.

“`

https://us.api.prod.airkit.com/internal/sessions/v1/auth/callback

“`

Next let’s configure the Zoom Developer API. Like Google, you will need a Zoom Developer account. You will be creating an OAuth app type. The app will be an account level application.

This image has an empty alt attribute; its file name is DrJpawWYxghsFxHTzriIfxsCsvBNILv64Oj0_FS3eDhTbpHIFMpuKM_uy3kfSyx5aYsmaDz1gtmnYv5vVa0ZxULT_xroI0FaOJxaeiMMCbDuv3XYa73Jztdr0IPpEVxMxe4Ys19yyIUcclpguhvmolnXZ7ZJxx9p6XlBwsni4wzgXyvsd0B4Oz29IA

You will be using the information from the App credentials later. Like before refer to the Custom Integrations documentation for the URL information for Redirect URL and Allow List. Now you are able to create the application. Finally you will need to add Scopes:

  • View and manage all user meetings

This image has an empty alt attribute; its file name is D22kKxY2B6qWVaIgrkNUtyxDkxqQ9WQU99cSb4s-d1vnWWpQRGYEjz1uqfQDr5SOCP6KnTdZJfoInb-d4jQF6HHOQUg_6FBLL0_hQpF6qITlep5XZs0aVUM5LBygQMbgIzluO-52JrhuqAD3sPgSSN22Vn2zInENq7ABRvrjkYiH8_6N6b6GMPYxmg

All of our integrations setup on Google Cloud and Zoom are done and ready to to be integrated into Airkit.

Creating the Integration

Now that you have the API integrations setup with Zoom and Google Calendar, it’s time to create the custom integration within our Airkit application. In the Airkit Console, go to the Integration tab. We will be creating two custom integrations. First, we will create a custom integration with Zoom and then will create a connected account to our application there. Next, we will repeat this process again with Google Calendar .

Zoom Integration

Create a new Custom Integration, with a name and key that you indicate an integration with Zoom. The authentication type we are going to use is OAuth 2.0. The Integration Parameters are client_id and client_secret.

This image has an empty alt attribute; its file name is InilW5GmtBDphFyBbjogAa2_KHhUaQuR-Ft5OfZ94JL3LY9yP5wPMVTKlfWYat4PPGN83bQY4WJwl-YaklLYRsmYZMg_VtJLecIfznGiIcm7lvI0J8T3ZoeuJ2iaHf8XmJxFP6b4eP9DZCxWPLSMvcGe6P4AKRIahWuT7T83qKZp7-FlV9rAIATrKQ

The OAuth2 Configuration will be using the following configuration parameters listed below and shown in the sample:

This image has an empty alt attribute; its file name is sMBqPdFGDmyYUgxoeEzY6vZqkRu6X2u6LwqqA5LL4dGBsaTkV5QI9-rYiIz0cZuQw-HkpzGiZOQ8rTQXwP61syllBQSs8ca_E466hv9-hbVy0VJI0eYYl8oR8oPp2aNm4PVYcPbPyjwie4WfcZlVBVpDrpaj1aX_8X6rPUgfKgUgHk-NklhOf1CZ4Q

The Auth token configuration will be the following configurations:

  • Token Parameter: Header
  • Token Parameter Name: Authorization
  • Token Parameter Value Template: Bearer {token}

This image has an empty alt attribute; its file name is ZUYoYaT1EE6r9N3vxn8M-mEjAVo_aFvvXyyHAxBh0LsBhIAfuyKd5f20hSnFgpzJGd8XLh-d9Jk9r0jLx5qffRa_wcdjAkfzW8bYf4TwhyE398g3WGjilRMCXTFce_vX4mB-LryTSO9Ym4V98NBO7I-qPPPBX8E0wYWJEWstbTimZgPZkIVpAUTJGQ

Google Calendar Integration

Create a new Custom Integration, with a name and key that you indicate an integration with Google Calendar. We will follow similar steps as done for the Zoom Integration. The authentication type we are going to use is OAuth 2.0. The Integration Parameters are client_id and client_secret.

This image has an empty alt attribute; its file name is FYUNjcXQqua-C2NRcuCYxm3SDC9JJ7cOWd4BL6EkLiYLHtf1Hxevix1malnLK5MM8qvm6VDCdOe45g1LqjocDo3lwUxcQXDpp6zR_VAd797jKhAIkv_JxI0On_6yNn6lC3nCPMfxsD3EPpVOS18A9PeQwJKxUAciOk8qIKWpRHEKBbb_jr4toy8c5g

The OAuth2 Configuration will be using the following configuration parameters listed below and shown in the sample:

This image has an empty alt attribute; its file name is 9_zmMt2G8vx36tgCacb3wP8EN9CGcE-iuXbL92tJMx_KmiWSU3Hv7j3nTyayNYL-5bVSZBqWHBVs7FiCCO3LEiVBzSHaLhGPZAwgqdHoWaRmaNxDcVd7C2LZQdi91Ke3lePDTUT_N4t24bMfx0idF6lu5WckEPAWlfT-EVjdCGfBLnXdZ_9BWFqZMQ

The Auth token configuration will be the following configurations:

  • Token Parameter is Header
  • Token Parameter Name is Authorization
  • Token Parameter Value Template is Bearer {token}

This image has an empty alt attribute; its file name is 4Lt7iptIQjU-Tls8e82NDiwLyHfCn_Hy6g8s7b8yL71HdQ_vSIOs0TZqdl_lfXeUg_u-bT6oCXwFvSZV9MK-RJyMkliS9wwQZfbRB6T0w0xBGrdnalb16KEILV0mKhGtikUWvcTzNWXIj9siVLRiEX7OvCHvYPTYpF4y5ptOwtaPxvvKEeUbPSVE5A

Refer to this snippet of the video on how to pair the connected accounts for Zoom and Google Calendar API or refer to this document on Connected accounts.

Functionality through Data Flows

Now we have the integrations ready for use in the Airkit Application, next we will need to build out six Data Flows for the application for self-service appointment scheduling. Refer to the YouTube Video for complete details on how to create all these Data Flows.

First, we will create three Data Flows for finding all the available time slots on a particular day. The main Data Flow will be called “Get Free Slots” and then we will create two additional supporting Data Flows called “Merge Objects” and “Generate 30 Min Slots”.

This image has an empty alt attribute; its file name is XM3bqx3IbEY4UQrrCPe0d6yO0xV7Pum98icKlIKCKM3NMV2GGoVdSNLz2txcl2wabi75AizGu3f8K8jwb2HnWyPZhFMTbhx85GehNLoOfJL86ECVYlughYBi1pzLBcSVpEPX-Yd_TUugUKi7qpteN2N0sMay-D7FRCpGIvbSuQSslSmOKF0lrFFRIg

Get Free Slots Data Flow: We will be setting the appointment window starting time and ending time, finding the existing appointments via the Google Calendar API, and creating a list of 30 minute available time slots.

Google Calendar API expects the date to be in RFC 3339 format. We will need to use the following Airscript function: FORMAT_DATETIME in order to format the date into RFC 3339.

This image has an empty alt attribute; its file name is WMN7r3x_ACrSTfKP_wgFPrpMt5L7X3Rqygd48mH7m-Wff7LR0ofo4_FYCURIe7dbpT1sVuzEURCVdsmbxYtqirY0YXBAOcyXck30CVfU7WiKL2XBZbej0lxBbb6I5BrY3TADPT2aVwUgIb-roat_zF1oR59MT1T319A3kspZ36MKoAK5iYMrv7xoZg

We can use this FORMAT_DATE Airscript in a Transform Function for both the Start of the Day and End of the Day Variable.

<https://support.airkit.com/reference/format_datetime>

Now we will need information from Google Calendar API to find the busy times so we will leverage the integration we set up already. In order to make this request, we will use HTTP Request Data operation and use the following settings:

This image has an empty alt attribute; its file name is gd9SkwiM7Zk4e4jZ6Ae0Ee8P6BgT5QDay0_W4fIGkfuWt1SnYn9icP-GodPaKWSKaPO7DV_G6xEBOhb4jiaD_PB3JRxFOohIb9TNFaizssta1sVFx4VRtGw4nAFT3rNa1Enc-cVLDWd1ygByPBFBuX2gsSjnwJfwrlea8zqFtTExogt434INe9mIaQ

The resulting busy time slots will look like the following:

This image has an empty alt attribute; its file name is X-Cl7pDhqPONvC1rYEXVW0HzFiT8VnM6ABjuKaFlsGOtaHcNyQlNYfCwRwD9CrOi5D4uTGW7IeSKp5kvcU-aDWyPv_dff2GUF8gNZmPlPEUuy3NEQ7KwzT4hbHrttRZZ5rmIrXk4rbICYfroHaI1xuPlnL1DNSjgNENE5wQZocLXMmYat8IkHkS2IA

Merge Objects Data Flow: Since we have a few time slot objects, we will need to bring some different object data together and we will create and use another Data Flow called Merge Objects. This Data Flow will use the Airscript Function [MERGE_OBJECT](https://support.airkit.com/reference/merge_objects). Refer to the YouTube Video for more details on this Data Flow.

Additionally there will be some additional time formatting needed to produce a list of 30 minute available time slots. Key Airscript functions will be TIME_FROM_FORMAT, UPDATE_TIMEZONE, and DATETIME_FROM_FORMAT refer to the documentation to learn more about these functions.

Generate 30 min Slots Data Flow: To generate a list of available time slots, we will create another supporting Data Flow called “Generate 30 min slots”. This Data Flow will take two inputs of start_time and end_time and create an object with a list of slots in 30 minute increments. In order to accomplish the list, use a Query Expression to create the list.

This image has an empty alt attribute; its file name is s6EIGdrgA5O0Yq9Ga_J85OUNWNI0tjhrL03BQgnJQNgGnevHYum0DQ5C2L3b_O2_WRDR-iDHA8vWznPN6CfUFtK6eHgOeIcz_bE5dRi1K2ydH-Y8-8tvGPpU62YFub7_ty8Rv1sOD5WMM_xgjHdiBm93RIulQ4_weFitWr3qH-WRlioZeMDJni6kjg

The list of time slots will be used later when we build the Airkit application.

Now we will create the last three Data Flows which will schedule the Calendar event and create a Zoom Meeting. We will create another main Data Flow called “Schedule Event” and two supporting Data Flows: “Create Zoom Meeting” and “Create Google Calendar Event”.

This image has an empty alt attribute; its file name is qbs9Usdpx-W-pfDkMXW6jQo9LQKPxTneAPxGBI4Im1AWeszuY7qkmmNcv42qRWK2BVq86g1_IcYd8rooNsrKyTeG6FlQgdexVHWASyspDcmephqU2Hz7r7AIiv5Sg3kz4fyDnJMBhZo-akZ2tTbyY_6NOCOAoc6tyqFrbcWmf_mXgkwg34XWr49naA

Create Zoom Meeting Data Flow: Let’s build this Data Flow! This Data Flow takes an input of starting time and a list of emails and then makes a HTTP request to Zoom for the meeting information.

We will use the Zoom API integration we configured before and will use the HTTP Request Data operation with the following settings:

  • Service: Zoom OAuth API
  • Method: POST
  • URL: “https://api.zoom.us/v2/users/me/meetings”
  • Content type: “application/json”
  • Body will need the following parameters modified:
    • schedule_for” :
    • Meeting_invitees” : Use a query expression to all the emails to send invites to
      • FROM email IN list_of_emails SELECT { “email”: email }
    • start_time” : Use the start time and format appropriately for Zoom
      • “{{FORMAT_DATETIME(start_time, “yyyy-MM-ddTHH:mm:ss”)}}”

This image has an empty alt attribute; its file name is JLXFzwVHVbY1LySZr0FhSqlrE18smYx4SQSMQBp0jNx5DQksNCHZSoLh9q3tM4a7Bu_bJqIMHm1HPwYykk6Zn8VMKCbdrdmunqSAbdSJEatx510lbSgDwY72Uw03fgsmgyEqVHgaGVJNCu7XGaGkWEKCIKCt6iWzBXi5AZd9UYcZJ0GkmmCce55UZw

The result can be customized accordingly with a Transform operation and then sent back to the “Schedule Event” Data Flow to be used in the “Create Google Calendar Event” Data Flow.

Create Google Calendar Event Data Flow: Let’s build it! This Data Flow takes the input of the following variables: summary, start_time, end_time, list_of_emails, and a description. And then makes a HTTP request to Google Calendar API to create a Google Calendar Meeting.

We will use the Google Calendar API integration we configured before and will use the HTTP Request Data operation with the following settings:

This image has an empty alt attribute; its file name is wpYX9i2OvY8PNAL2Fg9z7i1VuHc5nghzU0xhKwXopfs0pLTlc6b-IfZBFSJvQRZHt2YkvRJfK_SZWLo2cxd81qNtPUgjHX299b5T3IgWOAYCQU15bZsyW44GEL8ufPmn3zTL4t_sf-zL53Kl8s7TLNLI5DAyKCbAhv0Nj6CfzI7-X0VBXNjgSz_q7Q

Schedule Event Data Flow: Let’s build it now! This is the main Data Flow which brings all the necessary data together to create the Google Calendar Event. The Input data variables are the following: selected_time, name, email, list_guest_email, and preparation notes which all will come from a web page form built later in the Building Airkit Application section. See the screenshot below to see how the Data Flows are configured or continue to watch the Youtube Video to see how this app is built.

This image has an empty alt attribute; its file name is MqIMYHw6YjACVFUNbf8nRUXVqF_r8iieVlZkfBoz26TVpZsCHbKWXMFbqN7zfaePkSkcnGmhzv4v0tZp1eLCxV-1DkpHXRa4IPVQNbJVuJuWXot5Ukgkc-4p5CiVivdBJ42_NmBy-8pcljiSmxtEHnQKAvAg354teidAsEErhwMFyzJoExoEAqdREw

This image has an empty alt attribute; its file name is SatVBT50r4QkrnlwaPXVbmu4J-y5DWaxg9Gm48Hs60LL2G_jlq9YNZhGyagl2w4w2HhR67TcATg_BWG55-nnbuAoNTYwbX0Sd9ftDNuUhvr_X9-zRZZ6dE-qWk81Iw-jBd2XSzG-zRaxRUyMRPpaIs6z9Oh1pm0XAtw9_WJ7GHCstAWSjRSg1-bObQ

Building the Airkit Application

Now we have the integrations and Data Flows ready for use in Airkit Application, next we will need to build out the application for self-service appointment scheduling.
In Journey Builder, add a Visit a Link Trigger to start the application, and add a webflow in the first Journey step. Then in Web Builder, we will make three Web Pages. On the first page, a self-service appointment scheduler, we will add the following key controls: Label, Container, Date Picker and Container List with two Buttons. Make sure you label all the controls appropriately.

The Web Page Tree should look like the following example:

This image has an empty alt attribute; its file name is GxfMkubV1mZA_gZIqc7iIX77EavUIepp071Jy_GFn52sP_YxbKgMCY41zq6lSDuE8fRR8YA3ZCoBdhhkq5j5WotjN7_A2BwG5FKGZwMSzGWfVEzH79ImK0Ob6WpmghmZpmZIv2eplGoEU7wpQKwvaYiwAexU3s0Nu-UE2OzYVhfS01RDTHU7RIzZ7Q

After you add these controls you can configure labels appropriately similar to what is shown in the Youtube Video or the screenshot below:

This image has an empty alt attribute; its file name is uOyG4rpdFpkQp5CxLg82fbamTW9WdknjD2VnzFCKepskXzrhzxria7Wiwh0Z9XX7kXWEBJQh3lnzaWPu-YqJ_bOdwv1FoFhD4AHLM5TY8G-goyG0GH0JS5mqzjtc8DEdWMIVxnMPruYz4X6Cm32_wiJ-Ef8htrVdDXB2lZrt1xKNvz3oqS_z5cXteA

Next, we will configure the controls for the Date and Time Slot Selection. First we will configure the Date Picker control. You will configure the Control Properties as shown below to get a one month layout.

This image has an empty alt attribute; its file name is vlFqoLIIafApCu6VJ5Zj3MSMTlUFCQh92VLBVqgdIRdBjJjDjS7967D_J1GOkTtOeanMUFs09_ESeeqJsf1eKJh9oafL4wzKWJr6HZvQgjrHRMsMae8BOw1m7V5HbO-31I8Iwnc3ItJpl3Y_D63PR9lQZSAg5bVLVUiIQkyt2j8Iwd9n6mqd2x3bnw

The selection of the date has a concurrent action of calling a Data Flow which gets all available time slots for that particular day. We use the “Get Free Slots” Data Flow, which will extract information from Google Calendar. See the screenshot for the variables to update.

This image has an empty alt attribute; its file name is Q47wTOYqyjrsU-fyXXekJ45C7Q_9svVBU_mXOzDAXjtzK1vDGniK838Mc7bjWd8mBvzZXCSQuX9gMKKs9DbjIF9N39q-AvM0Ic_iIdBbdQvJpMVS-UgbtcZBL0xszwql1d8qPGtkMsNA8FRzf9r7a4ov1Ra83pf4KgUgpmOoKfXUXN0ZFQFEy0hkqw

The variable session.availability will have all the time slot data which will populate the buttons in the Container List control. The application will show a list of buttons with the available time slots.

Once a time slot is selected and confirmed via the Confirm Button control, the application will move to the next Web Page “Enter Details and Confirm”.

On the second page, “Enter Details and Confirm”, we will create a scheduled event form where a user can create a meeting, add guests to the email guest list, add any notes to the meeting and then schedule the appointment. We will be adding another set of controls: Container, Label, Text Input, Text Area Input and Button. Make sure you label all the controls appropriately.

This image has an empty alt attribute; its file name is tsdcEYQHaylXYaqmxi3NTHFPNUKGkAEGTU3DOuQhFycW4so5zBG9dpltdb07AHH80TFUkyHC6R-yhycXBSegg8XNJhlq-m9anZPhieYj6wevL2Se1nCsspSYRVmGVbfvB8JHV12-RtO1zPBvfMHAlJ8tZ7hPZAPdZ_xZLCFhyk8aawGh7GUKa3wBNQ

The Schedule Event button action unifies all the inputs from the initial page and current page via the “Schedule Event Data Flow” in order to create a Google Calendar Event with a Zoom Meeting. See the screenshot below:

This image has an empty alt attribute; its file name is yhvNr8BYCMtG-Ej0KYal3JEQWCS40885UsMAm4cpMLK53Ss4uTovNA4hJ1UuNGusBvy-_KfjUwyEjSs0yH9Ec3ZP5wNt7YD1LZqqLm1i3UznUZT6Vv2051IGlNgIrScezGTAlgRXp3Iu_el271znYmUof79ExB2diGV5FCwi7yH5xghRc8G0b4uWBA

After the event is scheduled, the user is sent to the Thank You page.

On the final page, a Thank you page, add a label which thanks the user for scheduling an appointment.

This image has an empty alt attribute; its file name is 1Drc1ohl9WX_JxYxHR1ngelBocIyK8Uzsz9RG4pf-aZFmwHq21fOPlnLCIp0ysxOGqPYISJ6savcNjyzB0dUUPl9SFmFYl4YULNPcXFQea9kFh41RWSiUsAztVYpo4vTaMM-P6QpkBKuwXEXTF-3BTyTB7B_5nmelIsv2uYw5fDQfE8-L14GJZGSSg

Wrap Up

Hopefully this walkthrough has been a helpful guide on how to create a calendly clone on your own.

Even this build has room to add additional functionality! You could upload additional documents for the meeting to the calendar invite via the File Upload control. You could change the video conference link by creating a new API integration with Microsoft Teams or any other video conferencing service. Try adding new features of your own and let us know what you build!

Top comments (0)

Timeless DEV post...

Git Concepts I Wish I Knew Years Ago

The most used technology by developers is not Javascript.

It's not Python or HTML.

It hardly even gets mentioned in interviews or listed as a pre-requisite for jobs.

I'm talking about Git and version control of course.

One does not simply learn git