Я создаю 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 »
Это буквально сводит меня с ума, и я не мог найти причину проблемы! Пожалуйста, помогите.