Skip to main content
Skip table of contents

Booking Lifecycle - Email Templates and Transmission

Introduction

During the life of a booking, our system will transmit several emails to different parties.

Configuration is required to control many aspects of this including

  • Which emails are sent

  • To whom they are sent and copied to

  • From what address they are sent

  • The templates that are used in the generation of the emails

  • The languages that are used within the emails.

The Emails

The system currently supports the following emails.

Booking Emails

Booking type emails combine a list of booking availabilities. These emails are typically sent when the state of relevant booking availabilities changes.

To enhance user experience, booking emails can reflect the availability status. For instance, if all availabilities are canceled, the booking can be shown as canceled, or a warning can be included indicating that some availabilities have been canceled.

Template

Possible Recipients

Notes and Conditions

Booking Acknowledgement

Sent immediately after the booking changes have been committed.

  • Consumer

  • Channel

  • Agent

  • Holibob

This email is sent immediately upon receipt of a request to change a booking. It is triggered when any of the booking availabilities are in a pending state and are about to be committed, canceled, or amended.

Booking Summary

Sent once the booking changes have been confirmed. This is commonly only a few minutes after the acknowledgement email.

  • Consumer

  • Channel

  • Agent

  • Holibob

This email is sent once all pending booking availability changes have been confirmed, and payments have been processed. Typically, this occurs within a few minutes after the request to commit the booking. However, in cases where failures occur due to downstream systems or when one or more products on the booking require acknowledgment from the supplier/operator, the delay may be greater.

Booking Failure

Dispatched to our internal support team in the event when a booking fails to complete through the standard operational process.

  • OnCall

  • Channel *

  • Agent *

Sent in the event of failure of any part of the commit process whether internal or as a result of errors returned by source systems. Email usually includes technical details of an error.

IN PROGRESS - only OnCall email are currently supported.

IN PROGRESS - given that an email can comprise various booking availabilities, it is possible for some availabilities to be in a failed state. The communication of this failed state to the consumer via the Booking Summary email is not always desirable behaviour.

IN PROGRESS - the distribution of failure emails to Channel and Agent, as well as the level of technical detail included in these emails, is currently under discussion

Booking Availability Emails

Booking availability type emails are sent for each individual booking availability, typically when the availability is confirmed, canceled, or reminded.

Template

Possible Recipients

Notes and Conditions

Booking Availability Confirmation

Sent to advise that a booking availability has been successfully confirmed.

  • Supplier

  • Channel

  • Holibob

Sent only for INTERNAL products to advise the supplier of a booking confirmed for one of their products.

  • Finance

Sent only for production booking availabilities.

(07/06/2024) requested by @a user not to send these as “already have the Stripe notification turned on for new bookings“.

Booking Availability Cancellation

Sent to advise that a booking availability has been successfully cancelled.

  • Supplier

  • Channel

  • Holibob

Sent only for INTERNAL products to advise the supplier of a booking cancelled for one of their products.

  • Finance

Sent only for production booking availabilities.

Booking Availability Confirmation Request

Sent for any INTERNAL product that is marked as ON_REQUEST to confirm the booking availability.

  • Supplier

  • Channel

  • Holibob

Sent only for INTERNAL products and only where the product is configured for ON_REQUEST. This email contains a button that links back to Extranet allowing the supplier to either accept or reject the booking availability. The consumer will not receive a Booking Summary until the supplier has taken action.

Booking Availability Cancellation Request

Sent for any INTERNAL product that is marked as ON_REQUEST to accept cancellation of the booking availability.

  • Supplier

  • Channel

  • Holibob

Sent only for INTERNAL products and only where the product is configured for ON_REQUEST. This email contains a button that links back to Extranet allowing the supplier to either accept cancellation or reject the booking availability. The consumer will not receive a Booking Summary until the supplier has taken action.

Booking Availability Pre Arrival Instructions

Sent two days (or less) prior to the start of the booking availability. The email contains any pre-arrival information that is configured on the product.

  • Consumer

  • Channel

  • Agent

  • Holibob

PLANNED for BLM Milestone 5

Sent only if the product has a content section for PRE_ARRIVAL_INSTRUCTIONS, which may be entered via the Product Domain UX.

Booking Availability Reminder Email

Sent a few days prior to the start of the booking availability.

  • Consumer

  • Channel

  • Agent

  • Holibob

NOT IMPLEMENTED

Booking Availability Pending Reminder Email

Sent when the booking availability has been marked for cancellation or amendment, but the change was not committed.

  • Consumer

  • Channel

  • Agent

  • Holibob

NOT IMPLEMENTED

Booking Availability Feedback Email

Sent when the booking availability has finished, and we seek to gather feedback about the experience.

  • Consumer

  • Channel

  • Agent

  • Holibob

NOT IMPLEMENTED

Important Notes

External Parties

Consumer, Agent, Channel, and Supplier are considered external parties.

Although the same template is utilised for different recipients, it's not always the case that the email has the same subject or content. Certain recipients may require different subject line formatting for improved traceability; or inclusion of additional information in the content (e.g., price breakdown). Moreover, different recipients may require emails in languages other than the booking language. It's important to note that when the system sends emails to different parties, it sends individual copies and does not utilise the CC function. This is to ensure that the addresses of other parties involved in the transaction are not inadvertently disclosed in the transaction.

In transactions involving agencies, it's common for emails to be duplicated to the agent who made the booking and, in some cases, to a central email address for the agency and/or the partner. For further details, refer to the configuration section below.

Internal Parties

The Customer Support Team (referred to as Holibob), OnCall, and Finance are considered internal parties.

Holibob receives all types of emails in English for every relevant production booking, detailing the recipients and reasons why certain emails were not sent. The only exceptions are:

  • Booking Availability Confirmation/Cancellation email is not sent if the product is not INTERNAL.

  • Booking Availability PreArrival Instruction email is not sent if the product does not have PRE_ARRIVAL_INSTRUCTIONS.

  • Booking Availability Confirmation/Cancellation Request email is not sent if the product is not INTERNAL and is not ON_REQUEST.

Additionally, Holibob receives a BCC of every email sent to other parties (excluding Finance and OnCall) and, upon request, forwards a copy of the email if one of the parties cannot locate the original.

Logging

All email transactions are tracked in our logging system, which consistently specifies the log code, email subject, sent time, and the recipients of an email. Furthermore, the system logs the reasons for omitting specific recipients from receiving emails. Please see Email Sender Logic & Entity Configuration - Holibob Technology - Confluence (atlassian.net) for the actual log structure.

TODO - the support team can see the email logs in a user-friendly format per individual Booking.

Configurations

PLANNED - implementation and migration of configuration is yet to be done.

Our systems include a feature known as Entity Configuration. This allows many different settings to be applied across the hierarchy of Business Principals. Any setting that is set at The Company (Holibob) level will apply to all partners, channels, users etc in the system unless this same setting is overwritten at a lower level. Equally a setting made at the Partner level will be applied to all of their channels unless the same setting is applied differently to one or more channels.

There are many other entity configuration available to the implementation team. This list is limited to those most relevant to the booking completion flows.

Name & Description

Config Name

Company Value

CONTENT

Used to inject information into emails, vouchers and the White-label sites.

Content - Appended to Supplier Booking Confirmation

Set for each language - Appears at the end of each supplier booking confirmation email.

SUPPLIER_CONFIRMATION_BODY_CONTENT

Content - Appended to Supplier Onboarding

Set for each language - Appears at the end of each onboarding email.

Content - Consumer Disclaimer

Set for each language - Controls the text that appears in the footer of all consumer emails.

CONSUMER_EMAIL_DISCLAIMER

DISCLAIMER

The content of this email is confidential and intended for the recipient specified in message only. It is strictly forbidden to share any part of this message with any third party, without a written consent of the sender. If you received this message by mistake, please reply to this message and follow with its deletion, so that we can ensure such a mistake does not occur in the future.

Content - Customer Service Phone number

Set to phone number - Appears on all consumer communications including vouchers

CUSTOMER_SERVICE_PHONE_NUMBER

+44 20 805 09518

Content - Customer Service Email Address

Set to an email address but used as text - Appears on all consumer communications including vouchers

CUSTOMER_SERVICE_EMAIL_ADDRESS

bookings@holibob.tech

Content - Postal address for Footer

Set for each language - Appears in the footer of all emails.

SUPPLIER_SERVICE_PHONE_NUMBER

Content for Supplier Service Email Address

Set to email address but used as text - Appears on all supplier communications

SUPPLIER_SERVICE_EMAIL_ADDRESS

ENABLEMENT (YES/NO)

Used to control functionality of email and booking flow

Enable Notifications to Consumer

When true - Sends acknowledgement, summary and pre-arrival-instructions to the Consumers's email.

ENABLE_CONSUMER_NOTIFICATION

SEND_CONSUMER_CONFIRMATION

YES

Enable Notifications to Supplier

When true - Sends Internal Product confirmations and cancellations to the Supplier's email.

ENABLE_SUPPLIER_NOTIFICATION

YES

Direct Application Enable Notifications to Consumer

hen true - Sends consumer emails when the booking was created by API partners.

ENABLE_DIRECT_APPLICATION_CONSUMER_NOTIFICATION

YES

Enable Consumer Notifications to Agent

When true - Sends acknowledgement, summary and pre-arrival-instructions to the Agent's email.

ENABLE_AGENT_CONSUMER_NOTIFICATION

ENABLE_AGENT_CONFIRMATION_NOTIFICATION

NO

Enable Consumer Failure Notifications to Agent

When true - Sends a copy of all booking failures to the Agent's email address.

ENABLE_AGENT_CONSUMER_FAILURE_NOTIFICATION

ENABLE_AGENT_FAILURE_NOTIFICATION

NO

Enable Consumer Notifications to Channel

When true - Sends a copy of consumer related emails to the Partner Channel’s email address.

ENABLE_CHANNEL_CONSUMER_NOTIFICATION

NO

Enable Supplier Notifications to Channel

When true - Sends a copy of supplier related emails to the Partner Channel’s email address.

ENABLE_CHANNEL_SUPPLIER_NOTIFICATION

NO

Enable Supplier BCC Notifications to Channel

When true - Sends a hidden copy (BCC) of supplier related emails to the Partner Channel’s email address.

ENABLE_CHANNEL_SUPPLIER_BCC_NOTIFICATION

NO

Enable Failure Notifications to Channel

When true - Sends a copy of all booking failures to the Partner Channel’s email address.

ENABLE_CHANNEL_CONSUMER_FAILURE_NOTIFICATION

NO

FROM Addresses

Used to control the email address from which certain emails are sent.

Holibob Default

Set to an email address - default address if nothing else

N/A

bookings@operations.holibob.tech

FROM Email Address (Default)

Set to an email address - Causes all outbound consumer emails to be sent from this address.

Requires domain setup by the partner and tech.

SENDER_EMAIL_ADDRESS_DEFAULT

FROM Email Address (Consumer Only) - DEPRECATED, always use FROM Email Address

Set to an email address - Causes all outbound consumer emails to e sent from this address.

Requires domain setup by the partner and tech.

SENDER_EMAIL_ADDRESS_CONSUMER

FROM Email Address (Supplier Onboard Only) - DEPRECATED, always use FROM Email Address

Set to an email address - Causes all outbound consumer emails to be sent from this address.

Requires domain setup by the partner and tech.

SENDER_EMAIL_ADDRESS_SUPPLIER

RECIPIENT Addresses

Used to enable to duplication of certain emails to additional addresses

In all cases all emails are also sent to The Company (Holibobs) internal customer services inbox

Holibob Default

Set to an email address - causes all Holibob (including BCC) emails to be sent to this address

N/A

holibobbookings@holibob.tech

OnCall Default

Set to an email address - causes all failure emails to be sent to this address

N/A

oncall@holibob.tech

Finance Default

Set to an email address - causes all finance emails to be sent to this address

N/A

partnerfinance@holibob.tech

Global Address for all Consumer Notifications

Set to an email address - Causes all consumer emails to be duplicated to this address - typically used in agent setups.

CHANNEL_CONSUMER_NOTIFICATION_EMAIL_ADDRESS

EXTRA_CONFIRMATION_EMAIL_ADDRESS

Global Address for all Supplier Notifications

Set to an email address - Causes all supplier emails to be duplicated to this address.

CHANNEL_SUPPLIER_NOTIFICATION_EMAIL_ADDRESS

INTERNAL_BOOKING_AVAILABILITY_NOTIFICATION_EMAIL_ADDRESS

Global Address for all Booking Failures

Set to an email address - Causes all booking failures emails to be duplicated to this address.

CHANNEL_FAILED_BOOKING_NOTIFICATION_EMAIL_ADDRESS

FAILED_BOOKING_NOTIFICATION_EMAIL_ADDRESS

CHANNEL_FAILURE_NOTIFICATION_EMAIL_ADDRESS

Reply-To Addresses

The email address used when replying to any email that is sent from the booking system

Default

Set to an email address - all replies to booking system emails to be routed here

N/A

holibobbookings@holibob.tech

Communications - REPLY-TO Email Address (Consumer Only)

Set to an email address - Causes all replies to consumer booking transactional to be routed here

Requires domain setup by the partner and tech.

CONSUMER_REPLY_TO_EMAIL_ADDRESS

TEMPLATES

Used to determine which template is loaded to generate a given email.

Where these are not set the system default templates will be used

TemplateId - for Booking Acknowledgement Email

Set to the ID of a SystemTemplate - Controls the design of the email sent after a booking is committed to the source.

EMAIL_BOOKING_ACKNOWLEDGEMENT_TEMPLATE_ID

EMAIL_ACKNOWLEDGEMENT_ENTITY_TEMPLATE_ID

eaa07e92-cb93-11ec-82e2-06a93a7b20b5

TemplateId - for Booking Summary Email

Set to the ID of a SystemTemplate - Controls the design of the email sent when booking changes have been confirmed.

EMAIL_BOOKING_SUMMARY_TEMPLATE_ID

EMAIL_ENTITY_TEMPLATE_ID

91bfd3a9-7dbb-11ec-8d17-06fbe1941b5f

TemplateId - for Consumer On Arrival Instructions email

Set to the ID of a SystemTemplate - Controls the design of the email sent to consumers about ob arrival instructions.

EMAIL_BOOKING_AVAILABILITY_ON_ARRIVAL_INSTRUCTIONS_TEMPLATE_ID

26b47ef3-da18-11ee-b580-061aef1a49c3

TemplateId - for Booking Availability Confirmation Email

Set to the ID of a SystemTemplate - Controls the design of the email sent when booking availability changes the state to confirmed.

EMAIL_BOOKING_AVAILABILITY_CONFIRMATION_TEMPLATE_ID

4672b750-c091-11ec-985b-0694cb7dd74f

TemplateId - for Booking Availability Cancellation Email

Set to the ID of a SystemTemplate - Controls the design of the email sent when booking availability changes the state to cancelled.

EMAIL_BOOKING_AVAILABILITY_CANCELLATION_TEMPLATE_ID

6b674072-edd9-11ee-9ca6-067d384bcad5

TemplateId - for Booking Availability On Request Confirmation Email

Set to the ID of a SystemTemplate - Controls the design of email sent to the supplier to confirm the booking availability confirmation request.

EMAIL_BOOKING_AVAILABILITY_ON_REQUEST_CONFIRMATION_TEMPLATE_ID

5ce40089-630b-40f5-880d-e784146c5d11

TemplateId - for Booking Availability On Request Cancellation Email

Set to the ID of a SystemTemplate - Controls the design of email sent to the supplier to confirm the booking availability cancellation request.

EMAIL_BOOKING_AVAILABILITY_ON_REQUEST_CANCELLATION_TEMPLATE_ID

ca610746-6c54-4a1b-af95-b80cbe003496

TemplateId - for Booking Failure Email

Set to the ID of a SystemTemplate - Controls the design of the email sent when booking or booking availability fails.

EMAIL_BOOKING_FAILURE_TEMPLATE_ID

cb361d8d-8461-4f34-bc6d-64bdaa1052a1

OTHER

URL for Manage My Booking

When active it replaces confirmation manage my booking CTA link.

MANAGE_MY_BOOKING_URL_TEMPLATE

Default’s to Holibob White-Label address.

Enable Communications Manage My Booking Button

When active it Displays the 'Manage My Booking' button emails and vouchers.

ENABLE_MANAGE_MY_BOOKING_BUTTON

YES

The Recipients and the subject lines 

Emails may be sent to any of the following parties

  • Holibob General Booking - HARD CODED as: HolibobBookings@holibob.tech (this would make more sense as GeneralBookings@holibob.tech)

  • Holibob General Finance - HARD CODED as: PartnerFinance@holibob.tech

  • The PartnerChannel Central Mailbox - from EntityConfiguration

  • The Agent - from the Agent user profile

  • The Consumer - from the lead passenger email booking question

  • The Supplier - from the Supplier profile (internal products only)

The logic for each email will construct an array of

  • Recipient Type: ie the Consumer, Agent, Supplier, ChannelGlobal etc

  • Email Address: the actual address that was determined

  • Subject Line: the subject line that would appear in the recipients in-box

  • Omitted Reason: Any reason that this email was NOT sent. ie “No agent present” or “Not configured” or “Sent previously”

The FROM address should always be read from EntityConfiguration. Note there is a default value and a specific value for consumer communications

Every email is ALWAYS sent to our central mailbox holibobbookings@holibob.tech and then conditionally sent to others with a modified subject line.

Subject Lines depend on who the recipient is

where 

  • <template> - the name of the template ie "Booking Summary"

  • <code> - the Booking.code or the BookingAvailability.code

  • <leadName> - the LeadPassengerName

  • <productName> - the ProductName in the correct language

  • <channel> - the name of the PartnerChannel ie "House of Travel" 

  • <consumptionDate> - the date of consumption in product local time WITH TIMEZONE

  • <consumptionTime> - the time of the consumption in product local time

Thus the subjects are

Recipient

Subject Constructor

Example

Holibob General Booking Internal Shared Mailbox

All outbound emails are sent to the Holibob General Bookings mailbox for the purposes of monitoring.

<channel> - <template>: <code> for <leadName>

House of Travel - Booking Confirmation: ABC123 for Graeme Bryce

Holibob General Finance Internal Shared Mailbox

Some messages may be sent to the holibob finance team

Partner Channel External Mailbox

Subject to configuration some emails may be sent to an external central mailbox operated by the Partner

<template>: <code> for <leadName> 

Booking Confirmation: ABC123 for Graeme Bryce

The Consumer

Subject to configuration some emails may be sent to the consumer (aka Lead Passenger) However this can be disabled thus allowing the agent to control all communication with the consumer

<channel> - <template>: <code>

House of Travel - Booking Confirmation: ABC123

The Agent
Subject to configuration some emails may be sent to the agent that confirmed or cancelled a booking.

<template>: <code> for <leadName> 

Booking Confirmation: ABC123 for Graeme Bryce

The Supplier
Emails relating to the internal products may be sent to the Supplier

<channel> - <template>:  <code> for <productName>

House of Travel - Product Booking: ZAS987 for My Special Product

Templates

Emails are created by reading a template from our database for the type of email to be sent.

These templates are in a format known as MJML (MailJet Markup Language). Our system supports default templates as well as partner-specific templates.

Templates can exist for many languages, including Arabic with right-to-left scripts.

Once a template has been loaded our system will inject all relevant data into the template before compiling the final result and passing it to the transmission system.

Each template may contain replacement values and conditional statements that will be processed at the time of compilation.

Example

The template shown is specific to a given partner channel.

Replacement Values

  • Values to be replaced are enclosed by [% … %]

  • Values are also prefixed by “it.” to indicate that where appropriate they will be subject to internationalisation such as for the formatting of dates, times and numbers.

Images

  • All images in the template must first be uploaded to the Holibob Image CDN and an appropriate URL with base64 encoded size data used to load the image in the template.

Fonts

  • The default fonts and styles are included in the metadata at the head of the template code.

image-20240219-143923.png

Template Code

The code below is the MJML for the template shown above.

Expand to view MJML Template Example
CODE
<mjml lang="[%=lang%]" dir="[%=dir%]">
    <mj-head>
        [%~rtlXML%]
        <mj-font
            name="Brown"
            href="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/fonts/brown/brown.css?no-cache=0003"
        />
        <mj-raw>
            <meta name="color-scheme" content="light dark" />
            <meta name="supported-color-schemes" content="light dark" />
        </mj-raw>
        <mj-attributes>
            <mj-text line-height="1.8" font-size="14px" font-family="Brown, Arial, Helvetica, sans-serif" />
            <mj-table font-size="14px" font-family="Brown, Arial, Helvetica, sans-serif" />
            <mj-section background-color="#f9f7f1" padding="20px 0 0 0" css-class="dark-mode-section" />
        </mj-attributes>
        <mj-style inline="inline">
            :root { color-scheme: light dark; supported-color-schemes: light dark; } @media (prefers-color-scheme: dark)
            { body {background-color: red} .dark-mode-section table2 { background: #1E1E1F; background-image:
            linear-gradient (#fec800, #fec800) !important; } .dark-mode-text div { color: blue !important; }
            .dark-mode-hide {display:none !important} } @media (prefers-color-scheme: light) { .dark-mode-hide
            {display:none !important} .dark-mode-text div { color: red !important; } }
        </mj-style>
        <mj-style> .dark-mode-text div { color: black; } </mj-style>
        <mj-style>
            .effective-state div { color: red !important; text-transform: uppercase; } .effective-state.CONFIRMED div {
            color: green !important; } .effective-state.PENDING div { color: blue !important; } .effective-state.ENDED
            div, .effective-state.CANCELLED div { color: red !important; } .effective-state.AMENDED div { color: orange
            !important; }
        </mj-style>
    </mj-head>
    <mj-body>
        <mj-section background-color="#fff">
            <mj-column>
                <mj-image
                    css-class=".lightImage"
                    width="100px"
                    src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/logo-english.png"
                />
            </mj-column>
        </mj-section>
        <!-- HERO -->
        <mj-hero
            mode="fixed-height"
            height="250px"
            background-width="600px"
            background-height="100px"
            background-url="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/hero-sindalah.jpg"
            background-color="#2a3448"
            padding="10px 0px"
        >
            <mj-text padding="20px" color="#fff" font-size="30px" line-height="45px" font-weight="900">
                [%=it.confirmationEmailLabel%]
            </mj-text>
        </mj-hero>
        <mj-section>
            <mj-column>
                <mj-text line-height="1.8">Dear [%=it.booking.leadPassengerGivenName%]</mj-text>
                <mj-text line-height="1.8">Thank you for booking with [%=it.booking.partnerChannelName%].</mj-text>
                [% if (it.bookingAvailabilityList.some(({ state }) => state === "FAILED")) { %]
                <mj-text line-height="1.8" color="red">Some bookings couldn't be processed successfully. Please check the details below. If the issue persists, contact support for assistance.</mj-text>
                [% } %]
            </mj-column>
        </mj-section>

        <!-- BOOKING DETAILS -->
        <mj-section>
            <mj-column>
                <mj-text font-size="20px" color="#bd8714">[%=it.booking.customerInformationLabel%]</mj-text>
            </mj-column>
        </mj-section>

        <mj-section padding-top="0">
            <mj-column>
                <mj-divider padding-top="0" border-width="1px" border-style="solid" border-color="lightgrey" />
            </mj-column>
        </mj-section>

        <mj-section>
            <mj-column width="30%">
                <mj-text padding-top="0" padding-bottom="0" font-weight="bold"
                    >[%=it.booking.leadPassengerNameLabel%]</mj-text
                >
            </mj-column>
            <mj-column width="70%">
                <mj-text padding-top="0" padding-bottom="0">[%=it.booking.leadPassengerName%]</mj-text>
            </mj-column>
        </mj-section>

        <mj-section padding-top="5px">
            <mj-column width="30%">
                <mj-text padding-top="0" padding-bottom="0" font-weight="bold">[%=it.booking.codeLabel%]</mj-text>
            </mj-column>
            <mj-column width="70%">
                <mj-text padding-top="0" padding-bottom="0">[%=it.booking.code%]</mj-text>
            </mj-column>
        </mj-section>

        <!-- EXPERIENCES HEADER -->
        <mj-section>
            <mj-column>
                <mj-text font-size="20px" color="#BD8714">[%=it.booking.bookingSummaryLabel%]</mj-text>
            </mj-column>
        </mj-section>

        <mj-section padding-top="0">
            <mj-column>
                <mj-divider padding-top="0" border-width="1px" border-style="solid" border-color="lightgrey" />
            </mj-column>
        </mj-section>

        <!-- SUB TEMPLATE -->
        [% it.bookingAvailabilityList.forEach(({ productUrl, code, codeLabel, startAtLabel, endAtLabel, type,
        effectiveStartAt, effectiveEndAt, effectiveStateLabel, effectiveState, product, totalPrice,
        cancellationPenaltyListLabel, cancellationPenaltyList, pricingCategoryCountList, isFinished }, idx, list) => {
        %]
        <mj-wrapper padding="0" full-width>
            <mj-section padding-top="0" padding-bottom="10px">
                <mj-column width="70%">
                    <mj-text line-height="1.1" font-size="20px"> [%=product.name%] </mj-text>
                    <mj-text
                        line-height="1"
                        font-size="12px"
                        padding-top="0"
                        css-class="effective-state [%=effectiveState%]"
                        >[%=effectiveStateLabel%]</mj-text
                    >
                    <mj-text line-height="1" padding-top="0" font-weight="bold"
                        >[%=totalPrice.grossFormattedText%]</mj-text
                    >
                    [% pricingCategoryCountList.forEach(({ label, count }) => { %]
                    <mj-text line-height="1" padding-top="0">
                        <span style="font-weight: bold">[%=count%]</span>
                        <span>&nbsp;x&nbsp;</span>
                        <span style="font-size: 12px">[%=label%]</span>
                    </mj-text>
                    [% }) %]
                </mj-column>
                <mj-column width="30%">
                    <mj-image
                        fluid-on-mobile="true"
                        align="center"
                        src="[%=product.previewImageUrl%]"
                        href="[%=productUrl%]"
                        alt="Product Image"
                        padding-bottom="0"
                    />
                </mj-column>
            </mj-section>

            <mj-section padding-top="0">
                <mj-column width="30%">
                    <mj-text padding-top="0" padding-bottom="0" font-weight="bold" font-size="12px"
                        >[%=codeLabel%]</mj-text
                    >
                </mj-column>
                <mj-column width="70%">
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px">[%=code%]</mj-text>
                </mj-column>
            </mj-section>

            [% if (effectiveStartAt) { %]
            <mj-section padding-top="5px">
                <mj-column width="30%">
                    <mj-text padding-top="0" padding-bottom="0" font-weight="bold" font-size="12px"
                        >[%=startAtLabel%]</mj-text
                    >
                </mj-column>
                <mj-column width="70%">
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px">[%=effectiveStartAt%]</mj-text>
                </mj-column>
            </mj-section>
            [% } %] [% if (effectiveEndAt) { %]
            <mj-section padding-top="5px">
                <mj-column width="30%">
                    <mj-text padding-top="0" padding-bottom="0" font-weight="bold" font-size="12px"
                        >[%=endAtLabel%]</mj-text
                    >
                </mj-column>
                <mj-column width="70%">
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px">[%=effectiveEndAt%]</mj-text>
                </mj-column>
            </mj-section>
            [% } %]

            <mj-section padding-top="5px">
                <mj-column>
                    <mj-text padding-top="0" padding-bottom="0" font-weight="bold" font-size="12px"
                        >[%=product.startPlace.addressLabel%]</mj-text
                    >
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px">[%=product.startPlace.name%]</mj-text>
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px"
                        >[%=product.startPlace.formattedAddress%]</mj-text
                    >
                </mj-column>
            </mj-section>

            [% if (!isFinished) { %]
            <mj-section padding-top="5px">
                <mj-column>
                    <mj-text padding-top="0" padding-bottom="0" font-weight="bold" font-size="12px"
                        >[%=cancellationPenaltyListLabel%]</mj-text
                    >
                    [% cancellationPenaltyList.forEach(({ formattedText }) => { %]
                    <mj-text padding-top="0" padding-bottom="0" font-size="12px"> [%=formattedText%] </mj-text>
                    [% }) %]
                </mj-column>
            </mj-section>
            [% } %] [% if (idx !== list.length - 1){ %]
            <mj-section padding-top="5px">
                <mj-column>
                    <mj-divider border-width="1px" border-style="solid" border-color="lightgrey" />
                </mj-column>
            </mj-section>
            [% } %]
        </mj-wrapper>
        [% }) %]

        <mj-section>
            <mj-column>
                <mj-divider border-width="1px" border-style="solid" border-color="lightgrey" />
            </mj-column>
        </mj-section>

        <!-- INSTRUCTIONS -->
        [% if (!it.booking.isFinished) { %]
        <mj-section>
            <mj-column>
                <mj-button
                    padding="0"
                    href="[%=it.booking.manageBookingUrl%]"
                    border-radius="20px"
                    background-color="#EBC03F"
                    align="center"
                    font-weight="600"
                    color="black"
                    >[%=it.booking.manageBookingLabel%]</mj-button
                >
            </mj-column>
        </mj-section>

        <mj-section>
            <mj-column>
                <mj-text line-height="1.8" padding-top="0"
                    >Should you need any assistance please use the "[%=it.booking.manageBookingLabel%]" button above.
                    Please find your full booking details and any tickets in the attached booking voucher.</mj-text
                >
            </mj-column>
        </mj-section>
        [% } %]

        <!-- GOOD BYE -->
        <mj-section css-class="section-main bottom">
            <mj-column>
                <mj-text line-height="1.8" padding-top="0">Thank you for your booking.</mj-text>
                <mj-text>
                    <a href="mailto:[%=it.booking.customerServiceEmailAddress%]"
                        >[%=it.booking.customerServiceEmailAddress%]</a
                    >
                    <div>[%=it.booking.customerServicePhoneNumber%]</div>
                </mj-text>
            </mj-column>
        </mj-section>

        <!-- FOOTER -->
        <mj-section border-top="4px solid #ebbf3f" background-color="black">
            <mj-column>
                <mj-text align="center" color="white">
                    <h3>Follow us on our journey</h3>
                </mj-text>
                <mj-social font-size="15px" icon-size="30px" mode="horizontal">
                    <mj-social-element
                        name="linkedin-noshare"
                        background-color="#ebbf3f"
                        href="https://www.linkedin.com/company/discoverneom/"
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-linkedin.png"
                    />
                    <mj-social-element
                        name="youtube-noshare"
                        background-color="#ebbf3f"
                        href="https://www.youtube.com/c/NEOMChannel  "
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-youtube.png"
                    />
                    <mj-social-element
                        name="facebook-noshare"
                        background-color="#ebbf3f"
                        href="https://www.facebook.com/NEOM"
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-facebook.png"
                    />
                    <mj-social-element
                        name="instagram-noshare"
                        background-color="#ebbf3f"
                        href="https://www.instagram.com/discoverneom"
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-instagram.png"
                    />
                    <mj-social-element
                        name="tiktok-noshare"
                        background-color="#ebbf3f"
                        href="https://www.tiktok.com/@neom?lang=en"
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-tiktok.png"
                    />
                    <mj-social-element
                        name="snapchat-noshare"
                        background-color="#ebbf3f"
                        href="https://www.snapchat.com/add/neomsnaps"
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-snapchat.png"
                    />
                    <mj-social-element
                        name="x-noshare"
                        background-color="#ebbf3f"
                        href="https://twitter.com/NEOM  "
                        src="https://s3.eu-west-1.amazonaws.com/tech.holibob.images.public/neom-brand/icon-x.png"
                    />
                </mj-social>
                <mj-text align="center" color="white">
                    <h3>Address</h3>
                </mj-text>
                <mj-text align="center" color="grey">
                    <div>NEOM Company</div>
                    <div>Building 4758, Gayal, Tabuk Province, 49643 — Kingdom Of Saudi Arabia</div>
                </mj-text>
            </mj-column>
        </mj-section>
    </mj-body>
</mjml>

Extranet UX

The Consumer Trip Booking Email Management screen displays all relevant information for quickly understanding recipients and reasons.

NOT IMPLEMENTED

email_ux.png

https://excalidraw.com/#json=C0CN8Y7hKXYiGVP5DxQ9H,DBDvSqegjmSIMgvikCRtqA

Testing

On Staging and Isolated environments HOLIBOB, SUPPLIER, CHANNEL and FINANCE type emails are sent to test-email-flow@holibob.tech shared email.

To add the shared email to your Outlook: File -> Open -> Shared Mailbox... -> Search for "Test Email Flow" -> select test-email-flow@holibob.tech

Notes

  1. AGENT and CONSUMER emails are always sent to the actual addresses of the consumer and agent who created the booking.

  2. some states and configurations prevent to send an email (e.g. availability confirmation email is sent only for INTERNAL)

  3. you can always check the recipients and reasons why certain emails are not sent in System Log in Extranet (HUB - Holibob administration). You can search by Booking ID (for Booking Emails) or by Booking Availability ID (for Booking Availability Emails)

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.