Integrating Sitecore Content Hub PIM and OrderCloud
Overview
Content Hub can be a great choice to be single "source of truth" system for all company products and services, which can power brand and 3rd party websites, print catalogs, ERP and eCommerce systems and more. This post is a quick overview of integration approach I implemented with Azure Logic App, which uses a combination of custom and prebuilt Azure functions.
Integrating Sitecore Content Hub PIM and OrderCloud
Overview
Content Hub can be a great choice to be a single "source of truth" system for all company products and services, which can power brand and 3rd party websites, print catalogs, ERP and eCommerce systems, and more. This post is a quick overview of the integration approach I implemented with the Azure Logic App, which uses a combination of custom and prebuilt Azure functions. I wrote a few custom functions to read Content Hub entity data and transform it to destination format and used prebuilt HTTP calls and other Azure functions to add conditional logic and send this data to Sitecore OrderCloud. Here's how it works:
- TODO: add a diagram
Implementation Approach
Azure Logic App to sync catalog changes from Sitecore Content Hub to OrderCloud
The below diagram is taken from the Azure logic App designer for my sample indexer. I like this very visual way of coding apps - easy to understand and easy to maintain. This app is POC to illustrate the idea, not quite production-ready, but it works and can easily be improved with Azure queues, retry and poison message handling logic, enhanced logging with App insights, and so on, but that would make this blog post very long :)
Here's how it works: once triggered an App will read the affected entity from Content Hub via its REST API using "Get Content Hub Entity Data", then generate JSON payload expected by OrderCloud APIs with "Render JSON Template" and then finally POST it to OrderCloud using Azure's out-of-the-box HTTP POST call. Sounds pretty straightforward, isn't it? It is.
Details on Azure Functions
When an HTTP request is received
The first item is an entry point of this entire Azure Logic App, It's an abstraction, defining entry point URL and payload JSON schema, which is what Content Hub's "API call" action will invoke each time when target entity is created or deleted (more on this in sections below). An ID of target Entity from Content Hub is getting passed in the payload of this request it will be used to retrieve that Entity in functions/steps below.
Get Content Hub Entity Data
The next function is a custom one: it makes an API call to Content Hub REST API to read the target entity, as well as all related entities, listed in the EntityRelations header parameter. The TargetEntityIdJsonPath parameter is a JSON Path expression, pointing to where the actual ID of the target entity can be found in payload JSON. For the purpose of this POC, I simply passed Content Hub credentials via function header parameters in real-life production scenarios such information should be stored in configs or, even better, Azure Key Vault.
Internally this function will read all properties from target entities, then read and add all fields from specified related entities and finally append renditions of the target entity. The output is serialized into JSON, which looks like this:
{
"Properties": { /* target entity properties */},*
"Properties": { /* a collection of elements, holding properties of the related entities, specified in EntityRelations parameter above */},*
"Renditions": { /* collection of rendition names and their Urls in Content Hub */}
}
See additional sections below for more details on function code and link to code project in GitHub
Generate JSON Payload for OrderCloud
Another custom function, which is a very simple version of templating engine. The template is expected to have two kinds of tokens:
- Tokens enclosed in double curly brackets hold JSON path to value, which should be found in Entity data from the previous call and then injected in place of a given token. Here's how it may look like {{$.Properties.Id}}
- Tokens enclosed in double square brackets can have the actual values to be injected in place of a given token. Those can look like this: [[ Hello world ]]
I used simple Regex to find and then replace all in the template. See additional sections below for more details on function code and link to code project in GitHub
Get OrderCloud Auth token
Here I'm using another Out-of-the-box Azure function to call OrderCloud authentication API, passing url-encoded credentials to get authentication token for the following "Send Product data to OrderCloud API" call to OrderCloud products API
Parse AuthToken JSON
The output of the above "Get OrderCloud Auth token API" call need to be parsed in order to extract token value from it. Luckily Azure already provides "Parse JSON", which is what I use here.
Send Product data to OrderCloud API
Again, using Azure out-of-the-box HTTP POST call, this time to send an HTTP POST request to OrderCloud API with payload generated by "Generate JSON Payload for OrderCloud" function and Authorization header generated from the output of "Get OrderCloud Auth token" functions above. The Authentication token value is a concatenated string, which consists of "Bearer " prefix followed by the access_token value from JSON response of the previous "Generate JSON Payload for OrderCloud" call
And finally, a Response
The last element is to format and send a response to the caller. I simply forward the response body from the above call to OrderCloud since calling the action in Content Hub doesn't really care about the response, but this response might be useful for debugging purposes.
Appendix
- Source code for above custom Azure functions and template Azure Logic App: https://github.com/sergyatsenko/SY.ContentHub.AzureFunctions
- Please refer to Sitecore documentation for more details on using Content Hub Actions and Triggers to call above Logic App.
- OrderCloud documentation on product APIs: https://ordercloud.io/api-reference/product-catalogs