0
votes

I'm a complete beginner on the Alexa development console. I use Python SDK to create an app which matches food and wine. My code is working but I still have to launch the app (with a LaunchRequest) and then ask the question about a match between food and wine.

I would like to give the possibility to the user to directly ask its question: "Alexa, ask Winy Bot which wine match with a ....".

However I don't know how to do that. I don't know if I have to create a new LaunchRequest or if it's possible to launch an IntentRequest directly.

Here is my code, do you think you could help me ?

class LaunchRequestHandler(AbstractRequestHandler):

    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool

        return ask_utils.is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        speak_output = "Bonjour, je suis là pour vous aider. Demandez-moi des informations sur un vin ou sur une association plat / vin. Vous pouvez simplement me donner le nom d'un plat ou d'un vin et je m'occupe du reste.";
        reprompt_text = "Vous pouvez par exemple essayer de me demander des informations sur le Chablis.";

        return (
            handler_input.response_builder
                .speak(speak_output)
                .ask(reprompt_text)
                .response
        )

class CapturePlatIntentHandler(AbstractRequestHandler):

    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return ask_utils.is_intent_name("CapturePlatIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        slots = handler_input.request_envelope.request.intent.slots
        plat = slots["plat"].value

        attributes_manager = handler_input.attributes_manager

        plat_attributes = {
            "plat": plat
        }

        attributes_manager.persistent_attributes = plat_attributes
        attributes_manager.save_persistent_attributes()

        speak_output = correspondance(plat);
        reprompt = "Si vous le souhaitez, vous pouvez me demander des informations sur un de ces vins en disant simplement son nom."

        return (
            handler_input.response_builder
                .speak(speak_output)
                .ask(reprompt)
                .response
        )
3

3 Answers

1
votes

I'm not a python expert but your code looks good to me. You don't need to create an additional intent for your use case. There are three ways a user can invoke your skill, see documentation:

  • By saying the skill's name, triggering the LaunchIntent
    • "Alexa, launch Wine Bot"
  • By saying the skill's name and an intent, triggering the specific intent (or FallbackIntent if implemented)
    • "Alexa, ask Winy Bot which wine match with a ...."
  • By using name free invocation

Therefore, you just need to make sure that

  1. Your intent has the correct sample utterances
  2. That you either elicit the required slot (for example via auto delegation) or handle the case if the slot is not set
0
votes

Thank you for your answer. Unfortunately it still doesn't work for me.

In my case, in my sample utterances, I have "which wine matches with a {plate}". If I launch the app by saying, "Alexa, asks Winy Bot which wine matches with a ..." it doesn't work and I don't understand why.

If I launch the App with the LaunchRequest and then I ask "Which wine matches with a ...", the IntentRequest works well.

Do you think I have something to change with my code ? Or is it something about the Intents ?

0
votes

I added a try/except clause. Not the best approach, but unblocked me for now. Here's an example of how I did it based on the Fact skill template, which has a combined helper for both LaunchRequest and GetNewFactIntent.

class GetNewFactHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return (is_request_type("LaunchRequest")(handler_input) or
                is_intent_name("GetNewFactIntent")(handler_input))

    def handle(self, handler_input):
        try:
            speech = handler_input.request_envelope.request.intent.slots["my_slot"].value
            
            print("Is not a LaunchRequest. Has intent attribute.")
            
            handler_input.response_builder.speak(speech)
            return handler_input.response_builder.response
        except AttributeError as ex:
            print("Is a LaunchRequest. No intent attribute.")
            
            handler_input.response_builder.speak("Welcome to my app!")
            return handler_input.response_builder.response

Updated: Added specific exception catch instead of catch-all per @kate-melnykova's suggestion.