Search code examples
javapython-3.xamazon-web-servicesalexa-skills-kit

How to make REST API calls to Amazon Alexa


I am building a custom Alexa skill and want to make REST API calls. Currently, I am able to make GET request to fetch data from my web service which is then used by Alexa. However, I have the following requirements and I am not sure how to go about developing this.

  1. Invoke the Skill (Complete)
  2. User will invoke "Get List of Topics" intent, Alexa makes the GET REST API call and provides the "list of topics"(Complete)
  3. Make Alexa prompt the user to select a topic from the list (Pending)
  4. Receive the response made by the user in the lambda function and use the response to make a POST/PUT call. (Pending)
  5. Reprompt the user if the selected topic is invalid (Pending).

How do I implement 3, 4, and 5? I am currently using Python 3.6 to write the lambda function at AWS developer console. Are there any Amazon Alexa APIs guide for Python 3.6.

How do I do this in Java which is my preferred way?

I followed the instructions here to develop what I currently have: https://github.com/simonprickett/alexabart

Is there any detailed documentation available on how to write Alexa specific lambda function and its associated API guide for Python3 or Java.

Thanks


Solution

  • If you have a lot of questions and you want each of them answered, you can use sessionAttributes variable. The session variable can retain it's value through out the course of the session. You can make a dictionary to be saved in your sessionAttributes(It has to be a dictionary).

    You can save something like this in your session variable.

    sessionAttributes: {
        "AllQuestions" : ["string", "string"],
        "LastQuestionIndex" : integer
    }
    

    I'm assuming you're able to get the list of questions (using a GET request).

    Step 1 : Make a slot

    Answer would be a slot which is going to store your answer.

    Step 2 : Get your questions ready

    When your intent has just started and you don't have anything in your sessionAttributes (use a simple if-else) you'll have to make the GET request and gather all of your questions (maybe in a list or something). You make your GET request and store all the questions in your sessionAttributes['AllQuestions']. And set LastQuestionIndex = -1.

    Now the tricky part comes in. (I'm also assuming you're able to use Dialog.ElicitSlot Directive).

    Step 3 : Ask questions one-by-one.

    Now you have a list of all the questions and you also have the index of last question that was asked. And now you just have to increment the index, get the Next Question, and use Dialog.ElicitSlot Directive to ask this new question. And update the LastQuestionIndex in your sessionAttributes.

    Step 4 : Getting the answer

    Before proceeding to next question, you'll also have to check if the slot Answer has any value or not? If it does have a value (it is not "None"), then you can use the LastQuestionIndex variable and store the answer for that particular question.

    If you're looking for code, here you go:

    # Line 1 - 22 should be in your intent function
    sessionAttributes =  dict()
    if 'sessionAttributes' in event['session']: 
        sessionAttributes = event['session']['sessionAttributes']
    
    if not sessionAttributes.has_key('AllQuestions') : 
        # Make the GET REQUEST
        Questions = ["all", "of", "your", "Questions", "stored", "in", "a", "list"]
        sessionAttributes['AllQuestions'] = Questions
        sessionAttributes['LastQuestionIndex'] = -1
    
    
    Answer = getSlotValue('Answer')
    if Answer != None:
        # AllAnswers is a dictionary which has key as the question number and value is the answer
        # AllAnswers = {
        #   0 : "Answer to your first question",
        #   1 : "Answer to your second question"
        # }
        AllAnswers[sessionAttributes['LastQuestionIndex']] = Answer
    
    return ansNextQuestion(sessionAttributes)
    
    
    def askNextQuestion(sessionAttributes) :
        Last = sessionAttributes['LastQuestionIndex']
        sessionAttributes['LastQuestionIndex'] = Last + 1
    
        if Last < len(sessionAttributes['AllQuestions']): 
            outputSpeech = "Your next question is " + sessionAttributes['AllQuestions'][Last + 1]
            return {
                "version": "1.0",
                "sessionAttributes": sessionAttributes,
                "response": {
                    "outputSpeech": {
                        "type": "PlainText",
                        "text": outputSpeech
                    },
                    "shouldEndSession": False,
                    "directives": [
                        {
                            "type": "Dialog.ElicitSlot",
                            "slotToElicit": "Question",
                            "updatedIntent": {
                                "name": "GetMovieDetails",
                                "confirmationStatus": "NONE",
                                "slots": {
                                    "Answer": {
                                        "name": "Answer",
                                        "value": "NONE" # You can change the value of Answer to get new answer, this is allowed.
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        else : 
            # You are out of questions, now proceed to what you should do after getting all the answers.