Перейти к основному содержимому

Бот для маршрутизации запросов

Это часть серии статей, посвященной созданию многоязычного бота.

  1. Принцип работы
  2. Маршрутизация запросов (вы находитесь здесь)
  3. Поддержка русского языка
  4. Поддержка других языков
  5. Публикация в канал

В этом разделе мы напишем реализацию бота-роутера, предназначенного для маршрутизации запросов клиента в одноязычного бота на нужном языке.

Перейдите в JAICP и создайте новый проект. Язык NLU и другие настройки данного проекта могут быть любыми. Перейдите в раздел Редактор.

Дескриптор сценария

В соответствии с предложенной схемой многоязычного бота роутер должен иметь доступ к следующим конфигурируемым параметрам:

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

Зададим данные параметры в разделе injector дескриптора сценария chatbot.yaml:

injector:
defaultLanguage: ru
unknownLanguageMessage: Извините, этот язык не поддерживается.
bots:
ru: ""
en: ""

Значение поля defaultLanguage и ключи в словаре bots должны соответствовать ISO-кодам языков, которые будет поддерживать бот. Значения словаря bots временно оставьте пустыми.

подсказка
Заданные параметры будут доступны из сценария через объект $injector.

Функции

Создадим в папке src файл router.js и поместим туда код, реализующий функциональность бота-роутера.

function detectLanguage(ctx) {
if (ctx.request.query === "/start") {
return ctx.injector.defaultLanguage;
}
return $caila.detectLanguage([ctx.request.query])[0];
}

function redirectToBot(botId, ctx, targetState) {
targetState = targetState || "/Hello";
var params = ctx.session || {};

ctx.response.replies = ctx.response.replies || [];
ctx.response.replies.push({
type: "context-switch",
targetBotId: botId,
targetState: targetState,
parameters: params
});
}

function processRequest(ctx) {
var lang = detectLanguage(ctx);
var botId = ctx.injector.bots[lang];

if (botId) {
redirectToBot(botId, ctx);
} else {
$reactions.answer(ctx.injector.unknownLanguageMessage);
}
}

Рассмотрим используемые функции. Все функции в числе аргументов принимают объект $context, представляющий собой текущий контекст обработки запроса.

  • Функция detectLanguage определяет язык запроса при помощи метода $caila.detectLanguage. Исключение составляет первый запрос /start — для него функция возвращает язык по умолчанию, заданный в дескрипторе сценария.

  • Функция redirectToBot переключает контекст в нужного одноязычного бота при помощи context-switch. По умолчанию делается переход в стейт /Hello. В качестве данных, общих между ботами, передается все содержимое объекта $session.

  • Функция processRequest используется для обработки всех запросов, которые принимает бот-роутер: она определяет язык запроса и переключает контекст на нужного одноязычного бота. Если бот для языка запроса не задан в дескрипторе, выдается сообщение о том, что язык не поддерживается.

Код сценария

В файле main.sc необходимо подключить файл router.js при помощи тега require, а также предусмотреть два стейта:

  1. стейт /Request для приема всех запросов, переданных в роутер;
  2. стейт-заглушку /Redirect, который будет использоваться для маршрутизации запросов.
подсказка
К обоим стейтам следует привязать в качестве обработчика функцию processRequest.
require: router.js

init:
bind("preMatch", processRequest);
bind("postProcess", processRequest, "/Redirect");

theme: /

state: Request
q!: *

state: Redirect

Далее мы перейдем к созданию первого одноязычного бота.