Sales/Service Cloud Connector - Einstein Decisions Template

The Marketing Cloud Personalization CRM Einstein Decisions template is designed for use alongside the Next Best Action component of the connector for Sales and Service Clouds. When configuring the template, code available below, it is important that you only modify the following parts:

  • Maximum promotions returned

Any changes to the template outside the preceding areas could break the component’s ability to render the response. As noted in the business user documentation, impression, and click data is currently not sent back to Personalization Campaign from CRM.

Prerequisites 

To use the following server-side template, you need Personalization Connector for Sales and Service Cloud version 2.0. If you’re unsure of your CRM package version, you can check your package version by doing the following.

  1. Log into your Sales/Service Cloud account.
  2. Navigate to the Setup page by clicking the gear icon in the top-right corner and then Setup.
  3. In the left-hand navigation menu, select Apps > Packaging > Installed Packages.
  4. Search for “Personalization Connector for Sales and Service Cloud”.

The package version number is listed alongside the package name.

If you’re running version 1.5 or lower or version 1.8 or later, you can upgrade your AppExchange package by navigating to the connector AppExchange page, downloading the latest version, and then selecting Upgrade for all users when prompted.

If you’re running version 1.6 or 1.7, you will have to uninstall your existing package and reinstall the latest version. After you’ve upgraded to version 2.0, you will not need to uninstall the package for future updates, as you will then become eligible for the upgrade option outlined for those users on version 1.5 or lower.

For instructions on upgrading your package, see Install Personalization Connector for Sales and Service Cloud on the Salesforce Help site.

Server-Side Code 

The following code sample contains Typescript code for the Personalization CRM Recommendations template.

1import { ContextualBanditConfig, decide } from "corvus";
2import { ItemReference, ContentZoneLookup } from "common";
3
4export class PromotionSearchOptions implements Search<string> {
5  search(context: GearLifecycleContext, searchString: string): ItemReference[] {
6    if (!searchString) {
7      return [];
8    }
9    const promos: Promotion[] = context.services.catalog.findByName(
10      "Promotion",
11      searchString,
12    ) as Promotion[];
13    return promos.reduce((allPromos: ItemReference[], promo: Promotion) => {
14      const promoItem = {
15        itemType: "Promotion",
16        id: promo.id,
17        label: promo.attributes["name"] != null ? promo.attributes["name"].value : promo.id,
18      } as ItemReference;
19      allPromos.push(promoItem);
20      return allPromos;
21    }, []);
22  }
23}
24
25export class EinsteinDecisionsTemplate implements CampaignTemplateComponent {
26  @lookupOptions(() => new ContentZoneLookup())
27  assetContentZoneOrTag: string;
28
29  @searchOptions((self) => new PromotionSearchOptions())
30  @title("Optional Fallback Promotion Selector")
31  @subtitle(`Search for a fallback promotion to return if there are no eligible promotions to return for the end user.
32   If no fallback is selected, no promotion will be returned. (NOTE: This field is case-sensitive.)`)
33  fallbackArm: ItemReference;
34
35  datafield: string = "promotions";
36  run(context: CampaignComponentContext) {
37    const banditConfig: ContextualBanditConfig = {
38      maxResults: 3,
39      contentZone: this.assetContentZoneOrTag,
40      fallbackArms: this.fallbackArm ? [this.fallbackArm.id] : [],
41    } as ContextualBanditConfig;
42    return { [this.datafield]: decide(context, banditConfig, null) };
43  }
44}