Kev
Kev

Reputation: 577

How do I delegate an intent to Alexa using Python and the ask-sdk (intent chaining)?

In my Alexa-Skill I ask the user a Yes/No Question (Whether he likes to hear the news or not) - in the yes-part I would like to start the NewsIntent as if the user had invoced it manually.

The idea behind it came from Justin Jeffress: https://developer.amazon.com/de/blogs/alexa/post/9ffdbddb-948a-4eff-8408-7e210282ed38/intent-chaining-for-alexa-skill

handler_input.response_builder.add_directive(DelegateDirective('NewsIntent')).speak(speech_text)
return handler_input.response_builder.response

When I test it in the developer console I receive the speach_text but then I'm informed that an error occured.

This is the JSON-output of it:

{
    "body": {
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "SSML",
                "ssml": "<speak>My pleasure!</speak>"
            },
            "directives": [
                {
                    "type": "Dialog.Delegate",
                    "updatedIntent": {
                        "name": "NewsIntent",
                        "confirmationStatus": "NONE",
                        "slots": {}
                    }
                }
            ],
            "type": "_DEFAULT_RESPONSE"
        },
        "sessionAttributes": {
            "IntentOrigin": null
        },
        "userAgent": "ask-python/1.13.0 Python/3.6.9 ask-webservice django-ask-sdk ask-webservice django-ask-sdk"
    }
}

Has anybody any idea how to solve this? Python does not throw any exception in that case. (It is running under Django)

Thank you!

Upvotes: 2

Views: 1282

Answers (2)

Cslim
Cslim

Reputation: 513

I don't know if this will be useful for you or not. I unfortunately could not use your solution because it did not reset/launch the required slot questions needed by the intent. It would simply keep the stored values from the last time it was fired.

For your case, I would make sure that you set a session attribute within your NewsIntent like so:

def handle(self, handler_input):
        attribute_manager = handler_input.attributes_manager
        session_attr = attribute_manager.session_attributes
        
        # Your logic for your intent here
        
        session_attr['news'] = 'some string or value'
        speak_output = "I found some news! Would you like to find more?"
        return (handler_input.response_builder.speak(speak_output).response)

You need to add the AMAZON.YesIntent intent in your builder UI.

You need a class that will define how to handle the AMAZON.YesIntent when it fires. For this example, I've named that class MoreNewsIntentHandler. Add this to the bottom of your code:

sb.add_request_handler(MoreNewsIntentHandler())

Then finally, create the class with the intended action when the AMAZON.YesIntent fires.

from ask_sdk_model.intent import Intent
from ask_sdk_model.dialog import delegate_directive

class MoreNewsIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        attribute_manager = handler_input.attributes_manager
        session_attr = attribute_manager.session_attributes
        return (is_intent_name("AMAZON.YesIntent")(handler_input) and "news" in session_attr)
    
    def handle(self, handler_input):
        attribute_manager = handler_input.attributes_manager
        session_attr = attribute_manager.session_attributes
        if "news" in session_attr:
            speak_output = "Ok. Let's get some more news"
            intent_name = "NewsIntent"
        return handler_input.response_builder.speak(speak_output).add_directive(delegate_directive.DelegateDirective(updated_intent=Intent(name=intent_name))).response 


With this, I plan to use session attributes to output different statements and identify the correct intent that needs to be fired based on the session attributes. I plan to continue tinkering with the session attributes to make sure that I can handle custom AMAZON.YesIntent actions through them. I'll post an edited update if I find out more.

Upvotes: 4

Kev
Kev

Reputation: 577

Finally I found the answer:

return NewsIntentHandler.handle(self, handler_input)

Upvotes: 3

Related Questions