Web SDK Setup
Introduction
The tracking JS script for Signal is a script that needs to be added to your page to be able to track events and communicate with the Signals SDK.
SDK Setup
To be able to use the SDK an authorization key is required. This key is created in the Marigold Moments application and should be provided in the SDK using the following methods.
Signals.setApiKey("<NEW_AUTH_KEY>");
// API key, passing via headers, main element of auth
Note: When no authorization key provided, an error is returned indicating no key has been set.
Inject the script in your pages
To use the Signals tracking script, you need to add this script to your pages; wherever tracking is required. There are 2 ways to do this: HTML and JavaScript.
HTML
<script defer src="https://mmx-eu-signals-js.s3.eu-west-1.amazonaws.com/eu/public/index.js" ></script>
<script defer src="<https://mmx-us-signals-js.s3.us-east-1.amazonaws.com/us/public/index.js>" ></script>
<script defer src="<https://mmx-jp-signals-js.s3.ap-northeast-1.amazonaws.com/jp/public/index.js>" ></script>
Javascript
var s = document.createElement('script');
var sp = document.getElementsByTagName('script')[0];
s.src = 'https://mmx-eu-signals-js.s3.eu-west-1.amazonaws.com/eu/public/index.js';
s.type = 'text/javascript';
s.defer = true;
sp.parentNode.insertBefore(s, sp);
var s = document.createElement('script');
var sp = document.getElementsByTagName('script')[0];
s.src = 'https://mmx-us-signals-js.s3.us-east-1.amazonaws.com/us/public/index.js';
s.type = 'text/javascript';
s.defer = true;
sp.parentNode.insertBefore(s, sp);
var s = document.createElement('script');
var sp = document.getElementsByTagName('script')[0];
s.src = 'https://mmx-jp-signals-js.s3.ap-northeast-1.amazonaws.com/jp/public/index.js';
s.type = 'text/javascript';
s.defer = true;
sp.parentNode.insertBefore(s, sp);
where the source is unique and specific for your account. You will have it as soon as you purchased Signals functionality.
The above script will allow the website to communicate with the Signals SDK. This SDK is installed by Marigold on the production server.
After you injected the script, you can use Signals SDK in order to track events.
Profile Identification Setup - SignIn/SignOut
There are 2 ways to be identified: by email or by external identifier. When sending the payload, you need to specify the type of identification that will be used by setting a value for the idType.
idType can be set to email or external. Depending on the value set for this field, either the email is required or the customerId.
The following events or signals are supported:
Supported payload
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | ||
| Field | Type | Description |
|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. Only for the SignIn signal. |
| String | The user's email. This field is required if idType is set to email. Only for the SignIn signal. | |
| customerId | String | The user's external customer id. This field is required if idType is set to external. Only for the SignIn signal. |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| profileAttributes | Object | User's custom attributes. | |
| eventAttributes | Object | Event's custom attributes. | |
| categories | string | Event's categories | |
Sign in
await Signals.signIn({
email: 'user@email.com',
});
//Which implies the idType is set to email by default
await Signals.signIn({
idType: 'email',
email: 'user@email.com',
});
//The idType is set explicitly to email
await Signals.signIn({
idType: 'external',
customerId: '1',
});
//The idType is set explicitly to external
Sign out
Note: The SDK does support anonymous users but it is recommended to provide the email or external id for user identification.
Supported signals for the Abandon Moments
At this point Marigold Moments support the following use cases:
Abandoned Cart
An abandoned cart occurs when a visitor of the webpage has added items to their cart and leaves the cart unattended for a certain amount of time. When the user clears the cart, removes items from the cart or purchases the items, no abandoned cart is triggered.
To support the Abandoned cart use case the following events are provided. All of these events are advised to track an abandoned cart moment and trigger the corresponding moment. Not tracking all events will impact your abandon cart moment:
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | Unique email identifier of the consumer. This field is required if idType is set to email. | ||
| cartId | Decimal | Unique identifier of the cart. | |
| items[] | Object | List of items. (These are optional for clear cart and purchase cart events!) | |
| sku | String | Unique identifier of the product. | |
| quantity | Decimal | Number of items for that product code in the cart. | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| items | array of objects | List of items | |
| type | String (25) | Type of item | |
| category | String (100) | Main category of the item | |
| subcategory | String (100) | Sub category of the item | |
| name | String (255) | Name of the item | |
| description | String (1024) | Description of what the item is | |
| upc | String (50) | Universal item code | |
| baseprice | Decimal | Price before discount | |
| discount | Decimal | Discount applied to the item | |
| discountType | String (50) | Discount per item or not | |
| netprice | Decimal | Total price for all items after discount | |
| itemAttributes | object | Flexible mechanism to store custom attributes related to the event, for example the imageURL | |
| profileAttributes | object | User's custom attributes | |
| eventAttributes | object | Event's custom attributes | |
| transactionId | string | The ID of the transaction. Only applicable to the purchase event | |
| transactionSource | string | The source of the transaction. Only applicable to the purchase event | |
| categories | string | Event's categories | |
| currency | string | Cart's currency, intended for `purchaseCart` event | |
| total | number | Cart's total, intended for `purchaseCart` event | |
Note:
- Data that exceeds the maximum limit will be trimmed by the SDK to the maximum length.
- Invalid decimals will be cleared by the SDK.
- The size of each items object should not exceed 4kb. If it does, a validation error is returned.
Track the add to cart event
await Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
or
await Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'external',
customerId: '17',
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
},
]
});
or following extended version, with optional parameters:
await Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email'
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
},
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
baseprice: 10.99,
netprice: 9.99,
discount: 1.99,
discountType: 'fixed',
name: 'Silmarillion',
type: 'book',
category: 'books',
subcategory: 'fantasy',
description: 'Tiny preface for The Lord of the Rings',
upc: '1234567890',
itemAttributes: {
imageUrl: 'http://www.meetmarigold.com',
}
},
]
});
Following is an example where the ItemAttributes are also provided. Only string values are accepted for the ItemAttributes, else a validation error is returned.
await Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
itemAttributes: {
imageUrl: 'https://shorturl.at/IjCZS',
anyAttribute0: 'anyValue0',
anyAttribute1: 'anyValue1',
}
},
]
});
Note: You can pass any custom attributes in the itemAttributes field. Note however that only string values are allowed.
Note 2: There is a validation for the size of each `items` object. It should not exceed 4kb in its serialized form. If it does, a validation error will be thrown.
Verify the result of the sent event
You can verify the result of the sent event in the following way:
const { success, error } = await Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
if (success) {
// nothing to add - event was sent successfully
} else {
// the event was not sent or didn't pass API validation for some reason
const { code, message, details } = error;
console.error(message);
// if you are interested in such errors. Can be done for you by `enableLogsToConsole: true`
}
Note: If disableValidations: true is set in the SDK configuration, you will not receive any errors in case the event sending fails and you will always receives `{ success: true }`.
Technical note:
You are not required to log errors to console in your code. The SDK can do this by enableLogsToConsole: true (by default true unless you disabled it).
In case you are not interested in the result of the event sending or wait while the method performs, you can use SDK in a fire-and-forget manner:
Signals.addToCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
Note: In this case it is recommended to turn off validations by setting disableValidations: true since you don't handle them.
Track the remove from cart event
await Signals.removeFromCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
},
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
},
]
});
Track the clear cart event
await Signals.clearCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: []
});
Track the purchase cart event
await Signals.purchaseCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
transactionId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
transactionSource: 'web',
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
},
]
});
Track the replace cart event
await Signals.replaceCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
}
]
});
Cart dependent events
If you don't have a cartId yet (which is a crucial field for these signals), you can and should send events without it. Signals SDK will handle this by stacking it and awaiting for the cartId to be sent later via the special method called setCartId(cartId: string). Once cartId is set, the SDK automatically sends all stacked events with the same cartId value. Even if you forget to call this method but one of the further eCommerce signals are called together with cartId, the SDK will automatically send all stacked events with the same cartId value. After all the signals with set cartId are sent, the SDK behaves as before and starts collecting events without a cartId again.
Following is an example of how to use it:
await Signals.addToCart({
idType:'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
await Signals.removeFromCart({
idType:'email',
email: 'user@email.com',
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
},
]
});
await Signals.setCartId('5ac97f5d-c360-4958-b753-eae88dc5d6f8');
Same effect can be achieved in the following way:
await Signals.addToCart({
idType:'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
await Signals.removeFromCart({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType:'email',
email: 'user@email.com',
items: [
{
sku: 'BOK-ABC123',
quantity: 1,
},
]
});
Abandoned Survey
An abandoned survey occurs when the website visitor starts filling out the survey but does not complete it.
The following events or signals are supported:
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | ||
| Field | Type | Description |
|---|---|---|
| objectId | String | The survey's id. |
| objectName | String | The survey's name. |
| idType | String | The user's id type used for identification. The value can be email or external. |
| customerId | String | The user's unique external id. This field is required if idType is set to external. |
| String | The user's email. This field is required if idType is set to email. | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| profileAttributes | Object | The user's custom attributes. | |
| event Attributes | Object | The event custom attributes. | |
| categories | string | Event's categories | |
| items | Object | ||
| id | string | The item's id. Mandatory if you decide to use the item object. | |
| name | string | The item's name. Mandatory if you decide to use the item object. | |
| type | string | The item's type. | |
| category | string | The item's category. | |
| subcategory | string | The item's subcategory. | |
| itemAttributes | object | The item's custom attributes. | |
Start Survey
await Signals.startSurvey({
idType: 'email',
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
},
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Survey 1',
});
Complete Survey
await Signals.completeSurvey({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Survey 1',
});
Update Survey
await Signals.updateSurvey({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Survey 1',
items: [
{
id: "it-1",
name: "Item 1",
type: "other",
}
]
});
Abandoned Booking
An abandoned booking occurs when the website visitor has started a booking but does not complete it within a given time frame.
The following events or signals are supported:
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | ||
| Field | Type | Description |
|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. |
| customerId | String | The user's unique external id. This field is required if idType is set to external. |
| String | The user's email. This field is required if idType is set to email. | |
| objectId | String | The Id of the booking. |
| objectName | String | The name of the booking. |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| categories | string | Event's categories | |
| items | Object | ||
| id | string | The item's id. Mandatory if you decide to use the item object. | |
| name | string | The item's name. Mandatory if you decide to use the item object. | |
| type | string | The item's type. | |
| category | string | The item's category. | |
| subcategory | string | The item's subcategory. | |
| itemAttributes | object | The item's custom attributes. | |
Start booking
await Signals.startBooking({
idType: 'email',
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
},
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Booking 1',
});
Complete booking
await Signals.completeBooking({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Booking 1',
});
Update booking
await Signals.updateBooking({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Booking 1',
items: [
{
id: "rm-1",
name: "Room 1"
category: "standard",
subcategory: "double",
}
];
});
Abandoned Game
An abandoned game occurs when a visitor of the webpage starts a game but does not complete it within a given time frame.
The following events or signals are supported:
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | ||
| Field | Type | Description |
|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. |
| customerId | String | The user's unique external id. This field is required if idType is set to external. |
| String | The user's email. This field is required if idType is set to email. | |
| objectId | String | The Id of the game. |
| objectName | String |
The name of the game. |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| categories | string | Event's categories | |
| items | Object | ||
| id | string | The item's id. Mandatory if you decide to use the item object. | |
| name | string | The item's name. Mandatory if you decide to use the item object. | |
| type | string | The item's type. | |
| category | string | The item's category. | |
| subcategory | string | The item's subcategory. | |
| itemAttributes | object | The item's custom attributes. | |
Start game
await Signals.startGame({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Game 1',
});
End game
await Signals.endGame({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Game 1',
});
Update game
await Signals.updateGame({
idType: 'email',
email: 'user@email.com',
objectId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
objectName: 'Game 1',
items: [
{
id: "dc-2",
name: "Disciples II: The Ries of the Elves",
category: "strategy",
subcategory: "expansion",
}
]
});
Abandoned Browse
An abandoned browse occurs when a potential customer visits the webpage, browses through the categories, products and services but leaves without making a purchase or taking any desired action.
The following events or signals are supported for the browse event:
- product visit (product browse)
- category and sub-category browse
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: In the following table, sections refer mostly to categories and sub-categories. Elements refers to products and their data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | |||
| Field | Attribute | Type | Description |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | The user's email. This field is required if idType is set to email. | ||
| sections | Array of strings | List of sections of browsing, for example sections: [[ "men", "clothes", "sport" ]] | |
| elements | Object | List of elements of the browse. Only for product browse signal. | |
| type | String | The element's type. | |
| id | String | The element's id. | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| elements | Object | List of elements of the browse. | |
| name | String | The element's name. | |
| description | String | The element's description. | |
| elementAttributes | Object | The element's custom attributes: any string values. | |
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| categories | string | Event's categories | |
Sub category page visit
await Signals.browse({
idType: 'email',
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
},
sections: [[ "men", "clothes", "sport" ]],
});
Top category page visit
await Signals.browse({
idType: 'external',
customerId: '17',
sections: [[ "jewelry" ]],
});
Product page visit
await Signals.browse({
idType: 'email',
email: 'user@email.com',
sections: [[ "men", "clothes", "sport" ]],
elements: [{
type: "product",
id: 'UA-1991',
name: 'T-shirt',
description: 'Nice t-shirt',
elementAttributes: {
imageUrl: 'https://shorturl.at/IjCZS',
}
}]
});
Note 1: You can pass on custom attributes to the ElementAttributes field. Only string values are allowed, else a validation error will be thrown.
Note 2: There is a validation for the size of each elementAttributes object. It should not exceed 4kb in its serialized form. If it does, a validation error will be thrown.
Note 3: Hierarchical categories/sub-categories are passed on from left to right, like a breadcrumb.
await Signals.browse({
idType: 'email',
email: 'user@email.com',
sections: [[ "men", "clothes", "sport" ]],
elements: [{
type: "product",
id: 'UA-1991',
name: 'T-shirt',
description: 'Nice t-shirt',
elementAttributes: {
imageUrl: 'https://shorturl.at/IjCZS',
anyAttribute0: 'anyValue0',
anyAttribute1: 'anyValue1',
}
}]
});
Abandoned Configuration
An abandoned configuration occurs when a potential customer visits the webpage, starts configuring an insurance, a car, a holiday, but leaves without completing the configuration.
The following events or signals are supported for the browse event:
Supported payload
When sending out messages as a result of a Moment, the marketer should be able to personalize these messages with information from the event that leads to the Moment.
In addition to the mandatory fields that need to be sent through, a series of optional fields can be added to the data.
Note: The supported payload attributes are case sensitive and need to be passed on in Camelcase. If this formatting is not respected, these attributes will not be validated .
| MANDATORY FIELDS | |||
| Field | Attribute | Type | Description |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | The user's email. This field is required if idType is set to email. | ||
| objectId | string. | Id of the configuration | |
| objectName |
string |
Name of the configuration | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| items | Object | List of items elements in the configuration. | |
| id | String | The item's ID. This is mandatory when using the item object | |
| name | String | The item's name. This is mandatory when using the item object. | |
| type | String | The item's type. This is optional in the object | |
| category | String | The item's category. This is optional in the object. | |
| subcategory | String | The item's subcategory. This is optional in the object | |
| itemAttributes | object | Item's custom attributes: any string values | |
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| categories | string | Event's categories | |
startConfig
await Signals.startConfig({
idType: 'email',
email: 'user@email.com',
objectId: 'M-AMG5632',
objectName: 'Mercedes E-class AMG config',
profileAttributes: {
profileFirstName: "John",
profileLastName: "Doe",
},
eventAttributes: {
ip: "ip address",
location: "the location",
},
items: [
{
type: "item/service",
id: "M-AMG5632",
name: "Mercedes E-class AMG config"
}
]
});
completeConfig
await Signals.completeConfig({
idType: 'email',
email: 'user@email.com',
objectId: 'M-AMG5632',
objectName: 'Mercedes E-class AMG config',
});
updateConfig
await Signals.updateConfig({
idType: 'email',
email: 'user@email.com',
objectId: 'M-AMG5632',
objectName: 'Mercedes E-class AMG config',
items: [
{
id: "M-AMG5632",
name: "Mercedes E-class AMG config",
category: "coupe",
subcategory: "AMG",
}
]
});
Supported signals for the Welcome Moment
An Signup occurs when a visitor signs up for your website, newsletter, event, webinar, program or game.
The following events or signals are supported for the Signup event:
Supported payload
| MANDATORY FIELDS | |||
| Field | Attribute | Type | Description |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | The user's email. This field is required if idType is set to email. | ||
| objectType | String | enum:[newsletter,webinar,event,site,program,game] | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| objectId | String | ||
| category | string | Event's categories | |
signUp
await Signals.signUp({
idType: 'email',
email: 'user@email.com',
objectType: 'newsletter',
});
Supported signals for the Goodbye Moment
A Goodbye occurs when a visitor unsubscribes from your website, newsletter, event, webinar, program or game.
The following events or signals are supported for the Goodbye event:
Supported payload
| MANDATORY FIELDS | |||
| Field | Attribute | Type | Description |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | The user's email. This field is required if idType is set to email. | ||
| objectType | String | enum:[newsletter,webinar,event,site,program,game] | |
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| objectId | String | ||
| category | string | Event's categories | |
cancel
await Signals.cancel({
idType: 'email',
email: 'user@email.com',
objectType: 'event',
objectId: 'reconnect-2020',
eventAttributes: {
country: 'Ireland',
}
});
Supported Service Ecommerce Signals
The Service Ecommerce signals cover use cases where reviews are recorded on a product item or service.
The following events are supported:
Supported payload
| MANDATORY FIELDS | |||
| Field | Attribute | Type | Description |
|---|---|---|---|
| idType | String | The user's id type used for identification. The value can be email or external. | |
| customerId | String | The user's unique external id. This field is required if idType is set to external. | |
| String | The user's email. This field is required if idType is set to email. | ||
| OPTIONAL FIELDS | |||
| Field | Type | Description | |
|---|---|---|---|
| profileAttributes | Object | The user's custom attributes. | |
| eventAttributes | Object | The event custom attributes. | |
| category | string | Event's categories | |
| items | Object | List of items in the review | |
| sku | String | The item's SKU | |
| quantity | Decimal | The number of items | |
| type | String (25) | Type of item | |
| category | String (100) | Main category of the item | |
| subcategory | String (100) | Sub category of the item | |
| name | String (255) | Name of the item. This field is required. | |
| description | String (1024) | Description of what the item is | |
| upc | String (50) | Universal item code | |
| baseprice | Decimal | Price before discount | |
| discount | Decimal | Discount applied to the item | |
| discountType | String (50) | Discount per item or not | |
| netprice | Decimal | The item's net price | |
| url | String | a valid URL for the item | |
| imageUrl | String | A valid URL for the image | |
| itemAttributes | Object | The item's custom attributes | |
reviewItem
await Signals.reviewItem({
idType: 'external',
customerId: '17',
items: [
{
name: 'item 1 name'
},
]
});
reviewCustomerService
await Signals.reviewCustomerService({
idType: 'external',
customerId: '17',
items: [
{
name: 'cs-review-1',
description: "some description",
},
]
});
Profile and Event attributes
For each sending event, there is an option to send additional data via custom fields, like profileAge or deviceType. You can place them under profileAttributes or eventAttributes. These fields are optional and can be omitted.
profileAttributes?: object;
// known profile attributes:
profileFirstName?: string;
profileLastName?: string;
profileTimezone?: string;
profileTier?: string;
profileTotalPoints?: number;
profileAge?: number;
profileAgeBand?: string;
profileCountry?: string;
profileCity?: string;
profileState?: string;
profilePostalCode?: string;
profileCohort?: string;
profileGender?: string;
profileProvider?: string;
profileOptinSms?: boolean;
profileOptinMail?: boolean;
profileOptinPush?: boolean;
profileJoinDate?: string;
profileStatus?: string;
profileJoinSource?: string;
eventAttributes?: object;
// known event attributes:
channel?: string;
ip?: string;
userAgent?: string;
deviceType?: string;
country?: string;
region?: string;
state?: string;
postalCode?: string;
city?: string;
await Signals.addToCart({
idType: 'email',
email: 'user@email.com',
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
profileAge: 32,
profileGender: 'male'
orAnythingCompletelyCustomButStringValueOnly: 'value'
},
eventAttributes: {
deviceType: 'mobile'
},
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
items: [
{
sku: 'TOY-XYZ'
quantity: 1
}
]
});
Use the SDK synchronously
Using the SDK synchronously will block the main thread of the current page and is not recommended.
If you must use the SDK in this way, follow this example:
Signals.addToCartSync({
cartId: '5ac97f5d-c360-4958-b753-eae88dc5d6f8',
idType: 'email',
email: 'user@email.com',
items: [
{
sku: 'TOY-XYZ789',
quantity: 1,
},
{
sku: 'BOK-ABC123',
quantity: 3,
},
]
});
Each existing event method has a copy with the Sync suffix in the Node.js style. Consider using the fire-and-forget method in such a use case.
User Identification
The user gets identified by a single field: email. This field should always be filled out, but it is possible to send events without it.
It is recommended to integrate and send SignIn & SignOut events properly however if such are missed, SDK will handle it for you by sending auth events with 'email' automatically, as well as SDK may detect a change of 'email' during the session and perform SignOut and SignIn events automatically.
The user remains identified until the tab is opened.
Tech note: In case of session-long user identification, the SDK utilizes sessionStorage so an access to it is required. Usually this feature is enabled by default in modern browsers. If it is not, the SDK requests such permissions in the browser on its very first run.
if (!(await window.document.hasStorageAccess())) {
await window.document.requestStorageAccess();
}
Anonymous users
While anonymous user data collection is not currently supported, you should still send all events, even if you do not have
You might have noticed in the above DTOs email: string; - that the userId field is not required.
However, in order to retrieve the desired functionality from Moments, it is recommended to send it if you know your user.
If you have an anonymous user you should still send all events as well as sending user events with email afterwards. This is valid scenario either and will be handled by Moments.
SDK Tweaking
You can configure the Signals SDK to comply with your needs / preferences: from an update auth key up to setting how to handle/log errors.
In case you need to update you API host or Auth key, you can do it like this:
typescript
Signals.setAuthKey("<NEW_AUTH_KEY>"); // API key, passing via headers, main element of auth
Signals.setApiHost("<NEW_API_HOST>"); // API host, BE API publicly available URI, it must starts with https://
Signals.setHostname("<NEW_HOSTNAME>"); // the current site hostname where SDK is working
Signals.setProfileIdQueryParamKey("<NEW_PROFILE_ID_QUERY_PARAM_KEY>"); // the key of the query param which contains [TEMP not working]
The following options are available for change during runtime:
typescript
Signals.setOptions({
disableValidations?: boolean; // do not perform any validations, no reaction on errors. Not recommended. By default false
clientValidationEnabled?: boolean; // do client validations and return an error obj. By default true
serverValidationEnabled?: boolean; // gather server validation errors (when status isn't 2XX) and return them. By default true
enableLogsToConsole?: boolean; // log to console if errors happen (client or server) in tracking scripts. By default true
performSignInAlways?: boolean; // perform SignIn event always when email is provided, even when SessionStorage holds the same value. By default false
});
where LogLevelEnum is one of the following: `debug`, `info`, `warn`, `error`, `silent`
GTM methods
SDK provides the same set of methods for GTM (Google Tag Manager) usage. The only difference is that GTM methods are sort-of-synchronous and success always. In fact, the code is not synchronous, meaning it does not block Event Loop, but the result is always successful and no errors are thrown considering the server. Eventually it implies that GTM methods do not support `serverValidationEnabled` feature, the client validation is in tact. The GTM methods' signature is the same as for Signals methods.
It's recommended not to use GTM methods over async methods which return promises, unless it's necessary.
typescript
Signals.browseGTM({
idType: 'email',
email: 'user@email.com',
sections: [["drinks", "alcohol"]],
})
Context
SDK offers context fields support such as profileAttributes.Any profileAttributes field can be set.
You can set context fields once and they will be sent with each event until the context gets cleared by signOut() or explictly by clearContext().
Example
Signals.setContext({
profileAttributes: {
profileFirstName: 'John',
profileLastName: 'Doe',
profileAge: 32,
}
});
It results into the following automatic post-merging of these fields and their values into each subsequent event. Keep in mind that Event fields have a higher priority than Context fields. If the same field is present in both, the Event field will be sent. Also, if you want to "cancel" any of fields - set its value to null like this:
Signals.setContext({
profileAttributes: {
profileAge: null,
}
});
Each subequently invocation of Signals.setContext() does accumulate the fields, not replace them. If you want to reset the context fields - use special method Signals.clearContext().
Signals.clearContext();
URL Parsing
Signals SDK can parse URL query parameters and send them via special header called `X-Marketing-ID`. This feature is disabled by default and can be enabled by setting names of query params needed to be parsed.
Signals.setMarketingIdQueryParamName('proxy_id');
Signals.setTrackingParamQueryParamName('tracking_id');
