Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a custom Alexa skill with Spring Boot https endpoint

I am trying to create a Custom Alexa Skill without using Lambda. As such, I have deployed a Spring Boot application to an AWS EC2 instance, setup an SSL certificate, and tested that the service is functional by using Postman to invoke it.

I then setup an Alexa skill as an "https" endpoint. When I using the Test form on developer.amazon.com, I simply get back:

The remote endpoint could not be called, or the response it returned was invalid.

When I invoke the service directly with Postman, I get:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "id": null,
      "text": "Hello, World.  I am a Spring Boot custom skill."
    },
    "card": {
      "type": "Simple",
      "title": "HelloWorld",
      "content": "Hello, World.  I am a Spring Boot custom skill."
    },
    "reprompt": null,
    "shouldEndSession": true
  },
  "sessionAttributes": null
}

My controller uses the Alexa Skill Set SDK. Here's the code:

@RestController
public class AlexaController  {

    @RequestMapping(value="/alexa", 
        method=RequestMethod.POST,
        produces=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<SpeechletResponseEnvelope> alexa(Model model) {

        String speechText = "Hello, World.  I am a Spring Boot custom skill.";

        SimpleCard card = new SimpleCard();
        card.setTitle("HelloWorld");
        card.setContent(speechText);

        PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
        speech.setText(speechText);


        SpeechletResponse response = SpeechletResponse.newTellResponse(speech, card);


        SpeechletResponseEnvelope envelope = new SpeechletResponseEnvelope();
        envelope.setResponse(response);
        envelope.setVersion("1.0");
        envelope.setSessionAttributes(null);

        return new ResponseEntity<SpeechletResponseEnvelope>(envelope, HttpStatus.OK);
    }
}   
like image 956
Raff Avatar asked Dec 18 '22 12:12

Raff


1 Answers

So, I scrapped the above and instead registered a custom servlet using Spring's ServletRegistrationBean class.

@Configuration
public class AlexaConfig {

    @Autowired
    private MyCustomSpeechlet mySpeechlet;

    @Bean
    public ServletRegistrationBean registerServlet() {

        SpeechletServlet speechletServlet = new SpeechletServlet();
        speechletServlet.setSpeechlet(mySpeechlet);

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(speechletServlet, "/alexa");
        return servletRegistrationBean;     
    }
}

My custom Servlet extends The Alexa Skill Kit class Speechlet.

@Service
public class MyCustomSpeechlet implements Speechlet {

    @Override
    public void onSessionStarted(SessionStartedRequest request, Session session) throws SpeechletException {    
    }

    @Override
    public SpeechletResponse onLaunch(LaunchRequest request, Session session) throws SpeechletException {
    }

    @Override
    public SpeechletResponse onIntent(IntentRequest request, Session session) throws SpeechletException {

        Intent intent = request.getIntent();
        if (intent == null)
            throw new SpeechletException("Unrecognized intent");

        String intentName = intent.getName();       

        if ( intentName.equals("TerriblyInterestingIntent") ) {

            String speechText = "Hello, World.  I am a Spring Boot custom skill.";

            SimpleCard card = new SimpleCard();
            card.setTitle("Hello World");
            card.setContent(speechText);

            PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
            speech.setText(speechText);

            SpeechletResponse response = SpeechletResponse.newTellResponse(speech, card);
            return response;
        }
        else {
            throw new SpeechletException("I don't understand that intent.");
        }
    }

    @Override
    public void onSessionEnded(SessionEndedRequest request, Session session) throws SpeechletException {

    }
}

Works like a charm!

like image 92
Raff Avatar answered May 09 '23 08:05

Raff