如何对 Amazon Alexa 进行 REST API 调用

How to make REST API calls to Amazon Alexa

我正在构建自定义 Alexa 技能并希望进行 REST API 调用。目前,我能够发出 GET 请求以从我的 Web 服务中获取数据,然后由 Alexa 使用。但是,我有以下要求,但我不确定如何着手开发它。

  1. 调用技能(完成)
  2. 用户将调用 "Get List of Topics" 意图,Alexa 进行 GET REST API 调用并提供 "list of topics"(Complete)
  3. 让 Alexa 提示用户 select 列表中的一个主题(待定)
  4. 接收用户在 lambda 函数中做出的响应,并使用该响应进行 POST/PUT 调用。 (待定)
  5. 如果 selected 主题无效(待定),则重新提示用户。

如何实施 3、4 和 5?我目前正在使用 Python 3.6 在 AWS 开发人员控制台上编写 lambda 函数。 Python 3.6.

是否有任何 Amazon Alexa APIs 指南

如何在 Java 中执行此操作?

我按照此处的说明开发了我目前拥有的东西:https://github.com/simonprickett/alexabart

是否有关于如何编写特定于 Alexa 的 lambda 函数及其相关 Python3 或 Java.

的相关 API 指南的详细文档?

谢谢

您可以使用 slotsDialog.ElicitSlot 指令,从用户那里获取信息。 更具体地说,您将需要一个您将 return Dialog.ElicitSlot 响应的插槽,并在响应的 speechOutput 中提供选项列表,当用户提供信息,它将被收集在插槽中。 看到这个:https://developer.amazon.com/docs/custom-skills/dialog-interface-reference.html#elicitslot

如果你正在寻找代码,这就是我在 Python 2.7

中所做的
def dialog_elicit_slot(output, slotToElicit, city_name, movie_name, attributes, multiplex = None, confirmationStatus = "CONFIRMED"):
    return {
        "version": "1.0",
        "sessionAttributes": attributes,
        "response": {
            "outputSpeech": {
                "type": "PlainText",
                "text": output
            },
            "shouldEndSession": False,
            "directives": [
                {
                    "type": "Dialog.ElicitSlot",
                    "slotToElicit": slotToElicit,
                    "updatedIntent": {
                        "name": "GetMovieDetails",
                        "confirmationStatus": confirmationStatus,
                        "slots": {
                            "CITY": {
                                "name": "CITY",
                                "confirmationStatus": "CONFIRMED" if city_name != None else "NONE",
                                "value": city_name
                            },
                            "NAME": {
                                "name": "NAME",
                                "confirmationStatus": "CONFIRMED" if movie_name != None else "NONE",
                                "value": movie_name
                            },
                            "MULTIPLEX": {
                                "name": "MULTIPLEX",
                                "confirmationStatus": "CONFIRMED" if multiplex != None else "NONE",
                                "value" : multiplex
                            }
                        }
                    }
                }
            ]
        }
    }

在这里,您可以看到我有 3 个插槽,其中 2 个(CITYNAME)在技能生成器中是必需的。

这就是我的技能。它在开始时询问电影的城市和名称(调用技能),然后我的技能将向远程站点发出 GET 请求以获取多路复用列表。当我有在他的特定城市显示该电影(用户告诉并收集在 NAME 插槽中)的多路复用列表时,我给他们多路复用列表(这只是一个字符串,output 上面代码中的变量)。 Dialog.ElicitSlot 指令收集 slotToElicit 插槽的插槽信息(在本例中为 MULTIPLEX)。

如果这看起来让人难以接受,您可以直接与我联系。

如果您有很多问题并且希望每个问题都得到解答,您可以使用 sessionAttributes 变量。会话变量可以在整个会话过程中保留它的值。你可以做一个字典保存在你的sessionAttributes(它必须是一个字典)。

您可以在会话变量中保存类似这样的内容。

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

我假设您能够获得问题列表(使用 GET 请求)。

第 1 步:制作插槽

Answer 将是一个存储您的答案的插槽。

第 2 步:准备好您的问题

当您的意图刚刚开始并且您的 sessionAttributes 中没有任何内容(使用简单的 if-else)时,您必须发出 GET 请求并收集所有问题(也许在列表或其他东西中)。 您发出 GET 请求并将所有问题存储在 sessionAttributes['AllQuestions'] 中。并设置 LastQuestionIndex = -1.

现在棘手的部分来了。(我还假设您能够使用 Dialog.ElicitSlot 指令)。

第 3 步:逐一提问。

现在你有一个所有问题的列表,你也有最后一个问题的索引。现在你只需要增加索引,得到下一个问题,然后使用 Dialog.ElicitSlot 指令来问这个新问题。并更新您的 sessionAttributes 中的 LastQuestionIndex

第 4 步:获得答案

在继续下一个问题之前,您还必须检查插槽 Answer 是否有任何值? 如果它确实有值(它不是 "None"),那么您可以使用 LastQuestionIndex 变量并存储该特定问题的答案。

如果您正在寻找代码,请看这里:

# 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.