0

So my Alexa skill asks for an invoice amount.

The user is supposed to say "My invoice is for one hundred dollars."

My sample utterance is "my invoice is for {invoiceAmount} dollars" where {invoiceAmount} is an Amazon.NUMBER slot

If the user says a number everything works fine. However, if they don't then the code blows up and Alexa exits my skill. For example, if a user says "My invoice is for baseball dollars."

Here is my code that handles this intent:

def set_amount_in_session(intent, session):
    card_title = "Set Invoice Amount"
    should_end_session = False

    if 'invoiceAmount' in intent['slots']:
        if intent['slots']['invoiceAmount']['value'] is not None:
            invoice_amount = intent['slots']['invoiceAmount']['value']
            try:
                val = int(invoice_amount)
            except ValueError:
                val = 0
            if val != 0:
                session['attributes']['invoiceAmount'] = int(invoice_amount)
                speech_output = "The invoice amount is " + str(invoice_amount) + " dollars. "
                card_output =   "Invoice Amount $" + str(invoice_amount)
                reprompt_text = "Please tell me the terms of the invoice."
            else:
                speech_output = "I'm not sure what the invoice amount is. " \
                                "Please try again."
                card_output =   "I'm not sure what the invoice amount is. " \
                                "Please try again."
                reprompt_text = "I'm not sure what the invoice amount is. " \
                                "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                                "my invoice is for one hundred and fifty dollars."
        else:
            speech_output = "I'm not sure what the invoice amount is. " \
                            "Please try again."
            card_output =   "I'm not sure what the invoice amount is. " \
                            "Please try again."
            reprompt_text = "I'm not sure what the invoice amount is. " \
                            "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                            "my invoice is for one hundred and fifty dollars."
    else:
        speech_output = "I'm not sure what the invoice amount is. " \
                        "Please try again."
        card_output =   "I'm not sure what the invoice amount is. " \
                        "Please try again."
        reprompt_text = "I'm not sure what the invoice amount is. " \
                        "Please tell me the amount of the invoice you wish to factor by saying, for example, " \
                        "my invoice is for one hundred and fifty dollars."
    return build_response(session['attributes'], build_speechlet_response(
        card_title, speech_output, card_output, reprompt_text, should_end_session))

This code works perfectly fine when I test it in the Amazon Developer Console, but it fails on my Echo Dot.

If I say "My invoice is for one hundred baseball dollars" it is able to handle the response and say it isn't sure what the invoice amount is.

If I say "My invoice is for baseball one hundred dollars" it actually ignores the "baseball" and sets the invoice amount to $100, which I'm fine with.

However, if I say "My invoice is for baseball dollars" it fails and says "There was a problem with the requested skills response" and it closes the skill.

Ben Tolsky
  • 39
  • 1
  • 1
  • 13
  • I just saw a similar problem on this post: https://stackoverflow.com/questions/42721603/alexa-custom-slot-type-no-value-in-intent?rq=1 However, the answer is given in javascript. How do I do this in Python? I am brand new to Python so I really don't know how to do this. – Ben Tolsky Aug 04 '17 at 19:08
  • Hey Ben, this looks like you are handling the edge cases properly. Can you try opening CloudWatch in the services dropdown inside AWS and check the Logs for your lambda to narrow down where the error may be? – Josep Valls Aug 07 '17 at 20:59
  • @JosepValls I've opened up CloudWatch but I don't know how to read these logs, what exactly should I be looking for? Thanks – Ben Tolsky Aug 07 '17 at 21:40
  • @JosepValls I figured out how to read CloudWatch, or at least enough of it to find where the error is. It turns out that my error was with not having a value, I will post an answer below. Thank you for pointing me in the right direction – Ben Tolsky Aug 08 '17 at 15:10

1 Answers1

0

So I figured it out.

When I say "my invoice is for one hundred dollars" I get:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.386d4fe9-dc04-4376-8e30-dec3205484fe",
  "locale": "en-US",
  "timestamp": "2017-08-08T14:59:43Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount",
        "value": "100"
      }
    }
  }
}

This of course is valid value so it is handled correctly.

When I say "my invoice is for one hundred baseball dollars" I get:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.c1b4a1d0-4949-4247-b326-a582ce4826b4",
  "locale": "en-US",
  "timestamp": "2017-08-08T15:01:09Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount",
        "value": "?"
      }
    }
  }
}

I'm not sure if this value is null or if it is just not an integer, but since I check for both scenarios, it is not an issue

The issue is that when I say "my invoice is for baseball dollars", the invoiceAmoutn slot has no value:

"request": {
  "type": "IntentRequest",
  "requestId": "EdwRequestId.a046d29b-581c-484a-8879-abe979ec6286",
  "locale": "en-US",
  "timestamp": "2017-08-08T14:51:36Z",
  "intent": {
    "name": "WhatIsInvoiceAmount",
    "slots": {
      "invoiceAmount": {
        "name": "invoiceAmount"
      }
    }
  }
}

Apparently, not having a "value" is different than having a "value" that is null. So I had to add one more check to my code to see if there is a value in the first place. So here is my new code that now also checks to see if there is a value:

if 'invoiceAmount' in intent['slots']:
    if 'value' in intent['slots']['invoiceAmount']:
        if intent['slots']['invoiceAmount']['value'] is not None:
            invoice_amount = intent['slots']['invoiceAmount']['value']
            try:
                val = int(invoice_amount)
            except ValueError:
                val = 0
            if val != 0:
                NOW I HAVE A VALID VALUE AND CAN EXECUTE MY CODE

With this change I seemed to have solved my problem.

Ben Tolsky
  • 39
  • 1
  • 1
  • 13