UNPKG

umbot

Version:

Мультиплатформенный фреймворк для создания голосовых навыков и чат-ботов с единой бизнес-логикой. Встроенная поддержка ВКонтакте, Telegram, Viber, MAX, Яндекс Алисы, Маруси и Сбера SmartApp. Архитектура на адаптерах позволяет подключать любые другие платф

224 lines (223 loc) 15.9 kB
import { BasePlugin } from '../../Base'; import { AppContext, IPlatformAdapter, BotController, IDatabaseInfo } from '../../../index'; /** * Тип ответа, который может вернуть адаптер после обработки запроса */ export type TContent = object | string | Promise<object | string>; /** * Дополнительные опции, которые передаются в конструктор адаптера */ export interface IOptions { /** * Любое свойство в необходимо для работы формате */ [key: string]: unknown; } export declare const EMPTY_QUERY_ERROR = "\u041F\u043E\u043B\u0443\u0447\u0435\u043D\u043E \u043F\u0443\u0441\u0442\u043E\u0435 \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043E\u0442 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B, \u0434\u0430\u043B\u044C\u043D\u0435\u0439\u0448\u0430\u044F \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u0430. \u0421\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E \u0437\u0430\u043F\u0440\u043E\u0441 \u043F\u0440\u0438\u0448\u0435\u043B \u043D\u0435 \u043E\u0442 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B."; export declare const EMPTY_CONTEXT_ERROR = "\u041D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F, \u0434\u0430\u043B\u044C\u043D\u0435\u0439\u0448\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u0430. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E\u0441\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F."; /** * Базовый адаптер для создания голосовых навыков и чат-ботов для собственной платформы (WeChat, WhatsApp, Slack и др.). * * Чтобы подключить другую платформу, которая не поставляется из коробки, унаследуйтесь от класса и реализуйте * все абстрактные методы. Адаптер автоматически зарегистрируется в системе * при подключении через `bot.use(new MyPlatformAdapter())`. * * === Обязательные методы === * - {@link isPlatformOnQuery} — определяет, относится ли запрос к платформе или нет * - {@link setQueryData} — обрабатывает запрос и заполняет `controller` данными * - {@link getContent} — формирует ответ в формате платформы * * === Опциональные === * - {@link getQueryExample} — генерирует пример запроса необходимого для тестов * - {@link isLocalStorage}, {@link getLocalStorage}, {@link setLocalStorage} — если платформа поддерживает сохранение локального состояния * - {@link soundProcessing} — кастомная обработка TTS/звуков (для голосовых платформ, или отправка аудиофайла в боте). * * @see Bot * @see BotController * @see BasePlatform */ export declare abstract class BasePlatform<TQuery = unknown> extends BasePlugin implements IPlatformAdapter<TQuery> { #private; /** * Время ответа навыка в миллисекундах при превышении этого времени, будет отправлено предупреждение */ protected WARMING_TIME_REQUEST: number; /** * Максимальное время ответа навыка в миллисекундах при превышении этого времени, будет отправлена ошибка */ protected MAX_TIME_REQUEST: number; protected _token?: string; protected _platformOptions?: IOptions; /** * Имя поля в заголовке запроса, по которому можно проверить корректность полученного запроса от платформы. */ signatureName?: string; /** * Определяет лимит платформы. * В значение указывается количество запросов, которое можно отправить платформе за 1 секунду. * В случае если у платформы нет ограничений, можно указать 0 или null. * По умолчанию null */ limit: number | null; /** * Контекст приложения */ appContext?: AppContext<unknown, TQuery>; /** * Имя платформы */ platformName: string; /** * Определяет тип платформы(голосовая или чат-бот) */ isVoice: boolean; constructor(platformToken?: string, additionalPlatformOptions?: IOptions); /** * Инициализация адаптера. * Определять не обязательно. Стоит указывать в случаях, когда нужно выполнить доп логику, например указать токены или писать какую-то статистику по использованию. * @param appContext */ init(appContext: AppContext<IDatabaseInfo, TQuery>): void; /** * Генерирует пример входящего запроса для локального тестирования вашего приложения. * Позволяет эмулировать запрос от платформы с заданным текстом, ID пользователя, номером сообщения и состоянием. * Необходимо указывать для того, чтобы можно было корректно проверить работоспособность приложения. * * Обязательно определите метод, если планируется тестирования приложения через инструменты предоставляемые платформой. Это существенно упростит процесс разработки приложения. * @param query Запрос пользователя * @param userId Идентификатор пользователя * @param count Порядковый номер запроса * @param state Данные из локального хранилища */ getQueryExample(query: string, userId: string, count: number, state: Record<string, unknown> | string): Record<string, unknown>; /** * Возвращает признак того, соответствует ли запрос текущей платформе или нет * * @example Telegram * ```ts * isPlatformOnQuery(query, headers) { * return headers?.['x-telegram-bot-api-secret-token'] === this._token; * } * ``` * * @example Алиса (тело содержит "meta.session_id") * ```ts * isPlatformOnQuery(query) { * return typeof query === 'object' && query.meta?.session_id; * } * ``` * @param query Запрос, который пришел в приложение * @param headers Заголовок с которым был отправлен запрос * @returns `true`, если запрос относится к этой платформе, иначе `false` */ abstract isPlatformOnQuery(query: TQuery, headers?: Record<string, unknown>): boolean; /** * Проверяет полученный запрос от платформы на корректность. * Из коробки проверка идет по sha256. Если по какой-то причине поведение по умолчанию не подходит, то просто переопределите метод. * @param query * @param headers */ isCorrectQuery(query: TQuery, headers?: Record<string, unknown>): boolean; /** * Обрабатывает входящий запрос и заполняет контроллер данными. * * Обязательно установите: * - `controller.userCommand` и `controller.originalUserCommand` — текст сообщения пользователя * - `controller.userId` — уникальный ID пользователя * - `controller.appType` = this.platformName * * Опционально: * - `controller.userToken` — если платформа присылает токен авторизации * - `controller.userMeta` — если платформа присылает метаданные * - `controller.state` — если платформа поддерживает локальное хранилище * - `controller.nlu` — если платформа присылает NLU/интенты (через `controller.nlu.setNlu(...)`) * * @returns `false`, если запрос повреждён или не может быть обработан; иначе `true` * @param query Запрос от платформы * @param controller Контроллер приложения */ abstract setQueryData(query: TQuery, controller: BotController): boolean | Promise<boolean>; /** * Формирует тело ответа для отправки пользователю. * * Возвращает платформо-специфичный ответ (например, JSON для Алисы). * Для платформ, которые отправляют ответ напрямую (например, Telegram через `sendMessage`), * метод может возвращать `{ ok: true }` или аналог. * * @param controller - контроллер с готовым ответом * @param stateData - данные для локального хранилища * @returns ответ в формате, понятном платформе */ abstract getContent(controller: BotController, stateData?: Record<string, unknown> | null): TContent; /** * Формирует ответ с оценкой * @param controller - контроллер приложения */ getRatingContext(controller: BotController): TContent; /** * Отправка текста пользователю * Этот метод используется для активных рассылок — когда голосовой навык или чат-бот инициирует диалог первым (например, уведомление). * В методе реализована механика преобразования текстового значения `controllerOrText` в контроллер, а также базовый механизм для отправки ответа. * * Переопределять данный метод не рекомендуется. Переопределить стоит только в том случае, если по каким-то технических условиям текущая реализация метода вам не подходит. * * Если платформа не поддерживает возможность начать диалог самостоятельно, то можно оставить метод пустым, либо вывести любую заглушку. * @param userId Ид пользователя, которому нужно отправить сообщение * @param controllerOrText Контроллер приложения или текст. Если необходимо отправить просто текст, можно передать строку, в случае, если необходимо передать картинку звук и тд, то необходимо корректно заполнить контроллер. */ send(userId: string | number, controllerOrText: BotController | string): TContent | boolean; /** * Устанавливает время начала обработки запроса. * Используется для измерения времени выполнения */ updateTimeStart(controller: BotController): void; /** * Получает время выполнения запроса в миллисекундах * @returns {number} Время выполнения запроса */ getProcessingTime(controller: BotController): number; /** * При превышении установленного времени исполнения, пишет информацию в лог * После вызова getContent() автоматически проверяется время выполнения. * Если оно превышает 2000 мс — пишется warning, если >2900 мс — ошибка. */ protected _timeLimitLog(controller: BotController): void; /** * Дополнительная обработка для звуков. * В данном методе стоит реализовать логику, с помощью которой будут наложены дополнительные эффекты для озвучивания текста пользователю * @param _controller */ soundProcessing(_controller: BotController): void | Promise<void>; /** * Инициализирует TTS (Text-to-Speech) в контроллере. * Обрабатывает звуки и стандартные звуковые эффекты * @param controller Тип приложения * @protected */ protected _initTTS(controller: BotController): void | Promise<void>; /** * Указывает, поддерживает ли платформа локальное хранилище. * * @param _controller - контроллер приложения * @returns `true`, если локальное хранилище доступно */ isLocalStorage(_controller: BotController): boolean; /** * Получает данные из локального хранилища платформы. * * @param _controller - контроллер приложения * @returns данные, сохранённые ранее */ getLocalStorage<TStorageResult = unknown>(_controller: BotController): TStorageResult | Promise<TStorageResult>; /** * Сохраняет данные в локальное хранилище платформы. * * @param _data - данные для сохранения * @param _controller - контроллер приложения */ setLocalStorage<TStorageData>(_data: TStorageData, _controller: BotController): void | Promise<void>; /** * Флаг, указывающий, что платформа голосовая (например, Алиса, Маруся). */ static isVoice(): boolean; }