Use Responses in the Alexa Conversations Description Language

In the Alexa Conversations Description Language (ACDL), responses are actions that render text, audio, or visual content to the user. Responses include any necessary arguments and a response act that indicates the situation that triggers the response.

Overview

You use the response<T>() action from the Alexa Conversations Core Library (ACCL) to describe, in a dialog sample, how the skill should respond. The response<T>() action has the following signature.

action Nothing response(Response response, ResponseAct act, ResponseAct nextAct = nothing, Thing payload = nothing)

As shown in the signature, the response<T>() action brings together the following parameters:

  • The Response<T> is the text, audio, or visual content to render to the user.
  • The ResponseAct is the purpose of the response. You can chain response acts by specifying both an act and a nextAct.
  • The payload contains any arguments passed to the rendered response.

Therefore, to use responses in ACDL, you take the following steps:

  1. Decide on the purpose of the response.
  2. Create APL/APLA files.
  3. Call the response<T>() action from a dialog.

Some examples on this page reference the following actions.

action SearchFlightResult searchFlights(City fromCity, City toCity, Date startDate, Date returnDate = nothing)
action BookFlightResult bookFlight(SearchFlightResult searchResult)

Decide on the purpose of the response

Each response has a purpose. In ACDL, this purpose is called the response act. For example, the Notify response act signifies that the response is an outcome of an action ("In Seattle, it's 65 degrees.") The Request response act signifies that the response is asking the user for information that an action requires "What city?"), and so on.

The following list shows the available response acts:

  • Bye ("Thanks for using Weather Bot. Goodbye.")
  • ConfirmAction ("You'd like to know the weather for Seattle, right?")
  • ConfirmArgs ("That was for Seattle?")
  • Notify ("The weather in Seattle is 65 degrees.")
  • Offer ("Would you like the hour-by-hour forecast?")
  • ReqAlt ("Would you like to know the weather for a different city?")
  • ReqMore ("Is there anything else I can do for you?")
  • Request ("Which city?")

Create APLA and APL files

To specify the content (Response) that Alexa renders to the user, you use the following items:

  • Speech – You render speech as APL for Audio (APLA) JSON files. These files are imported from the <skill-directory>/skill-package/response/prompts/ folder in the skill package. For details, see Response Prompt Files for Alexa Conversations.

    Alexa Conversations automatically creates APLA expressions in the prompts namespace from the APLA files of the skill package. The folder name of the APLA document becomes the name of the APLA expression, such as in the following example.
    // folder: weatherSkill/skill-package/response/prompts
    WeatherResponseAplaPrompt/document.json
    // In ACDL
    namespace org.example.weather
    import prompts.WeatherResponseAplaPrompt
    
  • Visual content – For Alexa devices with a screen, you specify visual content as Alexa Presentation Language (APL) JSON files. These files are imported from the <skill-directory>/skill-package/response/displays/ folder in the skill package. For details about APL, see Understand Alexa Presentation Language (APL).

    Alexa Conversations automatically creates APLA expressions in the displays namespace from the APLA files of the skill package. The folder name of the APLA document becomes the name of the APLA expression, such as in the following example.
    // folder: weatherSkill/skill-package/response/displays
    WeatherResponseAplPrompt/document.json
    // In ACDL
    namespace org.example.weather
    import displays.WeatherResponseAplPrompt
    
  • Multimodal – You can specify both speech (APLA) and visual (APL) content in the same response. To do so, you create a multimodal response from existing APL and APLA expressions, as shown in the following example.
    namespace org.example.weather
    import prompts.WeatherDisplay
    import prompts.WeatherAudio
    WeatherResponsePrompt = MultiModalResponse {
    apl = WeatherDisplay
    apla = WeatherAudio
    }
    dialog Nothing WeatherDialog() {
    sample {
      ...
      response(WeatherResponsePrompt, ...)
      ...
    }
    }
    

Examples of using responses

The following example shows how to import and use a toAndFromCityPrompt in a response.

import prompts.toAndFromCityPrompt

dialog BookFlights {
  sample {
    ...
    // toAndFromCityPrompt is imported above
    response(response = toAndFromCityPrompt, act = Request {arguments = [searchFlights.arguments.fromCity, searchFlights.arguments.toCity]})
        ...
  }
}

The following example shows how to use a MultiModalResponse response type, which combines an APLA prompt and an APL prompt.

import prompts.cityNamePrompt
import displays.cityNameAplPrompt

dialog BookFlights {
  sample {
    ...
    // Declare a name with type MultiModalResponse to use in the response<T>() action.
    multiModalCityNamePrompt = MultiModalResponse { apla = cityNamePrompt, apl = cityNameAplPrompt }
    response(response = multiModalCityNamePrompt, act = Request {arguments = [searchFlights.arguments.fromCity, searchFlights.arguments.toCity]})
    ...
  }
}

Access arguments in a response

APLA and APL documents uses the payload parameter of the response<T>() action to access arguments that the dialog samples provide. For example, to access arguments called fromCity and toCity, an APLA document might use the following line: "content": "Just to confirm, you want to book a flight from ${payload.fromCity} to ${payload.toCity}?"

Call the response() action

After you know the response act and have APL/APLA templates, call the response<T>() action from a dialog.

action Nothing response(Response response, ResponseAct act, ResponseAct nextAct = nothing, Thing payload = nothing)

The following example dialog results in a response that renders the weather to the user.

namespace com.weatherbot

import com.weatherbot.artifacts.getWeather
import org.weatherbot.artifacts.getWeatherEvent
import prompts.request_city_prompt // Imports the responses that the response<T>() action uses
import prompts.request_date_prompt
import prompts.weather_prompt

dialog Weather {
  sample {
    // An event that uses the getWeatherEvent samples that specify both the city and the date
    weatherEvent = expect(Invoke, getWeatherEvent)

    // Ensure that the user provided all the required arguments
    ensure(
      {arguments = [getWeather.arguments.cityName], response = request_city_prompt},
      {arguments = [getWeather.arguments.date], response = request_date_prompt}
    )

    // An action to get the weather information.
    weatherResult = getWeather(weatherEvent.cityName, weatherEvent.date)

    // Alexa's action to respond to the user with the result (weather information) from the previous action
    response(weather_prompt, Notify {actionName = getWeather, success = true}, payload = {weatherResult = weatherResult})
  }
}

You can use the act argument without explicitly naming it as an argument as shown in the following example.

// The following two lines are equivalent; the first is explicitly naming the arguments

response(response = multiModalCityNamePrompt, act = Request {arguments = [searchFlights.arguments.fromCity, searchFlights.arguments.toCity]})

response(multiModalCityNamePrompt, Request {arguments = [searchFlights.arguments.fromCity, searchFlights.arguments.toCity]})

You use the nextAct argument to chain response acts together, as described next.

Chain response acts

A single Alexa response can include multiple response acts. For example, in "Successfully booked departing flight, do you want to book a return ticket?" the skill responds with some information about the action it performed and then offers the user a possible follow-up action.

To represent chained response acts, you specify multiple responses using the response<T>() action. For alternatives to chaining, see Alternatives to chained response acts.

Alexa Conversations supports the following response act chains:

Notify and Offer

This sequence informs the user of the result of the current action and offers the next action.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // "Your flight from Seattle to Portland on July 31st has been booked. Would you like to book a hotel?"
  response(flightPrompt, Notify {actionName = searchFlights}, Offer {actionName = bookHotel})
}

Notify and ReqAlt

This sequence informs the user that Alexa was unable to fulfill the goal with the provided arguments. It requests alternative values for the arguments to continue the goal.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // "There are no flights from Seattle to Portland on July 31st. Would you like to book a flight for another date?"
  response(flightPrompt, Notify {actionName = searchFlights, success = false}, ReqAlt {arguments = [searchFlights.arguments.startDate]})
}

Notify and ReqMore

This sequence informs the user of the result of the current action and requests another goal.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // "Your flight from Seattle to Portland on July 31st has been booked. Anything else I can do?"
  response(flightPrompt, Notify {actionName = searchFlights}, ReqMore{})
}

Notify and Bye

This sequence informs the user of the result of the current action and ends the conversation.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // "Your flight from Seattle to Portland on July 31st has been booked. Have a nice day!
  response(flightPrompt, Notify {actionName = searchFlights}, Bye{})
}

Alternatives to chained response acts

If you can break a prompt into separate pieces, you can write consecutive response<T>() actions instead of using chained response acts. In this case, each response<T>() action has its corresponding response acts. The following two representations are semantically equivalent.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // Your flight from Seattle to Portland on July 31st has been booked. Would you like to book a hotel?
  response(flightPrompt, Notify {actionName = searchFlights}, Offer {actionName = bookHotel}, payload = SearchPayload {result = searchFlightResult})
}

You can break the response<T>() call in the previous example into two responses with the Notify and Offer response acts, as in the following example.

sample {
  bookFlightRequest = expect(Invoke, bookFlightEvent)
  searchFlightResult = searchFlights(bookFlightRequest.fromCity, bookFlightRequest.toCity, bookFlightRequest.startDate)

  // Your flight from Seattle to Portland on July 31st has been booked.
  response(flightPrompt, Notify {actionName = searchFlights}, payload = SearchPayload {result = searchFlightResult})
  // Would you like to book a hotel?
  response(flightPrompt, Offer {actionName = bookHotel})
}

Access action arguments

In ACDL, all declarations are represented as data structures. The same is true for action declarations. The following types represent the declaration of an action. This means that you can refer to the description of an action. For example, you can refer to an argument.

Action {
  Arguments arguments
  Type returnType
}

type Arguments {}

type Argument {
  Type argumentType
  Boolean isOptional
}

You can access the arguments of the action through the arguments field.

To reference the action arguments when using response acts that take in a List of type Argument, such as the Request response act, use the arguments field accessor. For example, the previous example accesses the uses the startDate argument by using following line.

response(response = datePrompt, act = Request {arguments = searchFlights.arguments.startDate]})

Because searchFlights is an action, it has a field named arguments that enables you to access its arguments.

Reuse prompts

You can reuse prompts for multiple response<T>() actions. In the following example, the arguments fromCity and toCity are of the same type. Asking the user "Which city?" applies to both responses, so you can use cityPrompt for both response<T>() actions.

sample {
  response(response = cityPrompt, act = Request {arguments = [searchFlights.arguments.fromCity]})
  ...
  response(response = cityPrompt, act = Request {arguments = [searchFlights.arguments.toCity]})
}