Alexa 提出问题并从外部获得回复 API

Alexa ask a question and get response from external API

我设置了一个简单的意图

{
  "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": []
    }
  }
}

但是当我问一个问题时,它会给我一个像这样的一般错误响应:

我:alexa问viva bank滞纳金什么时候收

Alexa:抱歉,我不知道。

这是我的 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();
};

我真的只是想创建一个非常简单的传递,向 Alexa 提出问题,然后我将其通过管道传输到外部 API 并让 Alexa 读取响应。

在 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
  }
}

此外,如果 "question" 总是需要 运行 意图,您可以设置一个对话框,这样 Alexa 会在用户不认识时询问 "question"。

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

如果意图是强制性的并且需要包含意图名称,则可以根据需要设置问题槽值。您可以使用 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");
      });
  });
};