用于混合实施的 Einstein Activities

借助 报告 & 仪表板 ,您可以根据自己的 B2C Commerce 数据确定随时间变化的趋势并做出更明智的业务决策。

Reports & Dashboards 分析只能从 Web 适配器日志或 Einstein Activities API 派生。默认情况下,SFRA 和 SiteGenesis 分析数据存储在 Web 适配器日志中,而 PWA Kit 将分析数据发送到 Einstein Activities API。

如果您追求 的是混合实现 ,其中某些页面由 PWA Kit 提供支持,而其他页面由 SFRA 或 SiteGenesis 提供支持,并且您希望在整个站点中使用报告 & 仪表板,则必须更新 SFRA 或 SiteGenesis 实现以使用 Einstein Activities API。这可确保 API 捕获完整的购物者体验,无论购物者是在 PWA Kit、SFRA 还是 SiteGenesis 中。

只有现有客户才能访问此页面上的某些链接。请访问 Salesforce Commerce Cloud GitHub 存储库和访问权限,了解有关如何访问 Commerce Cloud 存储库的信息。

Tip

本指南向您 展示如何将 Einstein Activities API 与 SFRA 的结账 集成,以便它发送与 PWA Kit 结账相同的活动。

如果分阶段部署在 SFRA 或 SiteGenesis 上有将分析数据发送到 Web 适配器日志的其他页面,则对于这些页面,您可以遵循类似于本指南中描述的过程。查看 Retail React App 中的相应页面,并观察它们发送了哪些活动。然后,您需要在 SFRA 或 SiteGenesis 页面上发送相同的活动。作为资源,此 Einstein 活动概述 向您展示了这些活动应该在哪里使用。

不正式支持将 SiteGenesis 与可组合网店结合使用的实施。

Note

关于代码示例 

集成提供的代码示例时要小心,并务必在将代码投入生产环境 (Production) 之前对其进行彻底测试。

要添加到现有代码的行用加号 (+) 标记,要删除的行用减号 (-) 标记。

在运行本教程中的命令之前,请将所有占位符替换为实际值。占位符的格式如 $PLACEHOLDER

第 1 步:更新结账控制器 

首先更新您的结账控制器以包含当前的购物篮 ID。

1res.render('checkout/checkout', {
2+   basketId: currentBasket.UUID,
3    order: orderModel,
4    customer: accountModel,
5    ...
6});

第 2 步:更新结账模板 

更新用于结账的 ISML 模板。此更改使浏览器可以使用购物篮 ID、商品和总计。

1-    <div id="checkout-main" class="container data-checkout-stage <isif condition="${pdict.order.usingMultiShipping && pdict.order.shipping.length > 1}">multi-ship</isif>" data-customer-type="${pdict.customer.registeredUser ? 'registered' : 'guest'}" data-checkout-stage="${pdict.currentStage}" data-checkout-get-url="${URLUtils.https('CheckoutServices-Get')}">
2+    <div id="checkout-main" class="container data-checkout-stage <isif condition="${pdict.order.usingMultiShipping && pdict.order.shipping.length > 1}">multi-ship</isif>" data-customer-type="${pdict.customer.registeredUser ? 'registered' : 'guest'}" data-checkout-stage="${pdict.currentStage}" data-checkout-get-url="${URLUtils.https('CheckoutServices-Get')}" data-checkout-price-total="${pdict.order.priceTotal}" data-checkout-items="${JSON.stringify(pdict.order.items)}" data-basket-id="${pdict.basketId}">

第 3 步:创建助手 

创建名为 js/einsteinHelpers.js 的 JavaScript 文件,其中包含助手函数:

不要忘记将占位符 $YOUR_SITE_ID$YOUR_CLIENT_ID 替换为实际值。

Important

1'use strict';
2
3/**
4 * Get the value of a cookie
5 * Source: https://gist.github.com/wpsmith/6cf23551dd140fb72ae7
6 * @param  {string} name  The name of the cookie
7 * @return {string | undefined}       The cookie value
8 */
9function getCookie(name) {
10    var value = '; ' + document.cookie;
11    var parts = value.split('; ' + name + '=');
12    var result;
13
14    if (parts.length === 2) {
15        result = parts.pop().split(';').shift();
16    }
17    return result;
18}
19
20/**
21 * Fire a given Einstein activity with the provided data.
22 *
23 * @param {string} name - The name of the activity.
24 * @param {Object} data - The activity payload.
25 */
26function fireEinsteinActivity(name, data) {
27    // NOTE: These should be placed in the custom preferences of BM. This will help
28    // avoid any code deployments if you need to change these values.
29    // NOTE 2: this is _Einstein_ site id (not the same as SFRA one like RefArch).
30    var SITE_ID = '$YOUR_SITE_ID';
31    var CLIENT_ID = '$YOUR_CLIENT_ID';
32    // Reports & Dashboards will only show data that's been tagged as `prd` (production)
33    var INSTANCE_TYPE = 'prd';
34
35    // Assign the realm to the data.
36    var activityData = Object.assign(data, {
37        realm: SITE_ID.split('-')[0],
38        instanceType: INSTANCE_TYPE
39    });
40
41    var userId = data.userId;
42    var cookieId = data.cookieId;
43
44    // Apply payload information for logged in users.
45    if (userId) {
46        activityData = Object.assign(activityData, {
47            userId: userId
48        });
49    }
50
51    if (cookieId) {
52        activityData = Object.assign(activityData, {
53            cookieId: cookieId
54        });
55    }
56
57    var url =
58            'https://api.cquotient.com/v3/activities' +
59                '/' + SITE_ID +
60                '/' + name;
61
62    try {
63        fetch(url, {
64            headers: {
65                'Content-Type': 'application/json',
66                'x-cq-client-id': CLIENT_ID
67            },
68            method: 'POST',
69            body: JSON.stringify(activityData)
70        });
71    } catch (e) {
72        console.error(e);
73    }
74}
75
76var exports = {
77    fireEinsteinActivity: fireEinsteinActivity,
78    getCookie: getCookie
79};
80
81module.exports = exports;

第 4 步:记录活动 

更新您的 checkout.js 脚本以记录活动。您必须将此 require() 调用添加到结账脚本的顶部,并且它必须出现在任何现有导入之后。

1var einsteinHelpers = require('../einsteinHelpers');

当结账阶段发生变化时,触发 checkoutStep 活动。在 updateUrl 方法中添加以下代码:

1/**
2 * @returns {boolean} whether the current customer is registered or not
3 */
4function isRegisteredCustomer() {
5    return $('.data-checkout-stage').data('customer-type') === 'registered';
6}
7
8/**
9 * Get the cookieId, which is a unique identifier used for linking subsequent activities to the same user.
10 * If the cookieId is not defined, then Reports & Dashboards will treat the activity as coming from an anonymous user.
11 * @returns {string | undefined} value of the cookieId param for Einstein Activities API
12 */
13function getCookieId() {
14    var siteId = window.CQuotient && window.CQuotient.siteId;
15    // This usid cookie is set by either PWA or plugin_slas
16    return einsteinHelpers.getCookie('usid_' + siteId) || einsteinHelpers.getCookie('usid') || undefined;
17}
18
19/**
20 * Get the userId, which is for linking registered users across different devices.
21 * @returns {string | undefined} value of the userId param for Einstein Activities API
22 */
23function getUserId() {
24    var siteId = window.CQuotient && window.CQuotient.siteId;
25    // This enc_user_id is set by PWA
26    return window.localStorage.getItem('enc_user_id_' + siteId) || window.localStorage.getItem('enc_user_id') || undefined;
27}
28
29/**
30 * Updates the URL to determine stage
31 * @param {number} currentStage - The current stage the user is currently on in the checkout
32 */
33function updateUrl(currentStage) {
34    // ...
35
36    var cookieId = getCookieId();
37    var userId = isRegisteredCustomer() ? getUserId() : undefined;
38
39    einsteinHelpers.fireEinsteinActivity('checkoutStep', {
40        basketId: $('#checkout-main').data('basket-id'),
41        stepName: checkoutStages[currentStage],
42        stepNumber: currentStage,
43        cookieId: cookieId,
44        userId: userId
45    });
46}

触发 checkoutStep 方法中的 updateUrl 活动可确保跟踪从一个结账阶段到下一个(或上一个)阶段的任何转换。

Note

在结账代码的 initialize 函数末尾触发 beginCheckout 活动:

1//
2// Send Einstein `beginCheckout` activity
3//
4// Parse total amount value
5var amount = $('#checkout-main').data('checkout-price-total');
6amount = Number(amount.replace(/[^0-9.-]+/g, ''));
7
8var products = $('#checkout-main')
9    .data('checkout-items')
10    .items.map(function (item) {
11        return {
12            id: item.id,
13            price: Number(item.priceTotal.price.replace(/[^0-9.-]+/g, '')),
14            quantity: item.quantity
15        };
16    });
17
18var cookieId = getCookieId();
19var userId = isRegisteredCustomer() ? getUserId() : undefined;
20
21einsteinHelpers.fireEinsteinActivity('beginCheckout', {
22    products: products,
23    amount: amount,
24    cookieId: cookieId,
25    userId: userId
26});

beginCheckout 结账期间,每次页面加载仅触发一次活动。活动数据准备是自动处理的。

Note

就是这样!您已成功将 Einstein Activities 与 SFRA 的结账集成。要完成 Reports amp &的设置,请执行以下作:仪表板,完成 Reports &仪表板

另请参阅