简体   繁体   English

Alexa提出问题并从外部API获得响应

[英]Alexa ask a question and get response from external API

I have set up a simple intent 我设置了一个简单的意图

 { "interactionModel": { "languageModel": { "invocationName": "viva bank", "intents": [ ...builtin intents...{ "name": "ask", "slots": [{ "name": "question", "type": "AMAZON.SearchQuery" }], "samples": [ "when {question}", "how to {question}", "what {question}" ] } ], "types": [] } } } 

But when I ask a question it gives me a generic error response like this: 但是,当我问一个问题时,它给出了一个像这样的通用错误响应:

Me: alexa ask viva bank when is the late fee charged 我:alexa询问viva银行是否收取滞纳金

Alexa: Sorry, I don't know that. Alexa:对不起,我不知道。

Here is my lambda code, but I don't think it is getting that far. 这是我的lambda代码,但我认为它没有那么远。

 'use strict'; const Alexa = require('ask-sdk-core'); var https = require('https'); var querystring = require('querystring'); const APP_ID = 'amzn1.ask.skill.1234'; const AskIntentHandler = { canHandle(handlerInput) { return !!handlerInput.requestEnvelope.request.intent.slots['question'].value; }, handle(handlerInput) { var question = handlerInput.requestEnvelope.request.intent.slots['question'].value; console.log('mydata:', question); var responseString = ''; const subscription_key = 'XXXX'; var data = { simplequery: question, channel: 'Alexa' }; var get_options = { headers: { 'Subscription-Key': subscription_key } }; https.get('https://fakeapi.com/' + querystring.stringify(data), get_options, (res) => { console.log('statusCode:', res.statusCode); console.log('headers:', res.headers); res.on('data', (d) => { responseString += d; }); res.on('end', function(res) { var json_hash = JSON.parse(responseString); // grab the first answer returned as text and have Alexa read it const speechOutput = json_hash['results'][0]['content']['text']; console.log('==> Answering: ', speechOutput); // speak the output return handlerInput.responseBuilder.speak(speechOutput).getResponse(); }); }).on('error', (e) => { console.error(e); return handlerInput.responseBuilder.speak("I'm sorry I ran into an error").getResponse(); }); } }; exports.handler = (event, context) => { const alexa = Alexa.handler(event, context); alexa.APP_ID = APP_ID; alexa.registerHandlers(AskIntentHandler); alexa.execute(); }; 

I'm really just looking to create a very simple pass through, where a question is asked to Alexa, and then I pipe that to an external API and have Alexa read the response. 我真的只是想创建一个非常简单的传递,其中向Alexa询问一个问题,然后我将其传递给外部API并让Alexa读取响应。

You can make the question slot value as required if it is mandatory for the intent and you need to include the intent name. 如果对于intent是必需的,您可以根据需要设置问题槽值,并且您需要包含意图名称。 You can use async/await to handle the API. 您可以使用async / await来处理API。

const Alexa = require('ask-sdk-core');
const https = require('https');
const querystring = require('querystring');
const { getSlotValue } = Alexa;

const APP_ID = 'amzn1.ask.skill.1234';

const AskIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      handlerInput.requestEnvelope.request.intent.name === "AskIntent"
    );
  },
  async handle(handlerInput) {
    const question = getSlotValue(handlerInput.requestEnvelope, "question");
    console.log("question ", question);
    const data = await getAnswer(question);
    const speechText = data;
    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
  }
};

const getAnswer = question => {
  const subscription_key = "XXXX";
  let data = {
    simplequery: question,
    channel: "Alexa"
  };
  let get_options = {
    headers: {
      "Subscription-Key": subscription_key
    }
  };
  return new Promise((resolve, reject) => {
    https
      .get(
        "https://fakeapi.com/" + querystring.stringify(data),
        get_options,
        res => {
          console.log("statusCode:", res.statusCode);
          console.log("headers:", res.headers);
          res.on("data", d => {
            responseString += d;
          });

          res.on("end", function(res) {
            var json_hash = JSON.parse(responseString);
            // grab the first answer returned as text and have Alexa read it
            const speechOutput = json_hash["results"][0]["content"]["text"];
            console.log("==> Answering: ", speechOutput);
            resolve(speechOutput);
          });
        }
      )
      .on("error", e => {
        console.error(e);
        resolve("I'm sorry I ran into an error");
      });
  });
};

In AskIntentHandler you should set your "canHandle" to the name of the intent like so in addition to checking the question slot. 在AskIntentHandler中,除了检查问题槽之外,您应该将“canHandle”设置为意图的名称。

const AskIntentHandler = {
  canHandle (handlerInput) {
  return handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
      handlerInput.requestEnvelope.request.intent.name === 'AskIntent' &&
      !!handlerInput.requestEnvelope.request.intent.slots['question'].value
  },
  handle (handlerInput) {
     // API Request Here
  }
}

Also if "question" is always required to run the intent, you can set up a dialog so Alexa will ask the user for "question" if she doesn't recognize one. 此外,如果始终需要“问题”来运行意图,您可以设置一个对话框,这样Alexa会询问用户“问题”,如果她不识别。

https://developer.amazon.com/docs/custom-skills/delegate-dialog-to-alexa.html https://developer.amazon.com/docs/custom-skills/delegate-dialog-to-alexa.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM