Breaking the barriers with a multi language translator
Tags: azure, cognitiveservices, azurefunctions, csharp
Published: 2019-11-16 19:09:25

Another day this tweet appeared on my Twitter timeline:

![Polemic tweet](https://thepracticaldev.s3.amazonaws.com/i/xadpcqupjglxba4xarth.png)

> English: "IT Brazilians professionals who lives in Brazil, with no real relevance overseas, tweeting in English, until when?
> Our country needs good professionals, and needs to include hundred thousands of people in IT, and most of them don't speak English. Be better than that, share in Portuguese.

Kind of extreme, but I understood his point even though I believe people is free to post whatever they want and in the language they want. As you can see, many people had replied to this tweet and it became an interesting thread.

Sometimes what you want to share is relevant to part of your audience, other times it can be useful to multiple cultures and as English is the universal language, I do believe we should share the content in English.

"But I don't speak English, what can I do?"

Believe or not, there's a website who can translate what you want to multiple languages, and it's free. All you need to do is go to https://translate.google.com and select the source and target languages, write the text you want to translate and hit the enter key.

WOW!

> Funny story: my friend Rodrigo Kono traveled to Japan and spent two hours at the airport trying to get help to go to his hotel. He sent me an audio telling me this "problem" and I reminded him about Google translator app, which has a feature where you can use the camera of your phone to translate a text in real time. He managed to go to his hotel and days later, return to Brazil and the day was salved thanks to his former roommate over here.

But what if you're not a Google fan or if you want to include translation features in your applications? You can consume AI pre-trained models through REST API's and achieve the same result.

> In 2016 while I was living in New Zealand, I've met a guy who started his own company after his app got featured on Tech Crunch. Basically he created an app and disrupted the traditional 1-1 language translation. You can read the full article in here: https://techcrunch.com/2016/04/20/miss-d-is-a-dictionary-app-for-the-linguistically-curious/

## Coding your own translation mechanism using Cognitive Services + Azure 

Functions + Azure Storage

The first thing we need to do is access Azure Portal and create a new "Translator Text" in your Azure Subscription:

![Creating a Cognitive Service Translator](https://thepracticaldev.s3.amazonaws.com/i/2crp38w7ulqlzhcau3hj.png)

Then we need to choose the pricing tier and choose a name for the service

![Specifying the name and resource group](https://thepracticaldev.s3.amazonaws.com/i/vcy7orzktlwrty9kbe0y.png)

Now, let's create an Azure Functions project using Visual Studio:

![Creating a new project](https://thepracticaldev.s3.amazonaws.com/i/esb5werv9x1lxayscmej.png)

After that, let's specify that our function will be triggered whenever a new blob was uploaded to our Storage Account:

![Selecting the trigger type for the Azure Function](https://thepracticaldev.s3.amazonaws.com/i/7h82841pslj1uqp2ikpm.png)

Next we need to install a nuget package to simplify the http request against the Cognitive Service which will translate out text:

```
using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using CognitiveServices.Translator;
using CognitiveServices.Translator.Translate;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.Auth;

namespace MultiLanguageTranslator
{
    public class Function1
    {
        [FunctionName("Function1")]
        public static void Run([BlobTrigger("english/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");

            var translateClient = new TranslateClient(new CognitiveServices.Translator.Configuration.CognitiveServicesConfig
            {
                Name = Environment.GetEnvironmentVariable("CognitiveServicesName"),
                SubscriptionKey = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
                SubscriptionKeyAlternate = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
            });

            using (var sr = new StreamReader(myBlob))
            {
                var fullContent = sr.ReadToEnd();
                var desiredLanguages = new string[] { "de", "es", "fr", "pt",  "it", "nl" };

                var responses = translateClient.Translate(new RequestContent(fullContent), new RequestParameter
                {
                    From = "en",
                    To = desiredLanguages,
                    IncludeAlignment = true
                });

                var storageAccountName = Environment.GetEnvironmentVariable("StorageAccountName");
                var storageAccountKey = Environment.GetEnvironmentVariable("StorageAccountKey");
                var storageAccountEndpoint = Environment.GetEnvironmentVariable("StorageEndpoint");

                var storageCredentials = new StorageCredentials(accountName: storageAccountName, keyValue: storageAccountKey);
                var blobClient = new CloudBlobClient(new Uri(storageAccountEndpoint), storageCredentials);

                var container = blobClient.GetContainerReference("translations");
                container.CreateIfNotExists();

                foreach (var response in responses)
                {
                    foreach(var translation in response.Translations)
                    {
                        var blob = container.GetBlockBlobReference($"{translation.To}.txt");
                        blob.UploadText(translation.Text);
                    }
                }
            }
        }
    }
}


```

In summary, Azure Functions will get the content of the original text that will upload into the Storage Account defined through the connection string StorageConnectionString. The content can be accessed through `myBlob` variable.
We're reading the content using the StreamReader class, then creating a string array with the languages we want to translate from the original English content.

Then, we getting some environment variables (we'll define on Azure Portal when we create the Azure Functions), and lastly we're accessing the storage account once again, but this time to store the translated text.

## Hosting the created code

First, let's create the storage account:

![Creating a storage account](https://thepracticaldev.s3.amazonaws.com/i/o398yk9oeaygtejljyrl.png)

![Creating a storage account part 2](https://thepracticaldev.s3.amazonaws.com/i/2q2r82cblxz9sbzvkz66.png)

Then's let's create the azure functions and get the publish profile to simplify our deploy process:

![Creating an Azure Function](https://thepracticaldev.s3.amazonaws.com/i/5lafm4rrip49ebomgw5b.png)

![Creating and Azure Function 2](https://thepracticaldev.s3.amazonaws.com/i/wna2uqyzs46f6eu8n4vu.png)

After it's ready, we can get the publish profile through the overview tab:

![Getting the publish profile](https://thepracticaldev.s3.amazonaws.com/i/btrz16hmix03xv51kdiw.png)

Now, let's use our Visual Studio to publish our code:

![Publishing the Azure Function Project](https://thepracticaldev.s3.amazonaws.com/i/h0wetsoamoxpro07d2uh.png)

Lastly let's create the environment variables clicking on the configuration link also from the Overview Tab:

![Creating the environment Settings](https://thepracticaldev.s3.amazonaws.com/i/p6pkrawwsjtwpw5iwjjv.gif)

Let's see everything in action:

![Testing our application](https://thepracticaldev.s3.amazonaws.com/i/c2i2r3po51tepcoetju9.gif)

The full language support can be found in here: https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support