Второй запрос Google Actions SDK во время разговора завершается с ошибкой «TypeError: стандарт не является функцией» - PullRequest
0 голосов
/ 05 ноября 2018

Я создаю Google Action, используя библиотеку Actions SDK V2.

Я могу заставить разговор работать, когда использую простые методы conv.ask и conv.close. Но как только я добавляю асинхронные методы в цепочку обработки, у меня возникают проблемы. Я использую

"actions-on-google": "^2.4.1", 
"firebase-admin": "^6.0.0",
"firebase-functions": "^2.1.0",

Ровно после каждых 3 неудачных попыток четвертая попытка проходит. Похоже, что предыдущий запрос отключил мою облачную функцию Firebase!

Первый запрос на выполнение работает нормально, а последующие сбои с «TypeError: стандарт не является функцией в /srv/node_modules/actions-on-google/dist/framework/express.js"

severity:  "ERROR"  
 textPayload:  "TypeError: standard is not a function
    at /srv/node_modules/actions-on-google/dist/framework/express.js:27:13
    at omni (/srv/node_modules/actions-on-google/dist/assistant.js:44:53)
    at cloudFunction (/srv/node_modules/firebase-functions/lib/providers/https.js:57:9)
    at /worker/worker.js:700:7
    at /worker/worker.js:684:9
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)" 

Я понимаю, что когда у меня есть асинхронные функции в цепочке обработки, я должен вернуть Promise обработчику Intent. И я делаю это. Но все равно последующий запрос не выполняется.

const app = actionssdk();
 // ... app code here


  app.middleware((conv) => {
    console.log('Conversation in Middleware:', conv);
    conv.hasScreen =
      conv.surface.capabilities.has('actions.capability.SCREEN_OUTPUT');
    conv.hasAudioPlayback =
      conv.surface.capabilities.has('actions.capability.AUDIO_OUTPUT');
  });

// Welcome Intent
app.intent('actions.intent.MAIN', (conv, input) => {
  // conv.ask('How are you');
  console.log('Conversation: ' + JSON.stringify(conv), conv);
  console.log('actions.intent.MAIN', input)
  return new Promise((resolve, reject) => {
    processIntents({conv: conv, input:input}).then(r => {
      console.log('Passing response from the handler!', r);
      for(let a of r) {
        conv.ask(a);
      }
      resolve();
    }).catch(e => reject(e));
  });
});

// React to a text intent
app.intent('actions.intent.TEXT', (conv, input) => {
  console.log('actions.intent.TEXT', input)
  // conv.ask('How are you');
  console.log('Conversation: ' + JSON.stringify(conv), conv);
  console.log('actions.intent.TEXT', input)
  return new Promise((resolve, reject) => {
    processIntents({conv: conv, input:input}).then(r => {
      console.log('Passing response from the handler!', r);
      for(let a of r) {
        conv.ask(a);
      }
      resolve();
    }).catch(e => reject(e));
  });
});

// React to list or carousel selection
app.intent('actions.intent.OPTION', (conv, params, option) => {
  // conv.ask('How are you');
  console.log('actions.intent.OPTION', {input: conv.input, option: option, params:params})
  console.log('Conversation: ' + JSON.stringify(conv), conv);
  console.log('actions.intent.OPTION', option)
  return new Promise((resolve, reject) => {
    processIntents({conv: conv, params: params, option: option}).then(r => {
      console.log('Passing response from the handler!', r);
      for(let a of r) {
        conv.ask(a);
      }
      resolve();
    }).catch(e => reject(e));
  });
});
app.intent('', (conv) => {
  // conv.ask('How are you');
  console.log('Empty Intent for direct WEB requests / ALEXA requests', conv);
  let input = ((conv.request.originalRequest ||{}).result ||{}).resolvedQuery;
  return new Promise((resolve, reject) => {
    processIntents({conv: conv, input: input}).then(r => {
      //TODO: send raw HTTP Response
      //TODO: Yet to figure out how this can be done@!
      resolve();
    }).catch(e => reject(e));
  });
});

const processIntents = (args) => {
    let conv = args["conv"];
    let params = args["params"];
    let option = args["option"];
    let input = args["input"];
    // Async Function here that responds with a Promise
    // Based on the request, it will send either array of responses to use in conv.ask calls
   // OR send response JSON body that can be sent to Amazon Alexa / WEB requests
  return Promise.resolve(response);
}
exports.apiaifns = functions.https.onRequest(app);

Я отправляю массив ответов на диалоги из метода processIntents и выполняю итерацию по всему массиву во время ответа.

Я перепробовал множество возможных комбинаций и комбинаций этого, но все равно последующий запрос не удался.

Обновление: тестирование с использованием облачных функций Google вместо GCF для Firebase Обновил код моего приложения, чтобы оно стало экспресс-приложением и было развернуто на GCF с таким же именем. Теперь ситуация на хуже . Только первый запрос после развертывания облачной функции является успешным, и все последующие запросы терпят неудачу с той же ошибкой, что и раньше!

Вот мое обновление для функции:

const express = require('express')
const bodyParser = require('body-parser')
var morgan = require('morgan')
.
.
.
const expressApp = express().use(bodyParser.json())
expressApp.use(morgan('dev'))
expressApp.post('/fulfillment', app)

exports.apiaifns = expressApp;

Я также изменил URL-адрес вызова actio на «https://us -central1-my-project.cloudfunctions.net / apiaifns / assignment »

Это буквально сводит меня с ума, и я не мог найти причину проблемы! Пожалуйста, помогите.

...