Translating Content with Kentico Cloud and Azure

ver since we released Kentico Cloud, developers have asked for a way to write content into their projects. To meet this need, we released a Content Management API last November, which allowed content to be created programmatically from any source. So, what are the possibilities this interface? In this article, I’ll show you how I leveraged Azure and the Kentico Cloud Content Management API to automate translating my content. 

Setting Up the Project

The first step of the process was to set up my Kentico Cloud project. Because I would be working with translated content, this meant adding some new Localization languages under my Project settings.

Creating the Content

Next, I created some content items. In this super awesome demo, I went with articles, because that is so original. For each content item, I had a title, intro text, and body.

I added a sample article to test with. The idea was that the “original” post would be created in the default language (English). Then, after it is published, I would use Azure to automate the translated content production.

I made another article, just so my screen shot wouldn’t be so boring.

Note that switching the language shows the content as Not translated.

Creating the Azure Functions

If you haven’t heard me say it before, Azure Functions are pretty awesome. They are great at extracting core pieces of functionality and making them globally available using practically any technology. They work especially well with other Azure components, like Azure Logic Apps. I decided to leverage these components, along with the Microsoft Translator API, to handle my automatic translations. The Logic App would handle the process flow, while the Functions handled the heavy lifting code pieces.

First, I defined what I wanted each function to do. Because I wanted to add some approval process (more on that to come), I decided to spread my code across two functions. The first would handle retrieving the full content from Kentico Cloud and generating the translated text. The second function would use the Kentico Cloud Content Management API to create the new content. 

In Visual Studio, I created a new Azure Function project and added my NuGet packages for the Kentico Cloud Delivery API and Content Management API.

Next, I added my two functions.

ProcessPublishWebhookFunction

This function processes the publish event for my Kentico Cloud content items. When a content item is published, the function uses the codename value that is passed to retrieve the full article details.  

 

1
2
3
4
5
6
// Get the content
Task<string> body = new StreamReader(req.Body).ReadToEndAsync();
string strCodename = body.Result.ToString();
log.Info(strCodename);
 
DeliveryItemResponse responseOriginal = await client.GetItemAsync(strCodename);

 

I created a new class to hold the full detail, and to make the passing of the translated text easier. After retrieving the details, I created a new ArticleModel.   

 

1
2
3
4
5
6
7
8
9
10
11
// Defines the content elements to update
ArticleModel NewArticleModel = new ArticleModel
{
  OriginalCodename = responseOriginal.Item.System.Codename,
  NewArticle = new Article
  {
    Title = await GetTranslatedText(strTranslatorAPIKey, responseOriginal.Item.GetString("title"), strLanguageCode),
    Intro = await GetTranslatedText(strTranslatorAPIKey, responseOriginal.Item.GetString("intro"), strLanguageCode),
    Body = await GetTranslatedText(strTranslatorAPIKey, responseOriginal.Item.GetString("body"), strLanguageCode)
  }
};

 

For each element, I called a helper function to retrieve the translated content. The Microsoft Translator API required the language code, and API Key, and the URLEncoded text. 

 

1
2
3
4
5
6
7
8
9
10
string strTranslated = "";
using (HttpClient client = new HttpClient())
{
  client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", strTranslatorAPIKey);
  string uri = host + path + "?to=" + strLanguageCode + "&text=" + System.Net.WebUtility.UrlEncode(strOriginal);
  HttpResponseMessage translationresponse = await client.GetAsync(uri);
  string result = await translationresponse.Content.ReadAsStringAsync();
  strTranslated = XElement.Parse(result).Value;
}
return strTranslated;

 

The serialized ArticleModel is then returned by the function.

 

1 return (ActionResult)new OkObjectResult(JsonConvert.SerializeObject(NewArticleModel));

 

ProcessTranslationFunction

Once the content is approved (as part of the Azure Logic App flow), I coded this function to handle the creation of the newly translated content within Kentico Cloud. First, I created a new ContentManagementClient object for connecting to the API.

 

1
2
3
4
5
6
7
8
ContentManagementOptions options = new ContentManagementOptions
{
  ProjectId = config["KenticoCloudProjectID"],
  ApiKey = config["KenticoCloudContentManagementAPIKey"]
};
 
// Initializes an instance of the ContentManagementClient client
ContentManagementClient client = new ContentManagementClient(options);

 

NOTE
The Content Management API requires an API Key. This key expires every 90 days, so be sure to add checks to ensure your functionality handles when the key is expired. You can find your API key under Project Settings / API keys in your Kentico Cloud project.

The input parameter is the serialized ArticleModel object created in the ProcessPublishWebhookFunction

 

1
2
3
4
// Defines the content elements to update
Task<string> body = new StreamReader(req.Body).ReadToEndAsync();
 
ArticleModel NewArticleModel = JsonConvert.DeserializeObject<ArticleModel>(body.Result.ToString());

 

The function then uses the Kentico Cloud Content Management API to create the new language variant.

 

1
2
3
4
5
6
7
// Specifies the content item and the language variant
ContentItemIdentifier itemIdentifier = ContentItemIdentifier.ByCodename(NewArticleModel.OriginalCodename);
LanguageIdentifier languageIdentifier = LanguageIdentifier.ByCodename(strLanguageCode);
ContentItemVariantIdentifier identifier = new ContentItemVariantIdentifier(itemIdentifier, languageIdentifier);
 
// Upserts a language variant of your content item
ContentItemVariantModel<Article> responseUpdate = await client.UpsertContentItemVariantAsync<Article>(identifier, NewArticleModel.NewArticle);

 

I deployed the functions to a new Azure Function App.

View the full Function Code

NOTE
The Functions were created using the new .NET Standard format. This made the functions more lightweight but also required additional functionality to pull in settings and configurations. 

Creating an Azure Logic App

With the functions created and deployed, I was ready to create my Azure Logic App. The Logic App would serve as the webhook Kentico Cloud calls when content is published. The flow has several steps, which guide the content through an approval process before it is created within Kentico Cloud.

There are a lot of pieces to the Logic App, so I thought it would easier to show you in a video.

If you want to learn more about Logic Apps and Kentico Cloud, check out my previous blog.

Testing

In Kentico Cloud, I published a content item.

I confirmed that the Logic App was successfully executed and was at the Approval check state.

I confirmed I received the Approval email with the translated text.

I confirmed that approving the content successfully completed the Logic App process.

Lastly, I confirmed the translated content was created within Kentico Cloud. I switched to the es-ES language to view the content.

Your Turn

If you're wanting to set up your own translation automation, here are some links to get you started. In my demo, I focused on Azure and Microsoft, but the possibilities are endless! If you're more in the AWS camp, check out Lamba functions and Amazon Translate for your solution.

Kentico Cloud Webhooks
If you want to use automation with Kentico Cloud, you need to know how webhooks work. Be sure you understand the structure of the notifications, when they fire, and how you can use them in your projects.

Kentico Cloud Content Management API

The Content Management API is how you will create your content in your project. As our newest API, it's still being built out but has a lot of functionality you can use. We have an SDK for .NET to help you with your integrations.

Azure Logic Apps

In my example, an Azure Logic App was the automation maestro, handling the initial requests  and data flow. Logic Apps have a lot of built-in connectors, and you can create your own. Use the Designer view to layout your flow to suit your needs. 

Azure Functions

The brains of the operation, Azure Functions handle all the heavy lifting and processing. They are where I move data between systems, translate the content, and connect everything together. Functions can come in several languages and flavors, so be sure to read up on the documentation to learn more. 

Moving Forward

Pretty awesome, huh? By combining the Kentico Cloud Content Management APIwith a translation service, you can automate your content creation for any language. Because Azure Logic Apps have built-in functionality for approvals, you can make sure the content looks correct at any step of the way. 

By leveraging Azure and Kentico Cloud, you can automate your content and create a streamlined process for editing your site. Good luck!


By Bryan Soltis in Kentico