Support Multiple Locales with the Alexa Conversations Description Language (Beta)
You can use the Alexa Conversations Description Language (ACDL) to create skills for multiple locales. A locale is the combination of a language and a location. For example, en-IN
is a locale that represents the English language spoken in India.
Your skill can support a single locale or any combination of the following locales that ACDL supports.
- English (AU) (
en-AU
) - English (CA) (
en-CA
) - English (IN) (
en-IN
) - English (UK) (
en-GB
) - English (US) (
en-US
) - German (DE) (
de-DE
) - Japanese (JP) (
ja-JP
) - Spanish (US) (
es-US
) - Spanish (ES) (
es-ES
)
Localization is optional. ACDL considers expressions that you don't explicitly annotate by the methods described on this page as global (that is, they apply to all locales). Therefore, if you already developed a non-localized skill with ACDL, you can continue to compile and deploy the skill without modification.
Prerequisites
Before you localize your skill, you must meet the following prerequisites.
-
Latest version of
askx
– Even if you already have a version of the Alexa Skills Kit Command-Line Interface (ASK CLI) that supports Alexa Conversation (askx
), you must install the latest version ofaskx
. For details about how to install the ASK CLI, see Set up the ASK CLI to Use the Alexa Conversations Description Language. You don't need to uninstall the previous version ofaskx
first. -
Alexa Conversations skill on the command line –You must already have an Alexa Conversations skill that you can work with on the command line. To create one, see Tutorial: Create an Alexa Conversations Skill with the ACDL or Tutorial: Convert an Alexa Conversations Skill to Alexa Conversations Description Language.
Steps to localize your skill
Complete the following steps to add locales to an existing skill:
- Add all supported locales to the skill manifest.
- Add an interaction model file for each locale.
- Use the
@locale()
annotation. - Specify locales in the skill entry point.
Step 1: Add all supported locales to the skill manifest
As with any Alexa skill, your skill manifest must include publishing information for each supported locale. This publishing information contains the skill name, description, example phrases, and so on.
To specify the publishing information
- Include an object for each supported locale in the
publishingInformation.locales
object of the skill manifest.
For details, see locales in the skill manifest documentation.
The following example skill manifest supports en-US
and en-GB
.
Step 2: Add an interaction model file for each locale
Your skill must also have an interaction model file for each locale that your skill supports.
To add interaction model files
- Navigate to the
<skill directory>/skill-package/conversations/interactionModels/custom
directory. - Create an interaction model file for each locale, using the locale name as the file name (for example,
en-US.json
,en-in.json
, and so on). - Specify the invocation name for your skill in each of the interaction model files.
For details about how to choose an invocation name, see Choose the Invocation Name for a Custom Skill. You can use the same invocation name for different locales.
The following examples show interaction model files for en-US
and en-GB
.
Step 3: Use the @locale() annotation
To localize your Alexa Conversations skill assets, you apply the @locale()
annotation to your utterance sets, responses, dialogs, and samples. For utterance sets and responses, you then group the localized assets together by using the variations()
action. As mentioned previously, if you don't apply the locale@
annotation to an expression, the expression applies to all locales.
The @locale()
annotation takes a locale as a parameter, which you specify by using a property of the Locale
enum. The Locale
enum can be one of the following values.
enum Locale {
en_AU // English (AU)
en_CA // English (CA)
en_IN // English (IN)
en_GB // English (UK)
es_US // English (US)
de_DE // German (DE)
}
For example, you specify the en-US
locale by using Locale.en_US
.
The following procedures show you how to apply the @locale()
annotation to a set of utterances, a set of responses, dialogs, and samples.
To localize a set of utterances
- Put the
@locale()
annotation before the utterance event declaration for each locale.
The utterance event declaration action isutterances<T>()
. - Use the
variations()
action to group all the corresponding utterance sets together into one locale-agnostic utterance set that you use as the argument to theexpect()
action when you declare an event.
To localize a set of responses
- Put the
@locale()
annotation before theapl<T>()
andapla<T>()
actions to indicate the path of the APL/APLA response files for a particular locale. - Use the
variations()
action to group all the corresponding responses together into one locale-agnostic response that you use wherever you specify a response.
Skill-level responses are in theskill()
declaration (see Step 4), and other responses are arguments to theresponse()
action within dialogs.
Dialogs contain the conversational flow.
To localize dialogs and samples
- To specify that a dialog applies to one or more locales, precede the dialog with the
@locale()
annotation. - Similarly, apply the
locale@
annotation to individual samples within the dialog.
Tip: For many skills, you can use the same dialog and samples for all locales, because the conversational flow of the skill is the same. In that case, you can omit the@locale()
annotation for the dialogs and samples if you choose.
Step 4: Specify locales in the skill entry point
You must specify the locales where you plan to deploy the skill.
To specify locales in the skill entry point
- Use the
locales
parameter of theskill()
action.
Theskill()
action is the skill entry point.
Complete example
The following example shows the ACDL for a localized skill.
namespace com.weatherbot
import com.amazon.alexa.ask.conversations.*
import com.amazon.ask.types.builtins.AMAZON.*
import slotTypes.*
type CityAndDate {
optional CityName cityName
optional DATE date
}
type WeatherResult {
CityName cityName
NUMBER highTemp
NUMBER lowTemp
}
type ResponsePayload {
WeatherResult weatherResult
}
@locale(Locale.en_GB)
getWeatherEventGB = utterances<CityAndDate>(
[
"What's the weather {date} in {cityName} in Great Britain",
"what is the weather {date} in Great Britain",
"How is the weather in {cityName} in Great Britain",
"How is weather in {cityName} {date} in Great Britain",
"how is weather in Great Britain",
"can you please give me weather report for {date} in Great Britain"
]
)
@locale(Locale.en_US, Locale.en_CA)
getWeatherEventNA = utterances<CityAndDate>(
[
"What's the weather {date} in {cityName} in North America",
"what is the weather {date} in North America",
"How is the weather in {cityName} in North America",
"How is weather in {cityName} {date} in North America",
"how is weather in North America",
"can you please give me weather report for {date} in North America"
]
)
getWeatherEvent = variations(getWeatherEventGB, getWeatherEventNA)
// Because the current folder path is skill-package/conversations/
@locale(Locale.en_US, Locale.en_CA)
request_city_NA = apla<CityName>("../../lib/prompts/en/request_city_apla_NA")
@locale(Locale.en_GB)
request_city_GB = apla<CityName>("../../lib/prompts/en/request_city_apla_GB")
request_city = variations(request_city_NA, request_city_GB)
// Nested variations() action
@locale(Locale.en_US)
request_date_en_US = apla<DATE>("../../lib/prompts/en/request_date_apla/document.json")
@locale(Locale.en_CA)
request_date_en_CA = apla<DATE>("../../lib/prompts/en/request_date_apla/document.json")
request_date_NA = variations(request_date_en_US, request_date_en_CA)
@locale(Locale.en_GB)
request_date_GB = apla<DATE>("../../lib/prompts/en/request_date_apla/document.json")
request_date = variations(request_date_NA, request_date_GB)
@locale(Locale.en_US, Locale.en_CA)
request_city_date_NA = apla<CityAndDate>("../../lib/prompts/en/request_city_date_apla_NA/document.json")
@locale(Locale.en_GB)
request_city_date_GB = apla<CityAndDate>("../../lib/prompts/en/request_city_date_apla_GB/document.json")
request_city_date = variations(request_city_date_NA, request_city_date_GB)
@locale(Locale.en_US, Locale.en_CA)
weather_prompt_NA = apla<ResponsePayload>("../../lib/prompts/en/weather_apla_NA/document.json")
@locale(Locale.en_GB)
weather_prompt_GB = apla<ResponsePayload>("../../lib/prompts/en/weather_apla_GB/document.json")
weather_prompt = variations(weather_prompt_NA, weather_prompt_GB)
// ================= Skill-level responses ==================
@locale(Locale.en_GB)
myWelcomeGB = apla("../../lib/prompts/en/Welcome_GB")
@locale(Locale.en_US, Locale.en_CA)
myWelcomeNA = apla("../../lib/prompts/en/Welcome_NA")
myWelcome = variations(myWelcomeGB, myWelcomeNA)
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
out_of_domain = apla("../../lib/prompts/en/OutOfDomain")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
bye = apla("../../lib/prompts/en/Bye")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
reqmore = apla("../../lib/prompts/en/RequestMore")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
provide_help = apla("../../lib/prompts/en/ProvideHelp")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
thank_you = apla("../../lib/prompts/en/ThankYou")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
you_are_welcome = apla("../../lib/prompts/en/YouAreWelcome")
@locale(Locale.en_US, Locale.en_GB, Locale.en_CA)
notify_failure = apla("../../lib/prompts/en/NotifyFailure")
skillLevelResponses = SkillLevelResponses
{
welcome = myWelcome,
out_of_domain = out_of_domain,
bye = bye,
reqmore = reqmore,
provide_help = provide_help,
thank_you = thank_you,
you_are_welcome = you_are_welcome,
notify_failure = notify_failure
}
// The skill will be deployed to en-US and en-GB
mySkill = skill(
locales = [Locale.en_US, Locale.en_GB],
skillLevelResponses = skillLevelResponses
)
action WeatherResult getWeather(CityName cityName, DATE date)
@locale(Locale.en_US, Locale.en_GB)
dialog void Weather {
sample {
weatherRequest = expect(Invoke, getWeatherEvent)
ensure(
RequestArguments {arguments = [getWeather.arguments.cityName], response = request_city},
RequestArguments {arguments = [getWeather.arguments.date], response = request_date},
RequestArguments {arguments = [getWeather.arguments.cityName, getWeather.arguments.date], response = request_city_date}
)
weatherResult = getWeather(weatherRequest.cityName, weatherRequest.date)
response(weather_prompt, Notify {actionName = getWeather}, payload = ResponsePayload {weatherResult = weatherResult})
}
}
Related topics
- About Alexa Conversations Description Language (ACDL)
- Actions in the Alexa Conversations Core Library
- Types in the Alexa Conversations Core Library
Last updated: Nov 27, 2023