'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://my_db.firebaseio.com/",
});
var database = admin.database();
var transition = database.ref('/stage');
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
console.info('Inside :) yessssssss !');
const agent = new WebhookClient({ request, response });
function moveToStage (agent) {
transition.set('2');
agent.add('Welcome to xx console. Please accept the notification on your watch');
}
transition.on('value', (snapshot) => {
console.info("Reading value succesfully from firebase");
console.info(snapshot.val());
if (snapshot.val() == '3'){
agent.add('Thank you for granting me the access.');
// OR
// response.setHeader('Content-Type','applicaiton/json');
// response.send(JSON.stringify({"fulfillmentText": 'Thank you for granting me the access.'}));
}
});
let intentMap = new Map();
intentMap.set('welcome_and_ask_to_sync', moveToStage);
agent.handleRequest(intentMap);
});
У меня есть намерение welcome_and_ask_to_sync, у которого активирован веб-перехватчик.
Когда это намерение запускается успешным голосовым вводом, оно отвечает текстом / голосом от агента и обновляет поле stage в соответствующей базе данных firebase.
Теперь другое внешнее приложение, при некоторой осторожности, обновляет это поле stage в базе данных firebase.
Нет, это часть кода выполнения, что меняет
transition.on('value', (snapshot) => {
console.info("Reading value succesfully from firebase");
console.info(snapshot.val());
if (snapshot.val() == '3'){
agent.add('Thank you for granting me the access.');
// OR
// response.setHeader('Content-Type','applicaiton/json');
// response.send(JSON.stringify({"fulfillmentText": 'Thank you for granting me the access.'}));
}
});
Цель состоит в том, чтобы затем заставить Google Home что-то говорить, как в этом случае Thank you for granting me the access..
ЗАМЕТКА:Мне не нужно намерение быть уволенным (извините за путаницу ранее). Мне просто нужен голосовой агент Google Home, чтобы подтвердить это изменение / триггер.
Теперь когда смотрю логи, вот тут ломается agent.add('Thank you for granting me the access.');
И журнал ошибок si примерно такой:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
at transition.on (/user_code/index.js:36:22)
at /user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:4465:22
at exceptionGuard (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:691:9)
at EventList.raise (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:9727:17)
at EventQueue.raiseQueuedEventsMatchingPredicate_ (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:9681:41)
at EventQueue.raiseEventsForChangedPath (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:9665:14)
at Repo.onDataUpdate_ (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:12770:26)
at PersistentConnection.onDataPush_ (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:12070:18)
at PersistentConnection.onDataMessage_ (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/index.node.cjs.js:12064:18)
Итак, остается основной вопрос:Как я могу заставить агента говорить / обновлять текстовый ответ и подтверждать изменение поля этой БД.

Короткий ответ: вы не можете - уж точно не так, как вы это делаете.
После отправки ответа от вашего веб-перехватчика обратно в Dialogflow соединение HTTPS закрывается, и любые дальнейшие ответы будут генерировать ошибку, которую вы видите.
Кроме того, диалоговая модель, используемая AoG и Dialogflow, заключается в том, что пользователь должен всегда инициировать каждый раунд диалога. На данном этапе AoG не может «объявить» что-либо. Это будет считаться несколько инвазивным.
Вы можете отправить уведомление через Actions on Google, который перезапустит диалог, когда пользователь подтвердит уведомление. Однако уведомления отправляются только на смартфоны, а не на динамики. Так что это может не соответствовать вашим потребностям.
Если вы ожидаете лишь нескольких обновлений, которые произойдут довольно быстро после первоначальной отправки, вы можете захотеть посмотреть, можете ли вы использовать Ответ СМИ, чтобы поддерживать разговор с «удержанием музыки», пока вы ждете новых обновлений. Когда "удерживаемая музыка" закончится, оно отправит событие вашему действию, и вы можете либо повторно запустить удерживаемую музыку, либо ответить. В этом случае вы не будете использовать метод .on() для получения обновлений, но вам придется проверять каждый раз, когда медиа заканчивает воспроизведение, чтобы видеть, были ли обновления, которые не были отправлены.
Спасибо за объяснение. Я поступлю соответствующим образом и посмотрю, как можно спроектировать новый прицел в соответствии с потребностями.
Я не уверен, что вы имеете в виду под «новым прицелом». Если ответ помог, принятие и / или голосование всегда приветствуются.
Удалось ли решить проблему?