How to Update Your Alexa Skills for Brazil

Rafael Miranda Apr 10, 2019
Share:
Localization News Portuguese
Blog_Header_Post_Img

Today, we announced that Amazon Alexa and Alexa-enabled devices are coming to Brazil later this year. Starting today, developers can use the Alexa Skills Kit (ASK) to build skills for customers in Brazil using the new Portuguese (BR) language model.

If you are new to skill development, check out this detailed walkthrough to get started. If you’re an experienced Alexa developer, you can enhance your existing skill by extending it to support the new Brazilian Portuguese language model. This tutorial will show you how you can add support for the Portuguese (BR) model for your existing skills. It will also show you how you can use ASK to enable Alexa to respond based on locales.

You will learn:

  1. How to update an Alexa skill for Brazilian customers using the new Portuguese (BR) language model,
  2. How to update your AWS Lambda function so your skill delivers the right content to your customers in each of the supported regions—all from a single code base.

Part 1: Add the New Language Model for Your Skill

1. Navigate to your existing skill on the Amazon Developer Portal.
2. Click on the language drop down on the top right of the screen and select the last option: “Language Settings.” In this example, the skill already has language models for English, Spanish, German and French.

Alexa Blog

3. Follow the steps below to complete the Language Settings screen:

  • Click “+ Add New Language

Alexa Blog

Select “Portuguese (BR)

Alexa Blog

Click on Save at the top of the screen. You will now have Brazilian Portuguese language as an option in the language dropdown menu.

Alexa Blog

4. Now provide the interaction model for the Portuguese (BR) version. You can do this by copying the interaction model from one of the English versions of our skill, and localizing the sample utterances and slot values and synonyms. In this example, we’re starting from English (US). Switch to the English version by clicking on the language dropdown in the skill builder, and choose English (US).

Alexa Blog

5. Click on JSON Editor on the left side bar. This displays the complete interaction model for the skill in JSON format.

Alexa Blog

6. Select and copy all of the JSON in the code window.
7. Switch back to Portuguese (BR) using the language dropdown.
8. Click on JSON Editor again, and paste the JSON into the code window, replacing the existing JSON.
9. Localize all sample utterances, slot values, and slot synonyms.
10. Click on the Save Model button.
11. Click on the Build Model button.

We now have the language model built for Brazilian Portuguese. You now need to translate the invocation name, the sample utterances, the slot values, and the synonyms.

You also must localize the skill metadata, including skill name, description, keywords and the icons, should they contain localized content, such as text or currency symbols. Skills metadata are available in the “Distribution” tab of the Alexa Developer Console.

In a typical development workflow, you will probably build the skill voice interaction model JSON document programmatically, based on different files you have with sample utterances and slot values.

If your interaction model uses any built-in slot types, you may need to make changes to ensure that the types are supported in the locale. See the Slot Type Reference for a list of slot types for each supported locale.

Once you have finished translating your interaction model for Portuguese (BR), you need to customize the responses your skill returns for the different locales that you support. Do this by updating your Lambda function.

Part 2: Update the Lambda Function

Now that your skill is ready to support multiple regions, you may want to update your Lambda function to ensure that your skill provides responses translated or tailored to each supported region.

At least, you need to translate to Brazilian Portuguese the strings the skill is sending to Alexa to render with the voice of Alexa. You can also use this technique to use different strings for different variation of English. For instance, you may want to greet your customers with “G’day” in Australia, “Hello” in Canada and the UK, “Namaste,” in India, "Hi" in the US, “Bonjour” in France, and “Bon matin” in Quebec. You can use any localization library to help you to match strings to locale. In this article I’m using an example I made with the ASK SDK v2 for Node.js, you can replicate

Step 0: Have a basic string localization library or class.

To facilitate localizing your skills, you should use one of the internationalization libraries available for the language of your choosing or write your own. In this example I am using i18next in conjunction with an interceptor. To learn more about how this works, read this post: How to Localize your Alexa Skills

Copied to clipboard
const i18n = require('i18next');
const sprintf = require('i18next-sprintf-postprocessor');

const LocalizationInterceptor = {
  process(handlerInput) {
    // Gets the locale from the request and initializes 
    // i18next.
    const localizationClient = i18n.use(sprintf).init({
      lng: handlerInput.requestEnvelope.request.locale,
      resources: languageStrings,
    });
    // Creates a localize function to support arguments.
    localizationClient.localize = function localize() {
      // gets arguments through and passes them to
      // i18next using sprintf to replace string placeholders
      // with arguments.
      const args = arguments;
      const values = [];
      for (let i = 1; i < args.length; i += 1) {
        values.push(args[i]);
      }
      const value = i18n.t(args[0], {
        returnObjects: true,
        postProcess: 'sprintf',
        sprintf: values,
      });

      // If an array is used then a random value is selected 
      if (Array.isArray(value)) {
        return value[Math.floor(Math.random() * value.length)];
      }
      return value;
    };
    // this gets the request attributes and save the localize function inside 
    // it to be used in a handler by calling requestAttributes.t(STRING_ID, [args...])
    const attributes = handlerInput.attributesManager.getRequestAttributes();
    attributes.t = function translate(...args) {
      return localizationClient.localize(...args);
    };
  },
};

Step 1: Take the strings from a language already supported by your skill.

All my strings follow this structure:

Copied to clipboard
const enData = {
  translation: {
    SKILL_NAME: 'Space Facts',
    GET_FACT_MESSAGE: 'Here\'s your fact: ',
    HELP_MESSAGE: 'You can say tell me a space fact, or, you can say exit... What can I help you with?',
    HELP_REPROMPT: 'What can I help you with?',
    FALLBACK_MESSAGE: 'The Space Facts skill can\'t help you with that.  It can help you discover facts about space if you say tell me a space fact. What can I help you with?',
    FALLBACK_REPROMPT: 'What can I help you with?',
    ERROR_MESSAGE: 'Sorry, an error occurred.',
    STOP_MESSAGE: 'Goodbye!',
    FACTS:
      [
        'A year on Mercury is just 88 days long.',
        'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.',
        'On Mars, the Sun appears about half the size as it does on Earth.',
        'Jupiter has the shortest day of all the planets.',
        'The Sun is an almost perfect sphere.',
      ],
  },
};

I’m taking the English string as a base for my translations. The “enData” object contains all the strings used by my skill in the English language. Our interceptor coupled with i18next supports both single strings and arrays, which can be seen on “FACTS”.

Step 2: Localize the strings for Brazilian Portuguese.

Using the English strings as base, I translated them to Portuguese also changing the object name from “enData” to “ptData” to reflect the new language.

Copied to clipboard
const ptData = {
  translation: {
    SKILL_NAME: 'Fatos Espaciais',
    GET_FACT_MESSAGE: 'Aqui vai: ',
    HELP_MESSAGE: 'Você pode me perguntar por um fato interessante sobre o espaço, ou, fexar a skill. Como posso ajudar?',
    HELP_REPROMPT: 'O que vai ser?',
    FALLBACK_MESSAGE: 'A skill fatos espaciais não tem uma resposta para isso. Ela pode contar informações interessantes sobre o espaço, é só perguntar. Como posso ajudar?',
    FALLBACK_REPROMPT: 'Eu posso contar fatos sobre o espaço. Como posso ajudar?',
    ERROR_MESSAGE: 'Desculpa, algo deu errado.',
    STOP_MESSAGE: 'Tchau!',
    FACTS:
      [
        'Um ano em Mercúrio só dura 88 dias.',
        'Apesar de ser mais distante do sol, Venus é mais quente que Mercúrio.',
        'Visto de marte, o sol parece ser metade to tamanho que nós vemos da terra.',
        'Júpiter tem os dias mais curtos entre os planetas no nosso sistema solar.',
        'O sol é quase uma esfera perfeita.',
      ],
  },
};

Step 3: Add the translated strings object to the list of supported locales.

When initializing the i18next service during step 0 you might have noticed a reference to “languageStrings”. This is the list of supported locales and where to find them. Every language is reference by their locale code, i18next will always search for strings in the most specific match first. If for example you have all your strings available for “en” and only a specific welcome message written for “en-AU”, then requests coming from “en-AU” would receive this single welcome message while every other string would just get served from the “en”-pool.

Copied to clipboard
const languageStrings = {
  'de-DE': deData,
  'en': enData,
  'en-US': enusData,
  'es': esData,
  'es-ES': esesData,
  'pt-BR': ptData
};

Here we added “pt-BR” to the end of our list and referenced the object we just translated.

Step 4: Using the strings in your code

Using our interceptor in combination with the i18next library both showed in step 0 we can easily reference strings by their IDs and automatically answering the skill request with the right locale. The selected Strings will be rendered in the language that matches the locale of the incoming request.

This handler for the "AMAZON.HelpIntent" just uses the "t" function saved in our request atributes referencing the ressource ID.

Copied to clipboard
handle(handlerInput) {
    const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
    return handlerInput.responseBuilder
      .speak(requestAttributes.t('HELP_MESSAGE'))
      .reprompt(requestAttributes.t('HELP_REPROMPT'))
      .getResponse();
  }

That’s all that it takes to update your skill for Brazilian customers. We are excited to have Alexa available in Brazilian Portuguese soon, and we can't wait to see what you will build. This space facts skill localized to Portuguese (BR) is available for everyone to try out.

portuguese console image

Check out our documentation to learn more about how you can use ASK to create multi-language Alexa skills.

Get Started

Check out the following training resources, tutorials, and code samples to start building Alexa skills:

Resources