В первую очередь регистрируемся на Алисе и создаем сервис на Firebase.
Firebase.json
Мы будем использовать отдельный контроллер, назовем его dialog.
{
"hosting": {
"rewrites": [
{
"source": "/dialog",
"function": "dialog"
}
]
}
}
Настройки сервера Express
Создаем файл server.js. Мы используем возможности firebase-functions, поэтому не забываем установить его в зависимостях package.json.
const functions = require('firebase-functions');
const express = require('express');
const app = express();
const router = express.Router();
exports.dialog = functions.https.onRequest(require('./dialog.js'));
exports.app = functions.https.onRequest(app);
app.use(router);
Создаем контроллер диалога
Для этого создаем файл dialog.js в директории проекта. Обязательно регистрируем приложение через firebase, а именно нужен ключа вашего сервис аккаунта гугл. Яндекс.Алиса использует POST запросы, поэтому исключаем GET-запросы, они нам не нужны.
const functions = require('firebase-functions');
const dialogflow = require('dialogflow');
const credentials = functions.config().service_account; // здесь будут данные вашего аккаунта
const app = 'tewst-landing-page'; // здесь указываем название вашего приложения firebase
module.exports = async (request, response) => {
try {
// Проверяем чтобы вход был выполнен через POST
if (!request.body.request) {
response.status(400).send(`<h1>Проверьте правильность запроса.</h1>`);
return;
}
// Действие после нажатия на кнопку
if (!request.body.request.hasOwnProperty('original_utterance')) {
response.send({
response: {
text: 'Приятно было помочь.',
end_session: true,
},
version: request.body.version,
});
return;
}
const { original_utterance } = request.body.request;
// Приветствие
if (original_utterance.length === 0) {
response.send({
response: {
text: 'Привет. Это помощник по навигации сайта goto Interactive Software.',
end_session: false,
},
version: request.body.version,
});
return;
}
// Проверка команды ping
if (original_utterance === 'ping') {
response.send({
response: {
text: 'понг',
end_session: false,
},
version: request.body.version,
});
return;
}
const sessionClient = new dialogflow.SessionsClient({ credentials });
const sessionPath = sessionClient.sessionPath(
app,
request.body.session.session_id,
);
const responses = await sessionClient.detectIntent({
session: sessionPath,
queryInput: {
text: {
text: original_utterance,
languageCode: request.body.meta.locale.toLowerCase(),
},
},
});
// Матчим ссылки и преобразовываем их в кнопки
const matches = responses[0].queryResult.fulfillmentText.match(/\bhttps?:\/\/\S+/gi);
const responseObj = {
text: responses[0].queryResult.fulfillmentText,
};
if (matches && matches.length) {
responseObj.end_session = false;
responseObj.buttons = matches.map(url => {
return {
title: 'Открыть ссылку',
payload: 'button1',
url: url,
hide: true,
};
});
} else {
responseObj.end_session = true;
}
response.send({
response: responseObj,
version: request.body.version,
});
} catch (error) {
response.send({
response: {
text: error.message,
end_session: true,
},
version: request.body.version,
});
}
}
Связываем наш сервис с WebHook
Итоговый результат
Для тестирования можно воспользоваться встроенной отладкой:
При всех плюсах и удобств Dialogflow, есть один минус, о котором умалчивают. Сервис Dialogflow представляет угрозу для продакшена, так как логирует и обрабатывает каждый запрос. Вероятнее всего, это делается для обучения ИИ от Гугл. Если вас это не устраивает, то придется переходить на собственное решение NLP и диалоговых систем.