3

I am trying to implement AMAZON.HelpIntent for my Alexa Skill.

This is the intended behavior:

User: Alexa, tell Volume Calculator to calculate the volume of a box.

Alexa: What is the length of the box?

User: Help

Alexa: The length of a box is how long the box is. Try saying the length is two or the length is two meters.

Prompt User Response

User: The length is two meters.

Alexa: What is the width of the box?

Conversation continues until the slots of the intent are filled.

To achieve this behavior I need to know which intent my user is in. This line of code allows me to do that.

session.attributes['last_intent'] = 'BoxVolumeIntent'

I can check inside my AMAZON.HelpIntent if 'last_intent' == 'BoxVolumeIntent'

if session.attributes.get('last_intent') == 'BoxVolumeIntent':
    # Determine which part of the multi-turn dialog I am in and return
    # relevant help to the user here. Then pass the value back to the 
    # correct intent to be processed. This is what I don't know how to 
    # do.

The session.attributes is defined in flask-ask by John Wheeler.

It can be accessed in Python with the following line:

from flask_ask import session

I asked John, in an email, earlier today if he knew how to solve my problem, and his response was that he hasn't worked on flask-ask for a while and he didn't know what a multi-turn dialog was.

How can I implement the AMAZON.HelpIntent correctly for my skill?

BoxVolumeIntent

@ask.intent("BoxVolumeIntent", convert={'length': int, 'width': int, 'height': int, 'unit': str},
            default={'unit': 'meters'})
def calculate_box_volume(length, width, height, unit):
    """
    Description:
        A function to calculate the volume of a box.
    Args:
        :param1 (int) length: The length of the box.
        :param2 (int) width:  The width of the box.
        :param3 (int) height: The height of the box.
        :param4 (str) unit: The unit of measurement. If unit is undefined its value defaults to 'meters'.
    :return: A statement to be spoken by the Alexa device and a card sent to the Amazon Alexa phone app.
    """
    # Determine which intent was the last one called.
    session.attributes['last_intent'] = 'BoxVolumeIntent'
    
    # Taken from Issue 72. Solves the problem of returning a Dialog.Directive
    dialog_state = get_dialog_state()
    if dialog_state != "COMPLETED":
        return delegate(speech=None)

    box_volume = length * width * height
    msg = "The volume of the box is {} cubic {}".format(box_volume, unit)
    return statement(msg).simple_card("Volume Calculator", msg)

I have included the BoxVolumeIntent from my Python 3 Backend. Notice how I do not have the strings for Alexa to ask the user what the length, width, and height are. All of this is handled in the Skill Builder BETA which can be found on the Amazon Developer Console. I am not able to tell which step of the intent my user is on.

Because as I mentioned in a comment below, the user could start on any of the steps. For example: The width of the box is five. That is typically step 2 not step 1 of the multi-step intent.

Community
  • 1
  • 1
Bradley Marques
  • 129
  • 1
  • 16
  • What exactly is not working for you? Because you have described the solution how to do that. Yes you can use `session.attributes` to keep the state. You can keep as many states (using different keys) as you want. – ck3g Jan 09 '18 at 08:41
  • I am not sure how to tell where I am in the multi-turn dialog. I can tell which intent was the last one that was called, but for intents that require multiple pieces of input I need to know what step my user is on so I can provide relevant help to them. – Bradley Marques Jan 10 '18 at 17:16

1 Answers1

0

I found that question somehow similar to this one.

You can you session.attributes for any different reasons, and you keep there your own values.

In your case you can introduce session.attributes['current_step'] = <number> and use it to define the current step of that multi-step intent.

if session.attributes.get('last_intent') == 'BoxVolumeIntent':
  if session.attributes.get('current_step') == 1:
    # Do stuff for the first step
    # Optional: increase the current step value
ck3g
  • 5,829
  • 3
  • 32
  • 52
  • I would like some more information. Where would I originally set the current_step value to one. Because with the way my code is structured I cannot tell which step was invoked first. Such is the way of multi-turn dialogs. The user could start the intent by saying: The width of the box is five. Typically that would be the second step and not the first. I figure I would have to set it somewhere in the BoxVolumeIntent. – Bradley Marques Jan 13 '18 at 02:33
  • You can set the initial value in the `LaunchRequest` handler. https://developer.amazon.com/docs/custom-skills/handle-requests-sent-by-alexa.html#launchrequest – ck3g Jan 14 '18 at 10:36
  • If your steps do not have the specific order. Then you need to use different intents to capture different responses. – ck3g Jan 14 '18 at 10:38