SendGrid Connector Guide

This article provides direction on how to configure and manage your SendGrid connector as well as create and customize templates in the SendGrid environment.

Table of Contents

Purpose

The purpose of the connector is to provide a uniform messaging experience by customizing emails to clients and staff.

Prerequisites

Before using the SendGrid app and Booxi’s connector, both modules must be configured and activated. Prior to doing so, the following steps must be fulfilled:

  1. Create a branded SendGrid account
  2. Create templates for email notifications to clients, groups and staff depending on the notifications you would like to send
  3. Provide Booxi with the following information:
    • Your SendGrid API key (associated to an authenticate Sendgrid account) 
    • The name and email address associated with the admin of your SendGrid account
    • The sender name and email address 
  4. Authenticate your domain from Sendgrid (DNS configuration) 
  5. Recommendation : ensure to configure the DMARC to authenticate the sender

With the above completed, the SendGrid App and SendGrid Connector must be configured. The following will explain how to do so.

Connector Configuration 

How to Configure SendGrid App

URL: https://app.sendgrid.com

To configure SendGrid App, complete the following steps:

  1. Download and install Twilio Authy (required for Two-Factor Authentication)

Choose of the below links:

  1. Domain Authentication and Activation
  • First, log in to the SendGrid App by entering your credentials.

APP-Login

  • Complete Two-Factor Authentication.
      • Launch Authy
      • Input code

App-TwoFactor

  • Review and validate your account settings.

App-Account

  • Validate that your API keys have been assigned.

App-APIKeys

  • Authenticate your domain.

App-Authentication


Domain authentication

  1. Go to “Settings” / “Sender Authentication”
  2. Choose your “DNS host” in the list (Contact your IT team if you don’t know)
  3. Click on “Next”
  4. Enter your “From Domain” (as “booxi.com” for Booxi), click on “Next”
  5. Add the entry in your DNS center (or contact your IT team with this information)
  6. Click on “Verify”

Notice-Icon

Once the above steps are completed, SendGrid App is configured and ready to be operated. Next, the SendGrid Connector must be configured.


Configuring the Booxi SendGrid Connector

The access to the connector is limited. The connector will be configured and activated by Booxi.

With both modules configured and activated, we can now move on to SendGrid itself.


How to Use SendGrid

Introduction to SendGrid Templates

SendGrid provides a flexible method to customize your email experience. Throughout this document, you will learn to configure, use and manage the SendGrid App and SendGrid Connector in synergy with Booxi’s email service.

To build a custom experience, you will first create multi-purpose design templates using the SendGrid App. Once completed, your Booxi representative will assign your templates to their respective notifications using the SendGrid Connector.

In SendGrid App, access Templates:

  1. Log in to your SendGrid App Account.
  2. On the left-hand side menu, click on Email API / Dynamic Templates.

    image3-May-21-2024-03-41-05-4633-PM
  3. Select Dynamic Templates

On the right-hand side of the screen, you will find a list of all templates currently available. If it is your first session, the list will be empty. Otherwise, all templates you created will be listed there. On this screen, we can edit an existing template or create a new one.

Let’s have a look at the notifications your templates will be assigned to.


Template Assignment

Templates will be assigned to notifications by Booxi per a customer's requirements.


Template Customization

How to create a new template

In order to create a new template in SendGrid App:

  1. Click on “Email API / Dynamic Template” in the left-hand menu.

    image3-May-21-2024-03-41-05-4633-PM

  2. Select “Create a Dynamic Template”

    image6-May-21-2024-03-41-05-5709-PM

  3. Assign a name to your new Template.
  4. Click on your newly created Template.
  5. Click on “Add version”
  6. Select a Template Design

App-Select Design

  1. Select an editing mode
Choose between “Design Editor” or “Code Editor”.
    • Design Editor: Visual, drag-and-drop editing tool with sets of prefab controls.
    • Code Editor: HTML editing with visual preview. Full control over editing.

      image7-May-21-2024-03-41-05-4197-PM

  1. Edit your template.

How to edit an existing template

To edit an existing template in SendGrid:

  1. Click on “Email API / Dynamic Template” in the left-hand menu.
  2. In the right-hand list, select the template you wish to edit by clicking on it.

    image3-May-21-2024-03-41-05-4633-PM

  3. Edit your Template.

How to customize templates

The template editor UI is comprised of 3 main components:

  • Code Editing Tab

You can view and edit code in HTML with native support for HandleBars.

image5-May-21-2024-03-41-05-7112-PM

  • Test Data Tab

Test data allows you to populate variables in your template. It must be formatted as JSON, and is used to preview dynamic content and iterators found in your emails.

image5-May-21-2024-03-41-05-7112-PM

  • Preview Window

On the right-hand side of the editing UI, the preview window allows visualizing how your email will appear on desktop, mobile and in plain text.
image4-May-21-2024-03-41-05-3323-PM
image1-May-21-2024-03-41-05-6153-PM

 

Booxi Notifications

A notification is a message sent by Booxi’s API that will be captured by SendGrid Connector to determine what email template should be sent out. Notifications are categorized in three groups or modules.

Notice-Icon

Booxi’s email service can be activated or deactivated for all notifications or for a selected group. 

When the email service is activated, generic template messages are sent out for all notifications.

When the email service is deactivated, all related notification emails will be sent using your assigned templates. If no template has been assigned to a notification, no email will be sent for that specific notification.

Notifications Groups

  • Custom Client Notifications
      • Custom notification message to a client via email. This notification only applies if you use the Notify Client feature in the Booxi back office. 
  • Client Appointment Notifications
      • Notifications directed to clients who booked an appointment.
  • Group Event Notifications
      • Notifications directed to clients who made a reservation in a group event, and attendees for whom the reservation was made.

Custom Client Notification

This feature allows staff to send a custom notification message to a client via email.

Supported Notification

Context

Custom Notification

Sent when a staff uses the feature to send a custom notification message to a client via email. 

Client Appointment Notifications

This module allows you to manage notifications directed to clients who booked an appointment. 

Supported Notifications

Context

Appointment Confirmation

Sent whenever a new appointment was booked with an approved status. 

Appointment Request

Sent whenever a new appointment was requested with a pending approval status from the staff. 

Appointment Created by Staff, awaiting client confirmation

Sent whenever an existing appointment was created by the staff with options set to request a confirmation from the client, to confirm the changes.

Appointment Changed by Staff, awaiting client confirmation

Sent whenever an existing appointment was updated by the staff, and is awaiting client confirmation. 

Appointment Changed

Whenever the staff or client changes some elements of the appointment, without requiring a confirmation from either end. 

Appointment Cancelled by Staff

Sent whenever an existing appointment was cancelled by the staff.

Appointment Cancelled by Client

Sent whenever an existing appointment was cancelled by the client.

Appointment No-Show

Sent whenever an existing appointment was marked as a no-show. 

Appointment Completed

Sent whenever an existing appointment was marked as completed by the staff or automatically. 

Appointment Reminder

Sent when it is time to remind the client of its appointment. The same notification is used for both the “reminder” and “additional reminder” features.

Appointment Recall

Sent when it is time to remind the client to book a new appointment, if a recall was programmed.  

Staff Appointment Notifications

This module allows you to manage notifications directed to clients who booked an appointment. 

Supported Notifications

Context

Appointment Confirmation

Sent out whenever a new appointment was booked with an approved status.

Staff Request

Sent out whenever a new appointment was booked with a pending approval status.

Staff Changed Wait Client Confirmation

Sent out whenever an existing appointment was updated with options set to request a confirmation from the client to approve the changes.

Staff Created Wait Client Confirmation

Sent out whenever an appointment is created with options set to request a confirmation from the client to approve.

Staff Changed

Sent out whenever an existing appointment was updated.

Staff Cancelled Staff

Sent out whenever an existing appointment was cancelled by the staff.

Staff Cancelled Client

Sent out whenever an existing appointment was cancelled by the client.

Staff No Show

Sent out whenever an existing appointment was marked as a no-show.

Staff Completed

Sent out whenever an existing appointment was marked as completed by the staff or automatically.

Staff Reminder

Sent out whenever it is time to remind the client of his appointment. The same notification is used for both the “reminder” and “additional reminder” features.

Group Event Notifications

This module allows you to manage notifications directed to clients who made a reservation in a group event, and attendees for whom the reservation was made. 

Supported Notifications

Context

Reservation Confirmation

Sent to the client when a new group reservation is booked. 

Reservation Changed

Sent to the client when a new group reservation is changed. 

Reservation Cancelled by Staff

Sent to the client when an existing reservation is canceled by the staff. 

Reservation Cancelled by Client

Sent to the client when an existing reservation is canceled by the client. 

Reservation Event Completed

Sent when the event associated with an existing reservation is completed. 

Reservation Reminder

Sent to the client when it is time to remind him of his group event. 

Attendee Confirmation

Sent to each attendee when a new group reservation is booked. 

Attendee Cancelled by Staff

Sent to the attendee whenever an existing attendee or the reservation was cancelled by the staff. 

Attendee Cancelled by Client

Sent to the attendee whenever the reservation was cancelled by the client. 

Attendee Event Completed

Sent to each attendee when the event associated with an existing reservation is completed. 

Attendee Reminder

Sent to each attendee when it is time to remind them of their group event. The same notification is used for both the “reminder” and “additional reminder” features.


 

Email Structure and Features

Your custom email will be built using a set of features partitioned in blocks, each block having its own purpose. Here is a list of blocks and their associated features.

Announce + Message

Greetings and appointment overview.

Instructions

Important information or guidance prior to an appointment.

Appointment Details

Message corpus, contains all details related to an appointment.

Additional Request

Client’s request or demands.

Location

Appointment’s venue or mean by which the service will be rendered.

Survey

Display answers provided at time of booking an appointment. Survey URL. 

Action Buttons

View, Modify, Cancel an appointment.

Footer

Term of Use / Privacy Policy, Subscription / Preferences.

ICS

ICS file 

 

Notice-Icon

You are free to construct your message using all or only a subset of these features. You can combine features within the same block.

Using a sample email, the following will cover each feature and will provide details on how to build your message with associated data and block segments. Please take note that the following uses partial data. For a complete list of content variables, please see the content variables section below.

Announce + Message

The purpose of this block is to provide your clients with information about their appointment, either for an updated status, a word of gratitude or a confirmation.

 

Example

Here’s an example which includes a greeting statement and details of the appointment.

Mail-Announce with TZ

Test Data

In the below data, a “client” and “event” data structures are created and populated.

"client":
{
"firstname":"Jane",
"lastname":"Do",
"email":"jane.do@test.fr",
"gender":"Unknown",
"lang":"eng",
"language":"eng",
"request":null
}
"event":
{
"date":
  {
  "start":
    {
    "s_month_shortly":"Dec.",
    "c_day":"18",
    "s_day":"Friday",
    "half_day":"pm",
    "hour":12,
    "u_hour":12,
    "c_minute":"00",
  },
    "duration":
    {
      "hours":0,
      "c_hours":"00",
      "minutes":30,
      "c_minutes":"30"
    },
    "timezone":"(EST)"
 }

Code

The below code segment creates an announce which includes an introduction and a summary of the appointment. It is constructed with the data defined above.

<div>

<h1 class="title1 fnt_colMain" aria-labelledby="title1 fnt_colMain">
Hello {{client.firstname}}, 
</h1>

<h1 class="title1 fnt_colMain" aria-labelledby="title1 fnt_colMain">
Your appointment has been confirmed for
{{event.date.start.s_day}}{{event.date.start.s_month_shortly}}
{{event.date.start.c_day}} at
{{event.date.start.u_hour}}:{{event.date.start.c_minute}}
{{event.date.start.half_day}} {{event.date.timezone}}.
</h1>

</div>

Instructions

Instructions are used to provide your client with important information or guidance prior to his appointment.

 

Example

Here’s an example where clients are requested to be present 15 minutes prior.

Mail-Instructions

Test Data

In the below data, instructions are defined for a specific service.

"services":
[
{
  "id": 51438,
  "name": "Smart booking solutions that work for everyone",
  "description": "Focus on your customers, not on appointment management
  Turn the page on paper agendas, and accept online booking with payment,
  for appointments, events and workshops.",
  "instruction": "Please join us 15 minutes before the meeting.",
  "tags": "VIP Service",
  "location": "Business",
  "location_text": "",
  "image": "https://storage.googleapis.com/booxi/rounded.svg",
  "category":
    {
      "id": 5790,
    "name": "Booking for Service Business",
    "description": "",
    "image":"https://storage.googleapis.com/booxi/rounded.svg"
  }
}
]

Code

The below code segment validates if instructions have been assigned to the service and if so, displays them in the message.

{{#each services}}
  {{#if this.instruction}}
  <div class="part" aria-labelledby="part">
    <div class="block" aria-labelledby="block">
         <div class="table" aria-labelledby="table">

           <span class="table_cell" aria-labelledby="table_cell">
            <img class="icon" aria-labelledby="icon"
              src="http://cdn.sendgrid.net/97/65a/40x40.png"
              alt="important instructions"/>
           </span>

           <span class="table_cell" aria-labelledby="table_cell" style="vertical-align: middle;">
           <p class="fnt_colMain" aria-labelledby="fnt_colMain">
              Important instruction</p>
           </span>

         </div>

<div style="clear: both;"></div>
         <div class="table" aria-labelledby="table">

          <span class="table_cell" aria-labelledby="table_cell">
            <p class="fnt_colMain" aria-labelledby="fnt_colMain"></p>
           </span>

        </div>
     </div>
  </div>

  <div style="clear: both;"></div>

  {{/if}}

{{/each}}

Appointment Details

All details pertaining to the appointment should be listed and detailed in this block. The level of details is yours to decide. The example below includes information from features. 

Example

Appointment details listed as a table with 3 separate sections.

 

Mail-Details

Appointment Details - Service

This block lists the service to be rendered. It includes the service’s name and description, its duration and the staff who will deliver it. 

Mail-Details-Service

Test Data

Service description and staff assigned to that service.

"services": 
[
{
  "id": 51438,
  "name": "Smart booking solutions that work for everyone",
  "category":
    {
    "id": 5790,
    "name": "Booking for Service Business",
    "description": "",
    "image": ""
    },
  "amount": "0.50",
  "currency": "USD",
  "s_currency": "$",
  "staff":
    {
    "language": "eng",
    "biography": "",
    "position": ".",
    "firstname": "John",
    "lastname": "Smith",
    "profile_image": ""
    }
}
]

Code

The below code displays the service name, duration and assigned staff.

{{#each services}}
<div class="part flex" aria-labelledby="part flex">
   <div class="colServiceLogo" aria-labelledby="colServiceLogo">
        {{#if this.image}}
        <div>
          <img class="service" aria-labelledby="service" src="{{this.image}}" alt="service_image"/>
        </div>
     
    </div>
    <div class="colServiceDetail" aria-labelledby="colServiceDetail">

      <p class="fnt_colMain" aria-labelledby="fnt_colMain" style="font-weight:bold;">
           {{this.category.name}}
      </p>

      <p class="fnt_colMain" aria-labelledby="fnt_colMain" style="text-align:left;">
           {{this.name}}
      </p>

      <p class="fnt_colSecondary small" aria-labelledby="fnt_colSecondary small"   style="text-align:left;">
           {{#greaterThan this.duration.hours 0}}
              {{../duration.hours}}
           {{/greaterThan}}

           {{#eq this.duration.hours 1}}
         hour
           {{/eq}}

           {{#greaterThan this.duration.hours 1}}
          hours
           {{/greaterThan}}                      

        with {{this.staff.firstname}} {{this.staff.lastname}}
      </p>

      <p class="right fnt_colSecondary" aria-labelledby="right fnt_colSecondary">
           {{#equals this.amount 0}}
         Free
           {{else}}

        <span class="currency" aria-labelledby="currency">
              {{../s_currency}}{{../amount}}
        </span>

           {{/equals}}              

      </p>
</div>
  </div>
{{/each}}

Appointment Details - Invoice

This block lists the transaction details, subtotal, taxes if applicable, total and amount due.

Mail-Details-Invoice

Test Data

Transaction details and applicable taxes.

"payment":
{
"total":"100.00",
 "subtotal":"80.00",
 "due":"20.00",
 "currency":"USD",
 "s_currency":"$",
 "payment_online_amount":null,
 "payment_status":"None",
 "taxes":
  [
   {
        "name":"Tax1",
      "rate":"13.5",
      "amount":"20.30"
      },
    { 
        "name":"Tax2",
      "rate":"9.5",
      "amount":"13.30"
     }
  ]
}

Code

The below code displays, total, sub-total, taxes and amount due.

<div class="part flex" aria-labelledby="part flex">
  <div class="colHalf" aria-labelledby="colHalf">
   <div class="innerFlex" aria-labelledby="innerFlex">

      <div class="colHalf" aria-labelledby="colHalf">
        <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">Subtotal</p>
      </div>

      <div class="colHalf" aria-labelledby="colHalf">
        <p class="right fnt_colMain" aria-labelledby="right fnt_colMain">
              {{payment.s_currency}}{{payment.subtotal}}
        </p>
      </div>

    </div>

      {{#each payment.taxes}}

    <div class="innerFlex" aria-labelledby="innerFlex">
      <div class="colHalf" aria-labelledby="colHalf">
        <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary"></p>
      </div>

        <div class="colHalf" aria-labelledby="colHalf">
          <p class="right fnt_colMain" aria-labelled="right fnt_colMain">
               {{../payment.s_currency}}{{this.amount}}
          </p>
        </div>

</div>

   

   </div>

    <div class="h_space" aria-labelledby="h_space"></div>

   <div class="colHalf" aria-labelledby="colHalf">
    <div class="innerFlex" aria-labelledby="innerFlex">
       <div class="colHalf" aria-labelledby="colHalf">
          <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">Total</p>
        </div>

        <div class="colHalf" aria-labelledby="colHalf"> 
          <p class="right" aria-labelledby="right">
           <span class="currency fnt_colMain" aria-labelledby="currency fnt_colMain">
                  {{payment.s_currency}}{{payment.total}}
            </span>
          </p>
        </div>
      </div>

     <div class="innerFlex" aria-labelledby="innerFlex">
      <div class="colHalf" aria-labelledby="colHalf">
         <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">Amount due</p>
        </div>

        <div class="colHalf" aria-labelledby="colHalf">
         <p class="right large" aria-labelledby="right large">
            <span class="currency fnt_colMain" aria-labelledby="currency fnt_colMain">
                 {{payment.s_currency}}{{payment.due}}
            </span>
          </p>
        </div>

</div>
</div>
  </div>

Appointment Details - Booking Summary

This block lists all remaining details not previously covered  such as date, time, mean and location. The time is provided in the store location time zone, except for video conference and by phone appointment, which can use a time zone selected by the client. To avoid confusion, it is always preferable to specify the time zone next to the time.

Mail-Details-Booking-Summary

Test Data

"event":
{
"date":
  {
   "start":
    {
    "year":2020,
    "month":12,
    "c_month":"12",
    "s_month":"December",
    "s_month_shortly":"Dec.",
    "day":18,
    "c_day":"18",
    "s_day":"Friday",
    "s_day_short":"Fri.",
    "half_day":"pm",
    "hour":12,
    "u_hour":12,
    "c_hour":"12",
    "u_c_hour":"12",
    "minute":0,
    "c_minute":"00",
    "second":0,
    "c_second":"00"
  }
"timezone": "(EST)"
}
}

Code

The code below displays the date and time of an appointment.

<div class="flex" aria-labelledby="flex">
<div class="colHalf" aria-labelledby="colHalf">
    <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">When</p>
    <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
        {{event.date.start.s_day}}, {{event.date.start.s_month}}
        {{event.date.start.c_day}}, {{event.date.start.year}}
    </p>   
</div>

  <div class="h_space" aria-labelledby="h_space"></div>

  <div class="colHalf" aria-labelledby="colHalf">
    <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">Time</p>
    <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
        {{event.date.start.c_hour}}:{{event.date.start.c_minute}}
    </p>
  </div>
</div>

Appointment Details - Location

As part of the booking summary, location is the venue (real or virtual) or mean by which the service is rendered (Phone, Video Conference, etc...).  For appointments booked at a physical location, the value of “location” must be set to “Business”.

Test Data

Appointment location set as “Video”, an URL is provided to participate.

{
"location":"Video",
"location_text":"A description of the location. Only available by VideoConference",
"video_url":"zoom.../"
}

Code

The below code parses where the appointment is held and displays its location.

<div class="h_space" aria-labelledby="h_space"></div>

<div class="colHalf" aria-labelledby="colHalf">
  {{#equals location "Business"}}
    <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">
      Phone   
    </p>
    <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
        {{business.phone}}
    </p>
  {{/equals}}                  
     
  {{#equals location "Video"}}
    <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">
      Video Link
    </p>
    <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
      <a href="{{../video_url}}" target="_blank">Join Video Conference</a>
    </p>

  
<p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary">Web </p>
  <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
   <a src="{{business.url_site}}"> Visit our website </a>
  </p>

</div>

Appointment Details - Additional Request

This block is used to display any additional requests or demands from your client.  That information can be displayed individually in its own section or included with the appointment details.

 

Mail-Request

Test Data

Additional request assigned in the service data structure.

"client":
{
  "firstname":"Jane",
  "lastname":"Do",
  "email":"jane.do@test.fr",
  "membership":"",
  "home_phone":"0000000000",
  "mobile_phone":"",
  "gender":"Unknown",
  "lang":"eng",
  "language":"eng",
  "request":"Please read my previous email."
}

Code

The below code displays any additional request for a specific service.

<p class="fnt_colMain left important" aria-labelledby="fnt_colMain left important">
Additional Request
</p>

<p class="fnt_colMain left" aria-labelledby="fnt_colMain left">
  {{this.request}}
</p>

Survey

This block lists all information pertaining to surveys. Surveys are divided into two categories:

Online Booking Survey

Surveys conducted at the time of booking an appointment. Results can be listed in the email.

Mail-Survey

Test Data

"surveys":
[
{
"name":"question1",
    "title":"How would you like to be contacted?",
    "required":true,
    "answer":"item1"
 },
 {
    "name":"question2",
    "title":"Feel free to describe your ideal fragrance",
    "required":false,
    "answer":"Sweet yet robust"
 }
]

Code

The code below scans all surveys and the corresponding answers. Results are then assigned.

{{#each surveys}}
  {{#each this}}
 <div class="column" aria-labelledby="column">
  <p class="left fnt_colSecondary" aria-labelledby="left fnt_colSecondary"> 
        {% raw %}{{this.title}}
      </p>            
                                                      
    <p class="left fnt_colMain" aria-labelledby="left fnt_colMain">
        {{this.answer}}
      </p>

</div>

 

Survey URL

Includes an URL where your client can be directed to fill out a survey prior to their appointment.

Mail-SurveyURL

Test Data

"survey": {"survey_url": "https://.../survey10222021.html" }

Code

Survey URL assignment

<a href="{{survey.survey_url}}" style="background-color:#000000; border:1px solid #000000; border-color:#000000; border-radius:6px; border-width:1px; color:#ffffff; display:inline-block; font-size:18px; font-weight:bold; letter-spacing:0px; line-height:normal; padding:12px 20px 12px 20px; text-align:center; text-decoration:none; border-style:solid; font-family:inherit;" target="_blank">

Answer the survey

</a> </td>

Action Buttons

This block should display a set of actions allowing your client to minimally view, modify and cancel his appointment.

Example

Mail-Actions

Test Data

In the below code segment, three urls are defined as “view”, “modify” and “cancel”.

event_url": 
[
{
   "name":"View",
  "url":"https://site.booxi.eu/html/...=2b&from=jane.do%40test.eng"
  },
{
    "name":"Modify",
    "url":"https://site.booxi.eu/html/...=2b&action=modify&lang=eng"
  },
{
    "name":"Cancel",
  "url":"https://site.booxi.eu/html/...=2b&action=cancel&lang=eng"
  }
]

Code

<div style="clear: both;"></div>
<div class="divider" aria-labelledby="divider"></div>
<div class="part" aria-labelledby="part">
<div style="display:table;margin: 0 auto;">
  <p class="fnt_colSecondary" aria-labelledby="fnt_colSecondary" style="margin: 0 auto;">
   Use the following buttons to modify or cancel your appointment
</p>
</div>

  {{#equals (length event_url) 3}}
 
<div class="table tb3" aria-labelledby="table tb3">

     {{#each @root.event_url}}
   <div class="column" aria-labelledby="column">
     <div class="action_button" aria-labelledby="action_button" onclick="{{this.url}}">
       <p class="fnt_colMain" aria-labelledby="fnt_colMain" style="font-weight:bold; margin:6px auto;">
                 {{this.name}}
             </p>
          </div>
</div>
     {{/each}}

</div>
  {{/equals}}

</div>

Footer

In the mail footer, display terms, policies, preferences as well as your business logo.

Example

Mail-Footer

Test Data

“Terms of Use” and “Privacy Policy” URLs are defined.

"terms": 
{
  "privacy_url": "URL for your privacy terms",
  "legal_url": "URL for your legal terms",
  "translation":
  {
    "fra":
    {
      "language": "fra",
      "legal_url": "URL for your legal terms in French",
      "privacy_url": "URL for your privacy terms in French"
    },
    "eng":
    {
      "language": "eng",
      "legal_url": "URL for your legal terms in English",
      "privacy_url": "URL for your privacy terms in English"
    }
  }
}

Code

<p class="fnt_colSecondary" aria-labelledby="fnt_colSecondary">

<a href="{{terms.terms_url}}" class="term_policy fnt_colSecondary" aria-labelledby="term_policy fnt_colSecondary">
Term of Use
  </a>

  <span style="margin:0 1em;">|</span>
  <span>booxi inc.(c) 2020</span>
  <span style="margin:0 1em;">|</span>

<a href="{{terms.privacy_url}}" class="term_policy fnt_colSecondary" aria-labelledby="term_policy">
Privacy Policy
  </a>

</p>

 

ICS Support

Appointment, group reservations and staff emails can optionally include an ICS file. The ICS file includes information such as the service name, date and time of a booking.

A download link will appear in the footer of the email notification.

image2-May-21-2024-03-41-04-9948-PM

The ICS contains the following information.

image8-4


 

Test and Validation

You can test and validate your templates by following the below steps:

  • Click on the “Settings” menu on the left-hand side of the screen.
  • Click on “Test your eMail” to expand its content.
  • Fill out all relevant information.Test-01
  • Click on “Send Test Message”test-02

Content Variables

This section lists all content variables supported by email templates.

Header

Field

Description

subject

Contains the email’s subject formatted as "Service name - booking number - Status" where the value of “Status” will be one of the following:

  • None
  • Confirmed
  • Pending Staff Validation
  • Pending Client Validation
  • Cancelled
  • Completed

who

Is this email sent to a “client” or “staff”?

confirmation_number

Contains an appointment or reservation’s confirmation number.

created_by

Contains the identity of who created the booking.

status

Contains the appointment’s status. Supported values are as follows:

  • None
  • Confirmed
  • Pending Staff Validation
  • Pending Client Validation
  • Cancelled
  • Completed

message

Contains a message in text format. Used only for custom notifications. This variable must be formatted as  {{{message}}} as its content isn’t escaped.

custom_terms_url

Contains a redirection URL to the merchant’s terms.

location

Contains the merchant’s location.

location_text

Contains the merchant’s location in a text format.

video_url

Contains a video’s URL.

quick_note

Contains any custom note left by the merchant or staff.

 

Business

The object “business” contains all information pertaining to the merchant associated with an appointment. It is formatted as a multi-field object and includes the following fields.

Field or Object

Description

url_site

Contains the URL to a merchant’s official website. See example below.

"url_site": "https//..."

url_logo

Contains the URL to a merchant’s logo. See example below.

"url_logo": "https://..."

booxi_url_site

Contains the URL to booxi’s website. See example below.

"booxi_url_site": "https://..."

name

Contains the merchant’s name. See example below.

"name": "YOUR_BUSINESS_NAME"

description

Contains the merchant’s description if any.

translation

Contains translations for all languages supported by a merchant. See example below.

"translation": {
       "fra": {
         "language": "fra",
         "description": "description translated"
},
     "client_language_exist": true,
     "staff_language_exist": true
}

currency

Contains a merchant’s default currency. See example below.

"currency": {
       "raw": "EUR",
       "symbol": "€"
}

language

Contains a merchant’s official language formatted in a 3-letter code. See example below.

"language": "fra"

timeZone

Contains a merchant’s time zone. See example below.

"timeZone": "EST"

timezone_detail

Contains additional details in regard with a merchant’s time zone. See example below.

 "timezone_detail": {
         "timezone_str": "Eastern Standard Time",
         "timezone_abbr": "EST",
         "timezone_gmt": "GMT05" 
}

phone

Contains a merchant’s phone number. See example below.

"phone": {
       "raw": "0000000000",
       "formatted": "+41 44 668 18 00",
       "detail": {
             "international": "+41 44 668 18 00",
             "national": "044 668 18 00",
             "E164": "+41446681800",
             "country_code": "41"  }
},

terms

Contains a merchant’s terms formatted as a multi-field object. See example below.

"terms": {
       "legal_url": "",
       "privacy_url": "",
       "translation": {
             "fra": {
                 "language": "fra",
                 "legal_url": "",
                 "privacy_url": ""  },
         "client_language_exist": true,
         "staff_language_exist": true  }
},

address

Contains a merchant’s address formatted as a multi-field object. See example below:

"address": {
       "street": "",
       "city": "",
       "postalCode": "",
       "state": "",
       "country": ""
}

email

Contains a merchant’s email address. See example below.

"email": "merchant_email@domain.mail"

 

Field or Object

Description

url_site

Contains the URL to a merchant’s official website. See example below.

"url_site": "https//..."

url_logo

Contains the URL to a merchant’s logo. See example below.

"url_logo": "https://..."

booxi_url_site

Contains the URL to booxi’s website. See example below.

"booxi_url_site": "https://..."

name

Contains the merchant’s name. See example below.

"name": "YOUR_BUSINESS_NAME"

description

Contains the merchant’s description if any.

translation

Contains translations for all languages supported by a merchant. See example below.

"translation": {
       "fra": {
         "language": "fra",
         "description": "description translated"
     },
     "client_language_exist": true,
     "staff_language_exist": true
}

currency

Contains a merchant’s default currency. See example below.

"currency": {
       "raw": "EUR",
       "symbol": "€"
}

language

Contains a merchant’s official language formatted in a 3-letter code. See example below.

"language": "fra"

timeZone

Contains a merchant’s time zone. See example below.

"timeZone": "EST"

timezone_detail

Contains additional details in regard with a merchant’s time zone. See example below.

"timezone_detail": {
         "timezone_str": "Eastern Standard Time",
         "timezone_abbr": "EST",
         "timezone_gmt": "GMT05" 
}

phone

Contains a merchant’s phone number. See example below.

"phone": {
       "raw": "0000000000",
       "formatted": "+41 44 668 18 00",
       "detail": {
             "international": "+41 44 668 18 00",
             "national": "044 668 18 00",
             "E164": "+41446681800",
             "country_code": "41"  }
 },

terms

Contains a merchant’s terms formatted as a multi-field object. See example below.

"terms": {
       "legal_url": "",
       "privacy_url": "",
       "translation": {
             "fra": {
                 "language": "fra",
                 "legal_url": "",
                 "privacy_url": "" 
},
         "client_language_exist": true,
         "staff_language_exist": true 
}
},

address

Contains a merchant’s address formatted as a multi-field object. See example below.

"address": {
       "street": "",
       "city": "",
       "postalCode": "",
       "state": "",
       "country": ""
 }

email

Contains a merchant’s email address. See example below.

"email": "merchant_email@domain.mail"

 

Client

The object “client” contains all information pertaining to the client associated with an appointment. It is formatted as a multi-field object and contains the following fields.

Field or Object

Description

firstname

Contains the client’s first name. See example below.

"firstname": "John"

lastname

Contains the client’s last name. See example below.

"lastname": "Smith"

email

Contains the client’s email address. See example below.

"email": "johnsmith@domain.com"

membership

Contains the client’s membership ID. See example below.

"membership": "IM-00993738"

home_phone

Contains the client’s home phone number. See example below.

"home_phone": "1178922001"

home_phone_detail

Contains additional details in regard with a client’s home phone number, formatted as an object. See example below.

"home_phone_detail": {

          "raw": "0000000000",

          "formatted": "+41 44 668 18 00",

          "detail": {

                "international": "+41 44 668 18 00",

                "national": "044 668 18 00",

                "E164": "+41446681800",

                "country_code": "41"  }

      }

mobile_phone

Contains a client’s mobile phone number. See example below.

"mobile_phone": "1949893729"

mobile_phone_detail

Contains additional details in regard with a client’s mobile phone number, formatted as an object. See example below.

"mobile_phone_detail": {

          "raw": "0000000000",

          "formatted": "+41 44 668 18 00",

          "detail": {

                "international": "+41 44 668 18 00",

                "national": "044 668 18 00",

                "E164": "+41446681800",

                "country_code": "41"  }

      }

gender

Contains a client’s gender. Its value can be left blank. See example below.

"gender": ""

lang

Contains a client’s language formatted as a 3-letter code. See example below.

"lang": "fra"

language

Contains a client’s language in text format.

timeZone

Contains a client’s time zone. See example below.

"timeZone": "EST"

timezone_detail

Contains additional details in regard with a client’s time zone. See example below.

"timezone_detail": {

          "timezone_str": "",

          "timezone_abbr": "",

          "timezone_gmt": "GMT05" 

}

request

Contains any additional request left by a client. See example below.

"request": "additionalRequest"

tracking_qrcode_url

Contains a Tracking QRCode provided with the appointment. See example below.

"tracking_qrcode_url": ""

 

Attendees

The object “attendees” contains an array of client objects, one for each client associated with a group reservation. This array is of length “number” where that value describes the number of clients (ex. "number": 1).

Field or Object

Description

attendees

"number" : 1,
   "attendees": [
   {
     "firstname": "",
     "lastname": "",
     "email": "",
     "membership": "",
      "home_phone": "",

     "home_phone_detail": {
       "raw": "0000000000",
       "formatted": "+41 44 668 18 00",
       "detail": {
           "international": "+41 44 668 18 00",
           "national": "044 668 18 00",
           "E164": "+41446681800",
           "country_code": "41"  }
     },
     "mobile_phone": "",
     "mobile_phone_detail": {
         "raw": "0000000000",
         "formatted": "+41 44 668 18 00",
         "detail": {
               "international": "+41 44 668 18 00",
               "national": "044 668 18 00",
               "E164": "+41446681800",
               "country_code": "41" 
}
     },
     "gender": "",
     "lang": "",
     "language": "",
     "timeZone": "",
     "timezone_detail": {
         "timezone_str": "",
         "timezone_abbr": "",
         "timezone_gmt": "GMT05"  },
     "request": "additionalRequest",
     "tracking_qrcode_url": ""
   }
  ]

 

Services

The object “services” contains an array of all services included in an appointment. It is formatted as a multi-field object and contains the following fields.

Field or Object

Description

id

Contains a service’s ID.

name

Contains a service’s name.

description

Contains a service’s description.

instruction

Contains instructions assigned with a service. Can be empty.

tags

Contains a list of tags assigned to the service.

location

Contains the location at which a service will be rendered.

location_text

Contains a service’s location in text format.

image

Contains the URL to a service’s image if any.

amount

Contains a service’s price. See example below.

"amount": "price.amount"

staff

Contains an array of all staff required to render all services assigned with an appointment.

"staff": 
[
{
"firstname": "John",
"lastname": "Smith",
"profile_image_url": "" ,
"email": "staff_email@domain.mail"
}
]

date

Contains the date, start and end times on which services will be rendered. It is formatted as a multi-field object. See example below.

"date": {

         "start": {
               "year": 2000,
               "month": 1,
               "c_month": "01",
               "s_month_shorty": "jan",
               "day": 1,
               "c_day": "01",
               "s_day": "monday",
               "s_day_short": "mon",
               "half_day": "am|pm",
               "hour": 13,
               "u_hour": 1,
               "c_hour": "13",
               "u_c_hour": "01",
               "minute": 1,
               "c_minute": "01",
               "second": 1,
                "c_second": "01" 
},

         "end": {
               "year": 2000,
               "month": 1,
               "c_month": "01",
               "s_month_shorty": "jan",
               "day": 1,
               "c_day": "01",
               "s_day": "monday",
               "s_day_short": "mon",
               "half_day": "am|pm",
               "hour": 13,
               "u_hour": 1,
               "c_hour": "13",
               "u_c_hour": "01",
             "minute": 1,
               "c_minute": "01",
               "second": 1,
                "c_second": "01" 

}

duration

Contains the total duration for all services to be provided. Formatted as a multi-field object. See example below.

"duration": {
         "hours": 1,
         "c_hours": "01",
         "minutes": 1,
         "c_minutes": "01" 
}

survey

Contains an array of questions constituting a survey. See example below.

"survey": 
[
{
"name": "name",
"question": "question",
"answer": "answer" 
}
]

currency

Contains the currency associated with a service (merchant owner). Formatted as a multi-field object. See example below.

"currency": {
         "raw": "EUR",
         "symbol": "€" 
}

category

Contains a service’s category. Formatted as a multi-field object. See example below.

"category": {
"id": "category id",
"name": "category name",
"description": "category description",
"image": "category image",
"translation":
{
"fra":
{
"language": "fra",
"name": "category name translated",
"description": "category description translated"
    },
"client_language_exist": true,
"staff_language_exist": true 
}
}

resource

Contains the resource assigned to a service. Formatted as a multi-field object. See example below.

"resource": {
"id": "resource id",
"name": "resource name",
"translation":
{
"fra":
{
"language": "fra",
"name": "resource name translated"
    },
"client_language_exist": true,
"staff_language_exist": true 
}
}

translation

Contains a service’s translation. Formatted as a multi-field object. See example below.

"translation": 
{
"fra":
{
"language": "fra",
"name": "service name translated",
"client_language_exist": true,
"staff_language_exist": true 
}
}

availabilities

Contains an array of availability associated with services included in the appointment. Formatted as a multi-field object. See example below.

"availabilities": 
[
{
"start":
{
"year": 2000,
      "month": 1,
      "c_month": "01",
      "s_month_shorty": "jan",
      "day": 1,
      "c_day": "01",
      "s_day": "monday",
      "s_day_short": "mon",
      "half_day": "am|pm",
      "hour": 13,
      "u_hour": 1,
      "c_hour": "13",
      "u_c_hour": "01",
      "minute": 1,
      "c_minute": "01",
      "second": 1,
      "c_second": "01"
    },

"end":
{
     "year": 2000,
      "month": 1,
      "c_month": "01",
      "s_month_shorty": "jan",
      "day": 1,
      "c_day": "01",
      "s_day": "monday",
      "s_day_short": "mon",
      "half_day": "am|pm",
      "hour": 13,
      "u_hour": 1,
      "c_hour": "13",
      "u_c_hour": "01",
      "minute": 1,
      "c_minute": "01",
      "second": 1,
      "c_second": "01" 
}
}
]

 

Surveys

The object “surveys” contains an array of all answers collected through the use of surveys. It is formatted as a multi-field object.

Field or Object

Description

name

Contains a survey’s name.

title

Contains a survey’s title.

required

Is filling a survey required or optional? See example below.

"required": true

answer

Contains a survey’s answer.

translation

Contains translations for each supported language. See example below.

"translation": 
{
"fra":
{
"language": "fra",
"title": "",
"client_language_exist": true,
"staff_language_exist": true 
}
}

 

Payment

The object “payment” contains all information pertaining to an appointment’s payment. It is formatted as a multi-field object and contains the following fields.

Field or Object

Description

total

Contains a payment’s total amount. See example below.

"total": "10.30"

total_detail

Contains the total’s integer and decimal components as separate fields. See example below.

"total_detail": {
       "integer": 10,
        "decimal": 30  }

subtotal

Contains a payment’s subtotal, excluding any applicable taxes. See example below.

"subtotal": "7,30"

subtotal_detail

Contains the subtotal’s integer and decimal components as separate fields. See example below.

"subtotal_detail": {
       "integer": 7,
        "decimal": 30  }

due

Contains a payment’s due amount. See example below.

"due": "9,10"

due_detail

Contains the due’s integer and decimal components as separate fields. See example below.

"due_detail": {
       "integer": 9,
        "decimal": 10  }

currency

Contains the payment’s currency details. It includes a 3-letter ID and its symbol. See example below.

"currency": {
       "raw": "EUR",
        "symbol": "€"  }

payment_online_amount

Contains the amount to be paid online. See example below.

"payment_online_amount": "onlinePaymentAmount"

payment_status

Contains the latest payment’s status. See example below.

"payment_status": "onlinePaymentStatus"

taxes

Contains an array of all applicable taxes. It is formatted as a multi-field object array. See example below.

"taxes": 
[
{
"name": "tax name",
"rate": "11%",
"amount": "2,10",
"amount_detail":
{
"integer": 2,
"decimal": 10
    }
}
]

 

Staff

The object “staff” contains all information related to the staff member who is rendering a service associated with the appointment. It is formatted as a multi-field object and includes the following fields.

Field or Object

Description

firstname

Contains the staff’s first name.

lastname

Contains the staff’s last name.

language

Contains the staff’s language.

biography

Contains the staff’s biography or description.

position

Contains the staff’s position or title within the organization.

profile_image

Contains the staff’s profile image URL.

email

Contains the staff’s email address. See example below.

"email": "staff_email@domain.mail"

translation

Array which contains translations for biography and position in all supported languages. See example below.

"translation": 
{
"fra":
{
"language": "fra",
"position": "position translated"
},
"client_language_exist": true,
"staff_language_exist": true 
}

 

Event

The object “event” contains the start and end time of an appointment as well as its duration. It is formatted as a multi-field object and contains the following fields.

Field or Object

Description

start

Contains the event’s start time in detail and in several formats. See example below.

"start": {
       "year": 2022,
       "month": 1,
       "c_month": "01",
       "s_month_shorty": "jan",
       "day": 1,
       "c_day": "01",
       "s_day": "monday",
       "s_day_short": "mon",
       "half_day": "am|pm",
       "hour": 13,
       "u_hour": 1,
       "c_hour": "13",
       "u_c_hour": "01",
       "minute": 1,
       "c_minute": "01",
       "second": 1,
       "c_second": "01"
}

end

Contains the event’s end time in detail and in several formats. See example below.

"end": {
       "year": 2022,
       "month": 1,
       "c_month": "01",
       "s_month_shorty": "jan",
       "day": 1,
       "c_day": "01",
       "s_day": "monday",
       "s_day_short": "mon",
       "half_day": "am|pm",
       "hour": 14,
       "u_hour": 2,
       "c_hour": "14",
       "u_c_hour": "02",
       "minute": 1,
       "c_minute": "01",
       "second": 1,
       "c_second": "01" 
}

duration

Contains the event’s duration in several formats. See example below.

"duration": {
       "hours": 1,
       "c_hours": "01",
       "minutes": 1,
       "c_minutes": "01"
}

Limitations

The template assignment is performed by Booxi.

Use Cases

Filtering Content per Language

Content can be filtered based on the client’s preferred language. The example below showcases how to display a service’s name in the client’s language by validating if the translation exists and if so, use its value.

{{#each services}}
{{#if this.translation.client_language_exist}}
{{#each this.translation}}
{{#equals this.language @root.client.language}}
{{this.name}}
{{/equals}}
{{/each}}
{{else}}
{{this.name}}
{{/if}}
{{/each}}

Troubleshooting

Your SendGrid account was configured with an email address to inform you whenever there is an error preventing SendGrid from sending emails.

If you receive an error message regarding an invalid template, it is because one of the templates you configured Booxi connector with, is not accessible anymore. It may have been deleted since, or the associated template does not have any active version.

A message was received from this address by our systems that had errors in the SMTPAPI header, and cannot be processed due to the following:

  - The template id must be a valid template id for your account. 

Documentation and External Links 

SendGrid’s How to Create Templates

Template Guide 

HandleBars

How to Use Handlebars with SendGrid