30 min read
Published:
Hello friends! This post emerged from another topic I started writing last week. I realized it would be more sensible to take a step back and cover an introductory topic before diving into a mini-series on related subjects.
Today, I'm excited to introduce a project I've been working on: the Sitecore Personalize Tenant SDK, available on NPM here: sitecore-personalize-tenant-sdk - npm (npmjs.com). This SDK focuses on wrapping the freely available APIs for managing assets in Sitecore Personalize. While still a work in progress, it's already proving valuable for those handling testing scenarios or exploring other use cases with Sitecore CDP/P.
The SDK primarily targets Personalize, but it's worth noting that CDP and Personalize were originally a single product built by Boxever. As such, this tool is designed to streamline working with both products, making it easier to consume and interact with their features.
This SDK is intended for anyone who wants to create, read, update, or delete Sitecore Personalize assets (such as flows, decision models, templates, and conditions). Some specific use cases include creating an Experience in Sitecore Personalize based on an action in another system, using a chat application with AI to generate experiences, or—as with the Serializer (which will soon use the SDK)—enabling new development approaches with Sitecore Personalize.
To clarify, this SDK is not designed for data ingestion into Sitecore CDP/P. For those needs, use the Engage SDK if you're not on XM Cloud or JSS 21.6+. If you are, opt for the Cloud SDK. For non-Web/Node platforms, you'd still interact directly with the Stream APIs or use the Engage Script.
Getting started with the SDK for Sitecore Personalize is straightforward. You can pull the latest version from NPM using the following command:
1$ npm install sitecore-personalize-tenant-sdk@latest
This SDK is not a CLI, so you'll need to install it in your Node project. Once installed, you can interact with it by initializing the Client. The Client expects an object of ClientInitOptions
, which requires a client ID, client secret, and the region for your Sitecore Personalize tenant. Keep in mind that this tool only supports tenants on Cloud Portal. If your tenant still requires access from a Boxever domain, you won't be able to use this SDK. Since most tenants will be migrated to the Cloud Portal soon, you'll need to wait until your tenant is converted before using this SDK.
Creating the Client ID and Secret is now straightforward. I've written a blog post about it here: Sitecore Personalize: New Developer Focused API Keys (dylanyoung.dev). You can also find more information in the Sitecore documentation: Create an API key | Sitecore Documentation. In my original article about creating New Developer Focused API Keys, I explored the potential of using the REST APIs—which I've incorporated into my SDK—to implement some of the use cases mentioned in the "Who is this for?" section. For now, let's focus on how to start using the client. You can use the code below as an example. While you might want to initialize the client using environment variables in practice, this example demonstrates the basic setup:
1import { Client, IClientInitOptions, RegionOptions } from "sitecore-personalize-tenant-sdk";23const clientOptions: IClientInitOptions = {4 clientId: "<Client Key Generated from Sitecore Personalize>",5 clientSecret: "<Client Secret Generated from Sitecore Personalize>",6 region: RegionOptions.US7}89const client = new Client(clientOptions);1011// Now you can start using the Client
One nice feature of the client is that you don't have to worry about authentication—it's all handled for you. So if you want to get all the Web Templates from your tenant, you can simply run the following command. This will return a Promise<IResponse<ITemplate[]> | undefined>
.
1import { IResponse, ITemplate, TemplateType } from "sitecore-personalize-tenant-sdk"23let templates: IResponse<ITemplate[]> | undefined = await client.Templates.GetAll(TemplateType.Web)
That covers the basics for now. I'll explore more use cases in the SDK documentation and upcoming blog posts.
Now that we've explored how to use this new SDK, let's discuss its potential applications in Sitecore Personalize for various testing scenarios.
This scenario is quite complex, as it's not directly about the SDK itself but rather how it enables a new workflow for building assets in Sitecore Personalize. Using the SDK, you could leverage a tool like the Serializer to implement a CI/CD process. This allows you to create code for Sitecore Personalize locally. You can then run unit tests on this local code to verify that your functionality works as intended. I'll delve deeper into this use case in future posts.
Integration testing verifies that the code you've written remains intact and functions as intended. The approach varies depending on the types of assets you're working with in Sitecore Personalize.
What exactly can you test with a Web Template or Flow? The answer is somewhat complex. Ideally, you'd want to test the Experience or Experiment on your own website, but that's quite complicated and, to my knowledge, not currently possible. Instead, you may want to see how Sitecore Personalize renders the contents of your Web Template or the Experience/Experiment based on your inputs. I can confirm this is achievable and can be done with the SDK (which I'll cover in a future blog post). You can learn more about the available APIs here:
https://doc.sitecore.com/personalize/en/developers/api/preview-templates.html - This API allows you to test existing Templates. You can pass a friendly ID or ref for a web template along with template params, and it'll return a collection of HTML, CSS, and JavaScript output.
https://doc.sitecore.com/personalize/en/developers/api/preview-template-code.html - This API differs slightly from the one above. It lets you test the assets and template params before they actually exist, allowing for a final check in a local source control system before pushing changes to the environment.
Another crucial form of testing involves verifying that your local changes still align with what's been deployed to your tenant. This ensures proper governance and prevents customers or developers from making unauthorized changes directly in Personalize.
A Sitecore Personalize Condition is a newer concept, but it's essentially a type of template you can define in Sitecore Personalize. These conditions were designed to replace audience templates on Flows (Experiences and Experiments). They're probably the closest equivalent to XP personalization rules, though they don't fully replace that functionality. Conditions allow you to define small code segments that represent specific decisions you want to make. For instance, you could create a condition that determines whether the current session user is a Visitor or a Known Guest.
Integration tests for these conditions are available using the undocumented endpoint: /v2/callFlows/testTemplate
. This endpoint accepts a specific set of parameters, enabling you to debug and verify if your condition's code works as expected in your environment. However, it's important to note that this endpoint doesn't function quite as you might expect. Rather than testing the template itself, it tests a flow and determines if it works based on the template it's using. One major challenge with this approach is that to test the integration of a Condition, you need a dummy experience to run this endpoint.
For Conditions, unit testing is likely your best approach. It allows you to test your code against mock data to ensure it performs as expected. However, the process isn't always straightforward. Sitecore Personalize uses ES5 syntax and requires a specific JavaScript format. Even if you write your code correctly locally, it might not work in Personalize. This is where integration tests prove valuable—they can help bridge the gap between local development and the Personalize environment.
When creating a Decision Model with Programmables or Decision Templates, testing individual components directly isn't possible. Instead, you must test the entire Decision Model. This approach, similar to Conditions, requires "dummy" decision models that incorporate your Programmables or Decision Templates. It's worth noting that JS Modules, which are only used alongside Programmables, can only be tested in this manner during integration testing. While this method is necessary for integration tests, I see value in running unit tests locally. These local tests can give you a general idea of how your components will perform before deploying them to an environment. The SDK includes a function called TestDecisionModelVariant
, which accepts a guestContext object (I'll explain this further in my next blog post), a Decision Model Ref, and a Variant Ref. This function allows you to pass a custom Guest to your Decision Model Variant, enabling integration tests for specific outcomes.
This concludes our overview of the SDK and introduction to integration versus unit testing for Sitecore Personalize. As mentioned throughout this post, I'll be releasing more content soon detailing how to use the SDK for specific integration testing scenarios. While it's still a work in progress, I plan to apply the SDK to the serializer and explore several unit testing scenarios. I'll also demonstrate how combining these with the Serializer can revolutionize your development workflow with Sitecore Personalize.