[Technical] Listen to events on the website

Read time: 5 minutes

Share:
[Technical] Listen to events on the website[Technical] Listen to events on the website

This article is technical and requires some programming knowledge (basic knowledge of JavaScript).

Calendesk can call global functions on the website after the occurrence of specific actions that take place on the website created by the Calendesk website builder.

You can react to these events by using your own code that you paste into a function that will be called by Calendesk.

This option will be useful when, for example, you want to track the conversion on the website to specific actions, you want to display additional information to the client, or in other non-standard cases.

List of global functions that will be called when events occur:

  • Creation of a customer account calendeskUserCreated
  • Creation of a booking calendeskBookingsCreated
  • Payment for the booking – success calendeskBookingPaymentSuccessful
  • Payment for the booking – fail calendeskBookingPaymentUnsuccessful
  • Rescheduling a booking calendeskBookingsRescheduled
  • Cancelation of a booking calendeskBookingsCanceled
  • Booking payment with user subscription calendeskUserSubscriptionPaidForBooking
  • Creation of a user subscription calendeskUserSubscriptionCreated
  • Cancelation of a user subscription calendeskUserSubscriptionCanceled

To react to the above events, you just need to declare a global function in your code matching the above names and insert it on the page in Calendesk.

Examples of functions that you can use in your implementation, with a description:

async function calendeskUserCreated(user) {
    // We will call this function after successful user signup. A parameter `user` is a user object.
    // User object:
    // public id!: number
    // public name!: string | null
    // public surname!: string | null
    // public email?: string | null
    // public cardBrand?: string | null
    // public cardLastFour?: string | null
    // public stripeId?: string | null
    // public status!: UserStatus
    // public preferences?: UserPreferences | null
    // public subscriptions?: Array<UserSubscription>
    // public defaultImage!: DefaultImage
    // public defaultAddress?: Address | null
    // public defaultPhone?: Phone | null
    // public dateOfBirth?: string | null
    // public emailVerifiedAt?: string | null

    console.log('Function: calendeskUserCreated, User: ', user)
}

async function calendeskBookingsCreated(bookings) {
    // We will call this function after creating a booking. A parameter `bookings` is an array of booking objects.
    // Booking object:
    // public id!: number
    // public employeeId!: number
    // public serviceId!: number
    // public serviceTypeId!: string
    // public startDate!: string
    // public endDate!: string
    // public startTime!: string
    // public endTime!: string
    // public startsAt!: string
    // public endsAt!: string
    // public customerTimeZone!: string
    // public status!: BookingStatus
    // public control!: string
    // public location!: ServiceLocation
    // public paid!: boolean
    // public paymentMethod!: string
    // public paidWithUserSubscriptionId!: string | null
    // public googleMeetUrl!: string
    // public zoomJoinUrl!: string
    // public teamsUrl!: string
    // public skypeUrl!: string
    // public customerWhatsAppUrl!: string
    // public employeeWhatsAppUrl!: string
    // public customFields!: Array<CustomField> | null
    // public paymentTransaction!: string
    // public service!: Service
    // public serviceType!: ServiceType
    // public employee!: Employee
    // public getPrice (): number;
    // public canBeCanceled (): boolean;
    // public getDuration (): number;

    console.log('Function: calendeskBookingsCreated, Bookings: ', bookings)
}

async function calendeskBookingPaymentSuccessful(booking) {
    // We will call this function after successful booking payment. A parameter `booking` is a booking object.
    console.log('Function: calendeskBookingPaymentSuccessful, Booking: ', booking)
}

async function calendeskBookingPaymentUnsuccessful(booking) {
    // We will call this function after unsuccessful booking payment. A parameter `booking` is a booking object.
    console.log('Function: calendeskBookingPaymentUnsuccessful, Booking: ', booking)
}

async function calendeskBookingsRescheduled(booking) {
    // We will call this function after successful booking reschedule. A parameter `booking` is a booking object.
    console.log('Function: calendeskBookingsRescheduled, Booking: ', booking)
}

async function calendeskBookingsCanceled(booking) {
    // We will call this function after successful booking cancelation. A parameter `booking` is a booking object.
    console.log('Function: calendeskBookingsCanceled, Booking: ', booking)
}

async function calendeskUserSubscriptionPaidForBooking(bookingIds) {
    // We will call this function after paying with a subscription for a booking. A parameter `bookingIds` is an array of paid booking ids.
    console.log('Function: calendeskUserSubscriptionPaidForBooking, Booking Ids: ', bookingIds)
}

async function calendeskUserSubscriptionCreated(subscription, user) {
    // We will call this function after creating a subscription.
    // A parameter `subscription` is a subscription object, a parameter `user` is a user object.
    // Subscription object
    // public id!: number
    // public subscriptionId!: string
    // public name!: string
    // public description!: string | null
    // public successUrl!: string | null
    // public recurringInterval!: string | null
    // public intervalCount!: number | null
    // public serviceLimit!: number | null
    // public wantsInvoice!: boolean
    // public requireBillingData!: boolean
    // public disableRobotIndexing!: boolean
    // public tax!: string | null
    // public createdAt!: string
    // public updatedAt!: string
    // public price!: SubscriptionProductPrice
    // public services!: Array<Service> | null

    // After calling this method, the system can redirect your user to the payment provider.
    // To make sure that your data is sent correctly, please use the `await` option.
    // For example, await new Promise(r => setTimeout(r, 2000))
    console.log('Function: calendeskUserSubscriptionCreated, Subscription: ', subscription, 'User: ', user)
}

async function calendeskUserSubscriptionCanceled(userSubscription, user) {
    // We will call this function after successful subscription cancelation.
    // A parameter `userSubscription` is a user subscription object, a parameter `user` is a user object.
    // User Subscription object:
    // public id!: number
    // public subscriptionId!: number
    // public stripeSubscriptionId!: number
    // public canceledAt!: string | null
    // public endsAt!: string | null
    // public createdAt!: string
    // public status!: SubscriptionStatus
    // public subscription!: Subscription
    // public usageRecords!: Array<UserSubscriptionUsageRecord> | null
    // public isActive (): boolean

    console.log('Function: calendeskUserSubscriptionCanceled, User subscription: ', userSubscription, 'User: ', user)
}

Where to paste the functions?

Functions can be pasted in the website builder in the Custom Scripts field, between the script tags, e.g.

<script>
async function calendeskBookingsCreated (bookings) {
  // Your code that will be executed after creating a booking.
  // For example, if you use Google Analytics, you can call here a conversion script for bookings.
}
</script>

See the related article: How to add Google Analytics, Facebook Pixel, and other custom scripts?

Custom Scripts

Useful examples

Send a conversion event to Google Tag Manager using Data Layer:

<script>
function calendeskBookingsCreated(bookings) {
    window.dataLayer = window.dataLayer || [];
    for (var i = 0; i < bookings.length; i++) {
        var booking = bookings[i]
        dataLayer.push({
            'event': 'bookingCreated',
            'bookingId': booking.id,
            'employeeId': booking.employeeId,
            'serviceId': booking.serviceId,
            'serviceTypeId': booking.serviceTypeId,
            'startDate': booking.startDate,
            'endDate': booking.endDate,
            'startTime': booking.startTime,
            'endTime': booking.endTime,
            'startsAtUTC': booking.startsAt,
            'endsAtUTC': booking.endsAt,
            'customerTimeZone': booking.customerTimeZone,
            'price': (booking.getPrice() / 100) // Convert cents to decimal
        })
    }
}
</script>

Send a conversion event to Google Analytics:

<script>
function calendeskBookingsCreated(bookings) {
    if (typeof ga === 'undefined') {
        console.error('Google Analytics not loaded');
        return;
    }
    // Loop through the bookings array and send each booking as an event to GA
    for (var i = 0; i < bookings.length; i++) {
        var booking = bookings[i];
        // Convert price from cents to decimals
        var priceInDecimals = booking.getPrice() / 100;
        // Convert price to an integer if it's a float, e.g. by rounding
        var priceAsInteger = Math.round(priceInDecimals);
        ga('send', 'event', {
            eventCategory: 'booking',
            eventAction: 'bookingCreated',
            eventLabel: `Booking ID: ${booking.id}, Employee ID: ${booking.employeeId}, Service ID: ${booking.serviceId}, Service Type ID: ${booking.serviceTypeId}`,
            eventValue: priceAsInteger,
            nonInteraction: true
        });
    }
}
</script>
Share: