Лямбда-функция не работает с навыком Алекса

Я пытаюсь соединить пользовательское намерение под названием "PageviewsIntent" с моей лямбда-функцией. К сожалению, это не работает?

Моя идея была подключиться сначала так

return request.type === 'IntentRequest'
        && request.intent.name === 'PageviewsIntent';

и добавить его в обработчики запросов

 .addRequestHandlers(
    PageviewsHandler,
    StartHandler,

Но это не работает. Вызов работает нормально. Функция getGA() работает, если я вызываю ее в StartHandler.

const Alexa = require('ask-sdk');
const { google } = require('googleapis')

const jwt = new google.auth.JWT(
  XXXXX,
  null,
  XXXXX,
  scopes
)

const gaQuery = {
  auth: jwt,
  ids: 'ga:' + view_id,
  'start-date': '1daysAgo',
  'end-date': '1daysAgo',
  metrics: 'ga:pageviews'
}

const getGA = async () => {
  try {
    jwt.authorize()
    const result = await google.analytics('v3').data.ga.get(gaQuery)
    return result.data.totalsForAllResults['ga:pageviews'];
  } catch (error) {
    throw error
  }
}

const PageviewsHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
        && request.intent.name === 'Pageviews';
  },
  async handle(handlerInput) {
    try {
      const gadata = await getGA()
      const speechOutput = GET_FACT_MESSAGE + " Bla " + gadata;

      return handlerInput.responseBuilder
        .speak(speechOutput)
        .withSimpleCard(SKILL_NAME, speechOutput)
        .getResponse();

    } catch (error) {
      console.error(error);
    }
  },
};

const StartHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    try {
      const speechOutput = GET_FACT_MESSAGE;

      return handlerInput.responseBuilder
        .speak(speechOutput)
        .withSimpleCard(SKILL_NAME, speechOutput)
        .getResponse();

    } catch (error) {
      console.error(error);
    }
  },
};

const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && (request.intent.name === 'AMAZON.CancelIntent'
        || request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const SKILL_NAME = 'Blick Google Analytics';
const GET_FACT_MESSAGE = 'Hallo zu Blick Google Analytics';
const HELP_MESSAGE = 'Bla Bla Hilfe';
const HELP_REPROMPT = 'Bla Bla Hilfe';
const STOP_MESSAGE = 'Ade!';

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    PageviewsHandler,
    StartHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

Я до сих пор не смог решить проблему, но теперь я проверил лямбду. Кажется, нет проблем. Если я проверю, как это

Я получаю правильный результат

  "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>Bla 5207767</speak>"

В https://developer.amazon.com/alexa/console/ask/build я настроил это так

Возможно ли, что инструмент тестирования не работает?

Тестовый интерфейс выглядит так:

2 ответа

Решение

Ваша проблема вызвана неправильной обработкой сеанса в StartHandler, По умолчанию он закрывается, когда есть только speak() метод, используемый в построителе ответов. Вы должны держать сеанс открытым, добавив .reprompt() на ваше приветственное сообщение:

return handlerInput.responseBuilder
        .speak(speechOutput)
        .reprompt(speechOutput)
        .withSimpleCard(SKILL_NAME, speechOutput)
        .getResponse();

или путем явного добавления .withShouldEndSession(false)

return handlerInput.responseBuilder
        .speak(speechOutput)
        .withSimpleCard(SKILL_NAME, speechOutput)
        .withShouldEndSession(false)
        .getResponse();

вашему строителю ответа. Вы можете найти больше информации об обработке запросов в Alexa Developer Blog

В вашей лямбде ваша "может справиться" отражает

canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
        && request.intent.name === 'Pageviews';
  }

Но ваше имя намерения на самом деле:

PageviewsIntent

Тестовое событие, которое вы предоставили на скриншоте, не вызвало бы код, которым вы поделились. Пожалуйста, дважды проверьте, совпадают ли имя вашего намерения и canHandle.

Если вы изменили имя Intent в консоли разработчика Alexa, вам необходимо убедиться, что вы сохранили и создали свой навык Alexa. Кроме того, убедитесь, что ваше умение направлено на правильную версию лямбды, чтобы избежать путаницы.

Другие вопросы по тегам