Szymon Lewandowski website logo
Published on

How to send event with catalog metadata in Marketing Cloud Personalization

Authors
  • avatar
    Name
    Szymon Lewandowski
    Twitter

Marketing Cloud Personalization - how to send event with catalog metadata

Sending events with catalog metadata in Interaction Studio (a.k.a. MCP) can be pretty annoying. You have to perfectly match the event structure, remember about specific Evergage or SalesforceInteractions namespace details and you won't be able to do easy debugging. That's why I wrote this article - with information about catalogObject attributes, event structure, working sendEvent examples and tips to check and troubleshoot your work.

Table of Contents

  1. Catalog Metadata in MCP
  2. Sending event - Evergage namespace
  3. Sending event - SalesforceInteractions namespace
  4. How to check if data was sent properly
  5. Troubleshooting

Catalog metadata in Marketing Cloud Personalization

First, we should get to know how the catalog metadata looks in the Marketing Cloud Personalization. There are many parameters that we could add to the event's structure. There are also different sets of possible attributes to each of the pre-built catalogObject.

Product catalogObject attributes table
ParameterTypeDescription
<attributes>ObjectAdding Product attributes (⚠ SalesforceInteractions only)
_id / idstringAdding Product ID attribute (_id in Evergage, id in SalesforceInteractions)
namestringAdding Product name attribute (could be different than id)
descriptionstringAdding Product description attribute
urlstringAdding Product url attribute
imageUrlstringAdding Product image url attribute
inventoryCountstringAdding Product inventoryCount attribute (eg. 5 pieces of item on stock)
pricedoubleAdding Product price attribute (seperated with dot .)
currencystringAdding Product price attribute (ISO 4217 standard)
ratingintAdding Product rating attribute (eg. adding user rating from review)
skustringAdding Product sku with _id parameter attribute (alternative product ID)
locationObjectAdding Product location parameters
citystringAdding Product location city attribute
statestringAdding Product location state attribute
postalCodestringAdding Product location postal code attribute
countryNumericCodestringAdding Product location country numeric code attribute
stateProvinceCodestringAdding Product location state attribute
longlatArrayAdding Product location longitude and latitude ( as array of decimals, e.g. [00.0000000.00.000000])
attributesObjectAdding Product custom attributes
categoriesObjectAdding Product categories values (available multiple parameters)
relatedCatalogObjectsObjectAdding Product relatedCatalogObjects (remember to push it as arrays)

Category catalogObject attributes table
ParameterTypeDescription
_id / idstringAdding Category ID (_id in Evergage, id in SalesforceInteractions)
namestringAdding Category name attribute (could be different than id)
urlstringAdding Category url attribute
imageUrlstringAdding Category image url attribute
descriptionstringAdding Category description attribute
isDepartmentbooleanChecking if Category is department (useful when we have different departments)
ratingintAdding Category rating attribute (eg. adding user rating from review)
locationObjectAdding Category location parameters
citystringAdding Category location city attribute
statestringAdding Category location state attribute
postalCodestringAdding Category location postal code attribute
countryNumericCodestringAdding Category location country numeric code attribute
stateProvinceCodestringAdding Category location state attribute
longlatArrayAdding Category location longitude and latitude ( as array of decimals, e.g. [00.0000000.00.000000])
attributesObjectAdding Category custom attributes
relatedCatalogObjectsObjectAdding Category relatedCatalogObjects (remember to push it as arrays)

Blog Post catalogObject attributes table
ParameterTypeDescription
_id / idstringAdding Blog Post ID (_id in Evergage, id in SalesforceInteractions)
namestringAdding Blog Post name attribute (could be different than id)
urlstringAdding Blog Post url attribute
imageUrlstringAdding Blog Post image url attribute
descriptionstringAdding Blog Post description attribute
ratingintAdding Blog Post rating attribute (eg. adding user rating from review)
locationObjectAdding Blog Post location parameters
citystringAdding Blog Post location city attribute
statestringAdding Blog Post location state attribute
postalCodestringAdding Blog Post location postal code attribute
countryNumericCodestringAdding Blog Post location country numeric code attribute
stateProvinceCodestringAdding Blog Post location state attribute
longlatArrayAdding Blog Post location longitude and latitude ( as array of decimals, e.g. [00.0000000.00.000000])
attributesObjectAdding Blog Post custom attributes
relatedCatalogObjectsObjectAdding Blog Post relatedCatalogObjects (remember to push it as arrays)

Article catalogObject attributes table
ParameterTypeDescription
_id / idstringAdding Article ID (_id in Evergage, id in SalesforceInteractions)
namestringAdding Article name attribute (could be different than id)
urlstringAdding Article url attribute
imageUrlstringAdding Article image url attribute
descriptionstringAdding Article description attribute
ratingintAdding Article rating attribute (eg. adding user rating from review)
locationObjectAdding Article location parameters
citystringAdding Article location city attribute
statestringAdding Article location state attribute
postalCodestringAdding Article location postal code attribute
countryNumericCodestringAdding Article location country numeric code attribute
stateProvinceCodestringAdding Article location state attribute
longlatArrayAdding Article location longitude and latitude ( as array of decimals, e.g. [00.0000000.00.000000])
attributesObjectAdding Article custom attributes
relatedCatalogObjectsObjectAdding Article relatedCatalogObjects (remember to push it as arrays)

Promotion catalogObject attributes table
ParameterTypeDescription
namestringAdding Promotion name attribute (could be different than id)
urlstringAdding Promotion url attribute
imageUrlstringAdding Promotion image url attribute
descriptionstringAdding Promotion description attribute
startDateDateTimeAdding Promotion start date
endDateDateTimeAdding Promotion end date
attributesObjectAdding Promotion custom attributes
relatedCatalogObjectsObjectAdding Promotion relatedCatalogObjects (remember to push it as arrays)

Custom catalogObject attributes table
ParameterTypeDescription
_id / idstringAdding Custom catalogObject ID (_id in Evergage, id in SalesforceInteractions)
namestringAdding Custom catalogObject name attribute (could be different than id)
urlstringAdding Custom catalogObject url attribute
imageUrlstringAdding Custom catalogObject image url attribute
descriptionstringAdding Custom catalogObject description attribute
ratingintAdding Custom catalogObject rating attribute (eg. adding user rating from review)
locationObjectAdding Custom catalogObject location parameters
citystringAdding Custom catalogObject location city attribute
statestringAdding Custom catalogObject location state attribute
postalCodestringAdding Custom catalogObject location postal code attribute
countryNumericCodestringAdding Custom catalogObject location country numeric code attribute
stateProvinceCodestringAdding Custom catalogObject location state attribute
longlatArrayAdding Custom catalogObject location longitude and latitude ( as array of decimals, e.g. [00.0000000.00.000000])
attributesObjectAdding Custom catalogObject custom attributes
relatedCatalogObjectsObjectAdding Custom catalogObject relatedCatalogObjects (remember to push it as arrays)

Sending event with catalog metadata - Evergage namespace

In theory, sending events with catalog metadata is quite easy. All you need to do is to add the catalog metadata to your sendEvent payload (or pageType payload). But... in practice this task could be tough when you are working on more complicated cases. Sending events is also not so easy to debug, as the Interaction Studio will not send any errors regarding the catalog metadata.

What's more, we have two different namespaces used across MCP - Evergage and SalesforceInteractions. They have several differences between objects architecture, so let's split these two. First, let's look at the Evergage structure and then build an example event.

Evergage event structure

Let's see the event with full available catalog metadata. Remember that you have to send data to the catalogObject object in the catalog object payload. Note also that relatedCatalogObjects objects are also placed inside the catalogObject1:

evergage_event_catalog_structure
Evergage.sendEvent({
    action: "Action name",
    itemAction: itemActionSpecificName,
    catalog: {
        catalogObject1 : {
            _id: "catalogObject1 ID value",
            name: "catalogObject1 name value",
            description: "catalogObject1 description value",
            url: "catalogObject1 url value",
            imageUrl: "catalogObject1 image url value",
            inventoryCount: catalogObject1InventoryCountValue,
            price: catalogObject1PriceValue,
            currency: "catalogObject1 currency value"
            rating: catalogObject1RatingValue,

            // sku object - adds alternative id
            sku: {
                _id: "catalogObject1 SKU ID value"
            }

            // location object - adds location to the product
            location: {
                city: "catalogObject1 city value",
                postalCode: "catalogObject1 postalCode value",
                countryNumericCode: "catalogObject1 country numeric code value",
                stateProvinceCode: "catalogObject1 state province code value",
                longlat: [catalogObjectLongtitudeValue.catalogObjectLatitudeValue],
            },

            // categories object - adds related categories to the product
            categories: {
                Category1: "catalogObject1 Category1 value",
                Category2: "catalogObject1 Category2 value"
            },

            // relatedCatalogObjects object - adds related catalog objects to the product
            relatedCatalogObjects: {
                relatedCatalogObject1: ["relatedCatalogObject1 value"],
                relatedCatalogObject2: ["relatedCatalogObject2 value"],
            }
        }
    }
});

Here you can see, that we can build catalog payload with multiple catalogObjects, it could be useful if we want to send information about several catalogObjects that are not related with each another, so for example we can send event that user viewed blog article about specific product with information about Article catalogObject and Product catalogObject.

Evergage event example

Now, let's build the example event, that uses the catalog metadata. I want to add the event that shows that user viewed a specific product called Apple iPhone 15 128GB Black, I want to add the specific ID of this product, add description, price, currency and stock. I also know what categories are appropriate and want to add relatedCatalogObjects values. Here we use the Evergage.ItemAction.ViewItem itemAction that allows us to count perform Product view event.

evergage_event_catalog_example
Evergage.sendEvent({
    action: "Action name",
    itemAction: Evergage.ItemAction.ViewItem,
    catalog: {
        Product : {
            _id: "100123",
            name: "Apple iPhone 15 128GB Black",
            description: "Check out this cool new iPhone!",
            price: 4699.99,
            currency: "PLN",
            categories: ["Smartphones","Smartwatches"],
            },
            relatedCatalogObjects: {
                RAMMemory: ["6"],
                ROMMemory: ["128"],
                OperatingSystem: ["iOS"],
            },
        },
    });

Want to know how to send the event without sitemap? Check How to send additional events in Marketing Cloud Personalization

Sending event with catalog metadata - SalesforceInteractions namespace

SalesforceInteractions is currently recommended namespace in the Marketing Cloud Personalization. It is necessary especially if you use Salesforce Data Cloud in your solution. Namespace seems to be organized a bit differently, but for me it has some disadvantages, like two attributes parameters with same name (one for built-in attributes and second for custom attributes) and no possibility to pass additional action name with the event (beacause we use only name attribute instead of splitted action and itemAction attributes).

SalesforceInteractions event structure

The whole structure is also different. We build it in the additional interaction nested object, also all bult-in attributes are in the attributes nested object and all custom attributes are outside of the catalogObject object. Remember to use id instead of _id attribute.

salesforceinteractions_event_catalog_structure
SalesforceInteractions.sendEvent({
    interaction: {
        name: interactionSpecificName,
        catalogObject: {
            type: "catalogObject1"
            id: "catalogObject1 ID value"
            attributes: {
                name: "catalogObject1 name value",
                description: "catalogObject1 description value",
                url: "catalogObject1 url value",
                imageUrl: "catalogObject1 image url value",
                inventoryCount: catalogObject1InventoryCountValue,
                price: catalogObject1PriceValue,
                currency: "catalogObject1 currency value"
                rating: catalogObject1RatingValue,
                sku: {
                    id: "catalogObject1 SKU ID value"
                }
                location: {
                    city: "catalogObject1 city value",
                    postalCode: "catalogObject1 postalCode value",
                    countryNumericCode: "catalogObject1 country numeric code value",
                    stateProvinceCode: "catalogObject1 state province code value",
                    longlat: [catalogObjectLongtitudeValue.catalogObjectLatitudeValue],
                },
            },
            // categories object - adds related categories to the product
            categories: ["Smartphones","Smartwatches"],

            // relatedCatalogObjects object - adds related catalog objects to the product
            relatedCatalogObjects: {
                relatedCatalogObject1: ["relatedCatalogObject1 value"],
                relatedCatalogObject2: ["relatedCatalogObject2 value"],
            }
        }
    }
});

SalesforceInteractions event example

Here is the example event built in SalesforceInteractions namespace with the same structure (but different values 😉). Here we use the SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject Interaction that allows us to count perform Product view event.

salesforceinteractions_event_catalog_example
SalesforceInteractions.sendEvent({
    interaction: {
        name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
        catalogObject: {
            type: "Product",
            id: "100124",
            attributes: {
                name: "Samsung Galaxy S23 8/128GB",
                description: "Check out this cool new Samsung!",
                price: 3699.99,
                currency: "PLN",
            },
            categories: ["Smartphones","Smartwatches"],
            relatedCatalogObjects: {
                RAMMemory: ["8"],
                ROMMemory: ["128"],
                OperatingSystem: ["Android"],
            },
        }
    }
});

How to check if event data was sent properly

You can check the item object payload in the Event Stream. Go to Reports>Event Stream and find the event that have been sent by you. Then, look at the item section:

Event with catalog object item object payload

In the picture we can see that the event payload was sent properly. But we should wait up to 15 minutes for data population in the Marketing Cloud Personalization UI. Then we can move to the Catalog section and check if both events resulted in data addition.

Event sending troubleshooting

When you encounter issues with event sending, try some tips below. There are the most common problem fixes:

⚠ Catalog metadata in Event Stream present, but no data in the Catalog

Check if the structure is ok. Maybe you added some atteributes in different hierarchy level than they should be. With proper structure you should at least see catalogObject with id. Remember also about 15 minute delay with populating data.

⚠ Missing item attributes in the Catalog

Check if the structure and attributes names are ok. Also check if you disabled the Strict Catalog Security in Catalog setup.

⚠ Missing relatedCatalogObjects in the catalogObject

Check if the structure and attributes names are ok. Remember to send values as an Array[], e.g.

relatedCatalogObjects: {
    Category: ["Smartphones"],
    Brand: ["Apple"],
},

⚠ My event was blocked by CORS Policy

Check if the structure and attributes names are ok. You probably mixed namespace structures or objects hierarchy.