Before Abandonment recovery emails can be sent, there are a number of steps that need to be completed:
This article describes the implementation procedure and how to set up new campaigns. It is possible that not all steps here will be fully self-service for Qubit clients or partners.
Please do not hesitate to reach out to Customer Support at Qubit for assistance.
The following diagram shows the high-level technical stack for abandonment recovery:
This system is a real-time data pipeline for qualifying segments of visitors and passing their information to an ESP, which then triggers personalized emails off this data.
The pipeline has several key steps:
In this section, we will cover the data requirements for a generic abandonment recovery email.
It is important to consider any custom dynamic content requirements that fall outside this generic use case and confirm that it can all be obtained from the data points suggested below.
The following events and fields represent our recommended implementation of the Abandonment recovery experience in the retail vertical.
For details of the eGaming and travel variants of these events, refer to Setup For eGaming and Setup for Travel.
For a more complete description of these events, and more information about QProtocol, QP events, and setting up Qubit on your website or mobile app, see Getting Started with Qubit.
The four key steps of implementing Abandonment recovery emails are shown in the following diagram:
There are two parts to this step. Firstly, collecting your requirements for the campaign and secondly, setting up the ESP.
You should complete this step in collaboration with Qubit. The following questions should be considered:
To ensure nothing is missed, refer to our requirements template.
Having implemented these campaigns for a number of clients, Qubit may recommend certain best practices:
In collaboration between Qubit and the Email Service Provider (ESP) you must create the email templates that capture the information to show in Abandonment recovery emails and data tables to hold this information on an per-visitor basis.
The templates and tables will be posted by the Qubit cloud function via API.
Qubit requires the following from the ESP:
The ESP is responsible for processing the data received from Qubit and parsing it into email templates.
Qubit has built integrations for a number of ESPs. Refer to the following list:
Several others are in the process of being built.
This step is generally a one-off to set up credentials and check the connection between Qubit and the Email Service Provider (ESP). This may be hard to test, so please do not hesitate to get in touch for assistance.
Select Experiences from the side menu, select against the Abandonment recovery experience you wish to configure, and select Edit:
Select Edit this experience's Global Configuration settings and edit the following settings as required:
preventEmails
- if set to true, no posts will be made to the ESP. This can be used for pausingexpirySecs
- the cooling-off period in seconds after an email has been sent. During the cooling off period no further emails will be sent to the same recipient and campaign combinationspamEmailPattern
- the email address pattern which is exempt from expirySecs
cancelOnConversion
- whether to cancel the email if the user convertedesp
- the configuration for your ESP. Refer to the examples belowesps
- alternative to esp
when multiple ESP configurations are required. Refer to the examples belowesp
configuration examples:
Example 1:
{
"esp": {
"name": "experian",
"grant_type": "password",
"auth": {
username: "my username",
"password": "XXXXXXXXXXXXXXXXXXX",
"grant_type": "password",
"client_id": "84139"
},
"cust_id": "92118",
"tables": [
{
"name": "User Info",
"submissionSequence": "0",
"form_id": "1",
"fields": [
{
"key": "user.email",
value: "user.email"
}
]
}
]
}
}
Example 2:
{
"esp": {
"name": "communicator",
"auth": {
username: username,
"password": "password"
},
"tables": [{
id: 12421,
"operationType": "Upsert",
"columns": [{
"columnId": 193311,
value: "user.user_id"
}]
}]
}
}
esps configuration example:
{
"esps": {
"default": {
"name": "communicator",
"auth": {
username: username,
"password": "password"
},
"tables": [{
id: 12421,
"operationType": "Upsert",
"columns": [{
"columnId": 193311,
value: "user.user_id"
}]
}]
},
"browsingAbandonment": {
"name": "communicator",
"auth": {
username: username,
"password": "password"
},
"tables": [{
id: 8888999,
"operationType": "Upsert",
"columns": [{
"columnId": 88911,
value: "user.user_id"
}]
}]
}
}
}
The configuration may also contain information on how the visitor data matches to tables and columns in the ESP. An illustrative example of this is shown below:
An example configuration for a Mandrill connection is:
{
"preventEmails": false,
"expirySecs": 86400,
"cancelOnConversion": true,
"spamEmailPattern": "^.*@qubit.com$",
"esp": {
"api_key": "WFRNhHOftN4767B6oPOTXA"
}
}
In the experience, make sure to include the @qubit/messages
package for scheduling and canceling emails. When done, implement your experience based on the following template:
module.exports = function execution (options) {
const { uv } = options
const messages = require('@qubit/messages')(options)
function schedule (user, items) {
messages.schedule({
recipientId: user.email,
key: 'basket-abandonment-2h',
delay: '2h',
window: '09:00-21:00', // optional
data: { user, items } // see documentation for data the integration expects
})
}
function cancel (user) {
messages.cancel({
recipientId: user.email,
key: 'basket-abandonment-2h'
})
}
let user = null
let items = []
uv.on('ecUser', event => {
user = event.user
}).replay()
uv.on('ecBasketItem', (event) => {
items.push(event.product)
}).replay()
uv.on('ecBasketSummary', (event) => {
if (user && user.email && items.length) {
// we found a non empty basket, schedule an email
schedule(user, items)
} else {
// an empty basket, cancel the email
// in case one has been scheduled
cancel(user)
}
}).replay()
uv.on('ecBasketTransactionSummary', () => {
if (user && user.email) {
// transaction! cancel the email
// in case one has been scheduled
cancel(user.email)
}
}).replay()
}
For full details on the usage of @qubit/messages package see @qubit/messages package documentation.
This involves correctly qualifying visitors and sending relevant information through the data pipeline described above.
Once the above has been set up, both on the ESP side and the Qubit experience, the testing phase can commence.
In this phase, real end users will be qualified using the experience trigger and variation, but the emails that would be sent out to these end users get rerouted to a test mailing list such as esp-test-CLIENTNAME@qubit.com
. This can be done by overriding uv.user.email
in the variation code by adding something like universal_variable.user.email = 'esp-test-CLIENTNAME@qubit.com'
to the solutionOptions.transformData
function.
This mailing list will be set up by Qubit and used to review the emails that would have gone out to end users, to ensure that there are no rendering issues, and that the emails generated match the on-site activity correctly (e.g does abandonment cause an email in the right time frame, does checking out cancel the email, etc).
To drill down into the sequence of events that occur for a particular user, between abandonment and Qubit sending email data to the ESP, Live Tap can be used to query QProtocol events. See Reporting for more information.
Once the campaign has been signed off, alerting is set up on the Qubit side to flag:
Following the go-ahead, the campaign can go live to end users (using their uv.user.email
value).
Throughout this pipeline, QProtocol QMail
events are generated in the following scenarios:
By querying this event in Live Tap we can answer a number of pertinent questions, including:
The full event schema for QMail
is shown in the following table:
Field | Description | Type | Available In Browser | Example |
---|---|---|---|---|
eventName | The event status | string | Yes | scheduled |
integration | The name of the ESP integration | string | Yes | mandrill |
environment | The environment where the experience is running | string | Yes | production |
campaign | The campaign name | string | Yes | abandon-basket-1-hour-en_GB |
experienceId | The experience Id | Long | Yes | |
iterationId | The Id of experience iteration | Long | Yes | |
variationId | The Id of the experience variation | Long | Yes | |
variationMasterId | The Id of the experience control | Long | Yes | |
The visitor’s email address if available | String | john.smith@example.com | ||
expiryTime | Integer | Yes | ||
delayTime | The number of minutes between a visitor abandoning a site and a personalized email being sent | Integer | Yes | |
timeRange | The time range, in 24 hour clock format, in which emails are allowed to be scheduled | StringArray | Yes |