line

Location Booking & Deposit Process

A workflow that manages the booking confirmation and deposit process for a marketplace where users can book event spaces at restaurants. The workflow launches when the customer requests a booking and triggers emails or SMS messages to manage the booking reservation and deposit processes between the location owner and customer. It also sends slack notifications to the customer success teams keeping them updated on each step. It is not possible to book a place less than 1 day and half before. Notifications are sent using third party APIs such as Sendgrid and Twilio.
It also sends Slack internal notification to the customer success teams keeping them updated on each step.

Visual of Workflow

This flowchart shows a visual representation of the workflow tasks.
line

Workflow Steps

Workflow is launched when the user creates a booking at a place with parameters location, deposit requirement (Y/N) and number of people.

  • Send a booking request email via Sendgrid to the location owner with the date, time and number of people.
  • Wait for the owner to respond (replyEvent) from the owner until 1 day.
  • If the owner refuses the booking, send an email via Sendgrid to the customer
  • If the owner does not reply within the wait time period:
    – send an SMS reminder to the owner via Twilio
    – send a slack notification to customer success team.
  • If the owner accepts the booking request:
    – Create the booking in the database with the booking data (date, time, number of people, location data, etc) in a task
    – Cancel other booking requests for other locations from the user in a task.
    – Send confirmation email via sendgrid to the location-owner with booking details

Check the workflow parameters to see if the location requires a deposit in the workflow parameters.

  • If the location does not require a deposit,
    – send the customer a confirmation SMS and email with booking and location details,
    – send a slack message to customer success that the a booking is confirmed,
    – update booking record in the database with confirmation details.
  • If the location requires a deposit,
    – send a booking confirmation email to the customer with details on how to make a deposit,
    – send a slack notification to customer success that a deposit has been requested,
    – execute a task to calculate the time to wait for the deposit - 36 hours from the date of request email or 6 hours before the event if the event is earlier than 36 hours. Learn more about idempotency in documentation.
    – Wait for the customer to pay the deposit (deposit event) until the amount of time (hours)that is calculated in the formula.

    • If the deposit is received within the wait period:
      – Send a confirmation SMS to the customer,
      – Update the booking record in the database with confirmation and deposit details.
  • If the deposit is not received within the wait period:
    – Execute a task to cancel the booking,
    – Send an email to the customer with cancellation details,
    – Send an email to the location owner with cancellation details.
    – Send a slack message to the team that the booking has been cancelled.

Workflow Code

Launch Booking Workflow

The workflow is triggered when a user requests a booking. He enters parameters such as booking_day, booking_date, owner_id and owner_place.

client.run.withTag(booking_id).workflow("BookingWorkflow", booking_day, booking_date, place_id, place_adress, owner_email, user_email, number_of_people, user_phone_number, owner_phone_number);

Send Events To Booking Workflow

EventReply is sent to the workflow when the owner validates the booking request in the application. Through the event, we send parameters about the need of a deposit :

client.select.workflow("BookingWorkflow").withTag(booking_id).send("EventReply", { status: "Accepted", deposit_amount, deposit_url });

The workflow will handle the event through this.wait.event("EventReply").for(duration.days(1)); method that will receive the event object as a parameter.

Structure of the workflow

This workflow is the code that orchestrates tasks (through the Zenaton workflow engine) and executes them on your servers.

const { workflow, duration } = require("zenaton");
/* Workflow for booking validation with notifications to user, owner's place and customer success team  */
​
module.exports.handle = function*(booking_id) {

  /* Connect to third party APIs */
  const sendgrid = this.connector('sendgrid', 'your-sendgrid-connector-id');
  const slack = this.connector('slack', 'your-slack-connector-id');
  const twilio_sms = this.connector('twilio_sms', 'your-twilio-connector-id');

  /* Send email to the owner */
  sendgrid.post('/mail/send', {body: {"template": "request_to_owner", ...}})/* Wait for owner's reply until 1 day  */
  const [event, status] = yield this.wait.event("EventReply").for(duration.days(1));/* If there is no reply */
  if(!event) {
    /* Send SMS reminder */
    twilio_sms.post('/Messages.json', {body: {To: this.user_phone_number, Body: '...'}})
    /* Alert the customer success team */
    slack.post('/api/chat.postMessage', {body: {"channel": "booking-request", ...}})
    /* Stops the workflow execution after an SMS reminder */
    return
  /* If the request is refused */
  } else if (status == 'refused') {
    /* Alert the owner about the cancellation */
    sendgrid.post('/mail/send', {body: {"template": "owner_cancellation", ...}})
  } else {
    /* The booking is accepted */
    yield this.run.task("CreateBooking", booking_id)
    yield this.run.task("CancelOtherBookingRequests", booking_id)
    sendgrid.post('/mail/send', {body: {"template": "user_confirmation", ...}})
  }/* Restaurant did not ask for a deposit */
  if(booking.deposit === null || booking.deposit === false) {
    /* Notify the user about the confirmation by SMS and email */
    twilio_sms.post('/Messages.json', {body: {To: this.user_phone_number, Body: '...'}})
    sendgrid.post('/mail/send', {body: {"template": "user_confirmation", ...}})
    /* Alert the customer success team */
    slack.post('/api/chat.postMessage', {body: {"channel": "confirmed-booking", ...}})
    yield this.run.task("SaveBookingMYSQL", booking.id)
    
  /* Restaurant asked for a deposit */
  } else {
    sendgrid.post('/mail/send', {body: {"template": "deposit_request", ...}})
    slack.post('/api/chat.postMessage', {body: {"channel": "booking-request", ...}})
    
    /* Calculate inside a task how long the waiting time is */
    const waiting_time = yield this.run.task("CalculateWaitingTimeForDeposit", booking.id)
    yield this.wait.event("DepositReceived").for(duration.hours(waiting_time));

    if (deposit_received) {
      twilio_sms.post('/Messages.json', {body: {To: this.user_phone_number, Body: '...'}})
      /* Update the booking record in the database  */
      yield this.run.task("SaveBookingMYSQL", booking.id)
    } else {
      yield this.run.task("CancelBookingRequest", booking.id)
      twilio_sms.post('/Messages.json', {body: {To: this.user_phone_number, Body: '...'}})
      slack.post('/api/chat.postMessage', {body: {"channel": "booking-request", ...}})
    }
  }   
}

Workflow Executions

View execution of this workflow from the Zenaton dashboard.
line