Search code examples
alexa-skills-kit

Make Alexa speak before executing action with Python SDK


The use case is pretty similar to things that are working already out there. I want Alexa to say something and then execute an action. For example, with the Spotify integration I can ask Alexa to play a playlist:

  • Alexa play rock playlist
  • Alexa says "I will play the rock classics playlist in spotify"
  • Alexa proceeds to play the playlist.

Notice that Alexa spoke BEFORE actually sending the command to the Spotify API asking to play the playlist. So my question is, how can I achieve the same behavior with the python SDK?

class GetNewFactHandler(AbstractRequestHandler):
    """Handler for Skill Launch and GetNewFact Intent."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return (is_request_type("LaunchRequest")(handler_input) or
                is_intent_name("GetNewFactIntent")(handler_input))
    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        logger.info("In GetNewFactHandler")
        print("Running action here")
        speak = "I will run the action"
        return (handler_input.response_builder.speak(speak).response)

I have something similar to the code above. But it always executes the action before Alexa says it will execute it. Is there any way to pass a callback to the response builder? I'm very new to the SDK, sorry if it is too obvious.


Solution

  • You can use Progressive Response

    Your skill can send progressive responses to keep the user engaged while your skill prepares a full response to the user's request. A progressive response is interstitial SSML content (including text-to-speech and short audio) that Alexa plays while waiting for your full skill response.

    To note, Alexa is not calling the API after saying the speech, it is calling the API while responding to the user to make it looks smooth.

    Phython code example

    def get_progressive_response(handler_input):
        # type: (HandlerInput) -> None
        request_id_holder = handler_input.request_envelope.request.request_id
        directive_header = Header(request_id=request_id_holder)
        speech = SpeakDirective(speech="Ok, give me a minute")
        directive_request = SendDirectiveRequest(
            header=directive_header, directive=speech)
    
        directive_service_client = handler_input.service_client_factory.get_directive_service()
        directive_service_client.enqueue(directive_request)
        time.sleep(5)
        return
    
    class HelloWorldIntentHandler(AbstractRequestHandler):
        # Handler for Hello World Intent
        def can_handle(self, handler_input):
            # type: (HandlerInput) -> bool
            return is_intent_name("HelloWorldIntent")(handler_input)
    
        def handle(self, handler_input):
            # type: (HandlerInput) -> Response
            speech_text = "Hello World!"
    
            get_progressive_response(handler_input)
    
            handler_input.response_builder.speak(speech_text).set_card(
                SimpleCard("Hello World", speech_text)).set_should_end_session(
                False)
            return handler_input.response_builder.response