Content Hub gems: Leveraging action scripts to aggregate CMP content and your linked assets – part 2

Introduction

We previously looked at how to leverage action scripts to simply how to access content and linked assets with a single web API call. In this blog post, we follow up with a deep dive into the code and logic within the action script itself.

The script

The first part of the script is shown below.

  1. Line 1 to 5 has all the required libraries being used in the script
  2. Line Line 7 & 8 has logic for extracting the id of the content item, which we are gathering the data in this script. Data from the web API request is specified in Context.Data, which is a JToken. The script expects it to be a JObject containing a contentId property.
  3. Line 10 to 14 contains logic for checking whether the content id could not be extracted from the data. In which case, a response http status-code 400 (bad request) together with a user-friendly error-message is returned. This is done with help of helper function SetError, as shown below:
  4. Line 16 to 19 contain the EntityLoadConfiguration we are going to use when loading the assets linked to our content item. Only Filename, Title and Description as well as AssetToSubtitleAsset relation will be loaded in our use case.
  5. Line 21 to 24 similarly contain the EntityLoadConfiguration we are going to use when loading the content item (our blog post content type). Blog_Title, Blog_Quote, Blog_Body as well as CmpContentToMasterLinkedAsset & CmpContentToLinkedAsset relations will be loaded here. CmpContentToMasterLinkedAsset relation holds the link to the master image associated with this item. CmpContentToLinkedAsset relation has the assets linked with this item, such as the video asset.
  6. Line 26 to 31 contain the logic for loading the content (Blog post), by leveraging MClient.Entities.GetAsync function and specifying the content id and the EntityLoadConfiguration already defined above. We have a check on line 27 whether the content entity was actually found, and return a response http status-code 400 (bad request) together with a user-friendly error-message, when none was found.
  7. Line 33 to 37 start preparing the output object for our script. We have created a new JObject which has the shown properties. We have added the values of properties Blog_Title and Blog_Quote and Blog_Body. We are going to add more properties as we walk through the rest of the script.

Second part of the script

The code listing from line 39 through to 83 has the logic for loading the video asset linked with this content item.

  1. Line 39 get the list of video asset ids by using a helper function GetLinkedVideos shown below. This function makes use of the LINQ query, which filters down only entities of type M.Asset which are linked to current content id (parent in the CmpContentToLinkedAsset relation). In my use case, I have used the file extension .mp4 to identify video asset (but you could use any other property or combination of properties to meet your specific use cases)
  2. Line 40 checks if our GetLinkedVideos found any video ids, in which case the rest of the logic will try and process them
  3. Line 42 extract the first video id that was found. I have used the MCient.Logger.Info method to log user friendly messages that helped me show which video ids were found. These message appear on the Action Script’s View Logs window.
  4. Line 45 to 46 contain the logic for loading the video asset entity, by leveraging MClient.Entities.GetAsync function and specifying the video asset id and the EntityLoadConfiguration already defined before in first part of the script. Line 46 checks to ensure the video asset was found, for us to do further processing
  5. Line 48 and 49 contains the logic for getting the video asset public link, which is required as part of the output from the script. On line 48, I am leveraging GetPublicLinks function, which I have defined as shown below. I am interested in the original rendition of my video asset. Please note that if the video asset does not have original public link generated, nothing will be retrieved.
  6. Which is why the code on line 49 further makes use of a function named GetFirstPublicLinkUrl which helps load the M.PublicLink entity and inspect the RelativeUrl property, as shown below.
  7. Line 50 to 55 we are now creating a new JObject which has the shown properties as expected the output of the script. This object is added to videoAsset section of our main result object.
  8. Line 57 contain logic for getting the video asset subtitles. The AssetToSubtitleAsset is a IParentToManyChildrenRelation, so we get hold of subtitles using the Children property from this relation. In essence, a video subtitle is an asset in its own right. So the code listing from Line 59 is trying to load each of the subtitle asset and we are interested in the Title property as well as the Public Link (original rendition). This is now familiar to how we got public link for the video asset itself. We add each of these properties in a JArray, which in turn, is added to the result.

Part three of the script

In the last part of the script, we also get the master asset linked to our content item. In this case, we are interested in the asset Public Link, asset file name, Blog_Title and Blog_Body properties. We create a new JObject which has the shown properties as expected and added to the result object.

Line 103 stores our result object that we have been preparing onto the Context. This tells the script to return it to the user.

Final script output

The script output is similar to the one shown below.

This completes the code listing for this script.

Next steps

In this blog post, I have looked at the second part of the Content Hub Action Scripts for Web API use cases. We have taken a deep dive into the source code for the script, covering the various components and how they work together. For a practical use cases, look at my blog post on how I have created a custom connector for publishing video assets from Content Hub into Cloudflare Stream

Stay tuned and leave us any feedback or comments.

Unlocking the Potential: Tips and Tricks for Working with GraphQL Queries and Sitecore Experience Edge

Adapted from
adapted from www.wallarm.com

What is GraphQL

GraphQL is a kind of query language and server-side runtime technology used widely for application programming interfaces (APIs) that ensure that the client gets the required data. Nothing less or nothing more. Created by Facebook, GraphQL has a lot of aims and functions:

  • A powerful data-fetching API
  • API interface that’s easy to learn and work with
  • An open-source query language making APIs fast and flexible
  • An effective method to streamline security management for the API
  • A way to give developers and business analysts the ability to develop APIs with desirable methods
  • A query language that gets along with a given integrated development environment easily and effectively
  • The facility to develop APIs that will function the way the client/end-user wanted or expected

GraphQL Playground

The easiest way to compose GraphQL queries to query your Sitecore Experience Edge is to make use of the GraphQL playground. I am presuming that you already have your Sitecore Experience Edge instance
connected to your Sitecore Content Hub instance or Sitecore XM Cloud instance.
To refresh your memory, you can visit this blog post where I have detailed steps to help you with the set up

In this blog post, I will be working with my Sitecore Content Hub instance to share a few tips and tricks. You will find these tips and tricks applicable to Sitecore XM Cloud as well.

Preview and Delivery APIs

Before you can access the GraphQL playground, you need to decide whether you are going to be using the Preview API or the Delivery APIs.

  • Preview API: The Preview API is a GraphQL endpoint that exposes a preview of your content. Use the Preview API to access content that is not approved yet, including drafts. This can be useful when you want to test content in a staging environment before going to production. This is accessible using endpoint {ContentHubURL}/api/graphql/preview/v1 where ContentHubURL is your Sitecore Content Hub instance url.
  • Delivery API: The Delivery API is a GraphQL endpoint that exposes approved and published content. Use this API for all production-related actions. This is accessible using endpoint https://edge.sitecorecloud.io/api/graphql/v1

You will also need access to API Keys to use with your Preview or Delivery APIs. You can obtain your API keys as follows:

  • Navigate to Manage -> API Keys to launch the API Keys management screen
  • On the API Keys screen, you need to provide the required name and scope of the API Keys, then click the call to action to generate the Preview or Delivery API keys. Please keep a note of them as you get only once chance to view and copy them. I recommend storing these keys securely on your Key Vault or similar tool.

Launching GraphQL Playground

To launch the GraphQL playground, open your browser and specify the following URL:

  • Preview IDE: {ContentHubURL}/api/graphql/preview/ide This will launch the Preview API playground
  • Delivery IDE: https://edge.sitecorecloud.io/api/graphql/ide This will launch the Delivery API play ground

Below is a screenshot of Delivery API playground

  • A – This is the Delivery IDE URL
  • B – This is the Delivery API endpoint
  • C – This the GraphQL query section, where you will specify the queries. In my example, this the query to list all published assets, by using the predefined object allM_Asset
  • D – This is the output of the GraphQL query, showing the results as JSON object. Notice only the id and title are returned, as specified in my query. This is one of the main advantages of using GraphQL, you get nothing less or nothing more than what you specify.
  • HTTP Header – this is where we specify our API Key using the “X-GQL-Token” header. In this example, I have used the Delivery API key as I am querying my Delivery instance.

Troubleshooting tips and tricks

I am presuming you have so far been successful getting your GraphQL playground working. If you encounter any issues, try and troubleshoot as follows:

  • Do you have your Delivery Platform setup correctly? ?Check that your Sitecore Content Hub has a license for Delivery platform, and this has been enabled. One way of verifying this is by having Manage -> Delivery Platform icon on your dashboard, as shown below. If you are missing it, contact Sitecore Support to have it enabled.
  • Are you using correct Delivery API or Preview API Keys? Do not get the Delivery or Preview API keys mixed. To avoid any potential mix up, ensure you assign your API keys names to reflect Delivery or Preview scope when generating them. If you are not sure anymore, you can always discard and generate new ones (Please note in Production environments, deleting and generating new API keys may affect production services, plan this carefully
  • Are you accessing the correct GraphQL Playground? Similarly to above, ensure your browser is pointing to Delivery IDE or Preview IDE accordingly. For example, if you haven’t published all your Assets, you may get discrepancy in the assets output within Delivery IDE and Preview IDE. Please note Preview IDE will show content that is not approved yet, including drafts.
  • Have you checked Browser Developer Tools? Your browser “Network” section captures detailed logs on requests and responses. An example screenshot below will help verify the response coming back from GraphQL server:

GraphQL tips and tricks

Using filters with your query

Suppose you want to control how many items to query, then you will need to filter the query results. Below is an example, where we are getting a single asset with id value of "some_asset_id"

Using parameters with query filters

Suppose you want to use a parameter with your filter the query. A use case is to be able to dynamically filter the list of assets based on some condition. Below is an example, where we are using a parameter for the id value of "some_asset_id"

  • A – We make use of the Query Variables section to define parameters. In this case it is named "assetId"
  • B – We define the parameter using the arguments to the query as shown here. ID is the strong scalar type for the Asset Identifier field

Next steps

This completes this blog, where I have walked you through GraphQL and Sitecore Experience Edge. I hope you find this useful, and feel free to leave me any comments or thoughts. See you soon in my next blog post.