UNPKG

umbot

Version:

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

182 lines (181 loc) 8.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VkAdapter = void 0; const index_1 = require("../../../index"); const API_1 = require("../API"); const Base_1 = require("../Base/Base"); const Button_1 = require("./Button"); const Card_1 = require("./Card"); const Sound_1 = require("./Sound"); const constants_1 = require("./constants"); const utils_1 = require("../Base/utils"); /** * Адаптер, обеспечивающий поддержку платформы VK. Позволяет разрабатывать чат-ботов для мессенджера ВК на TypeScript с использованием кросс-платформенного функционала: обработка текстовых запросов, работа с карточками и кнопками. * * Подключение адаптера не требует изменения существующей бизнес-логики: после интеграции * все команды и обработчики, написанные для umbot, автоматически становятся доступны для VK. * Единый интерфейс позволяет одновременно использовать одну бизнес-логику для нескольких * платформ (Viber, VK, Алиса и др.) без дублирования кода. * * Этот адаптер автоматически обрабатывает входящие webhook`и от мессенджера VK, * преобразует их в унифицированный формат фреймворка и формирует ответ, * совместимый с требованиями платформы. Подключается одной строкой и * не мешает работе других адаптеров (например, для Алисы или Маруси). * * Поддерживает: * - голосовые и текстовые запросы; * - карточки, кнопки; * * Подключается как любой другой адаптер: `bot.use(new VkAdapter(token))`. * Несколько адаптеров могут работать одновременно — система сама выберет подходящий * на основе заголовков и структуры входящего запроса. * @example * ```ts * // Простейший бот для VK, который отвечает на приветствие * import { Bot } from 'umbot'; * import { VkAdapter } from 'umbot/plugins'; * * const bot = new Bot() * .use(new VkAdapter('YOUR_VK_TOKEN', { vk_confirmation_token: 'YOUR_CONFIRMATION_TOKEN' })) * .addCommand('start', ['привет'], (_text, ctx) => { * ctx.text = 'Привет! Я твой первый бот для ВК'; * }); * * bot.start('localhost', 3000); * ``` * * @see Bot * @see BotController * @see BasePlatform */ class VkAdapter extends Base_1.BasePlatform { platformName = constants_1.T_VK; isVoice = false; limit = 30; signatureName = 'x-vk-signature'; init(appContext) { super.init(appContext); if (this._token) { appContext.appConfig.tokens[this.platformName].token = this._token; } if (this._platformOptions?.vk_confirmation_token) { appContext.appConfig.tokens[this.platformName].confirmation_token = this ._platformOptions.vk_confirmation_token; } if (this._platformOptions?.vk_api_version) { appContext.appConfig.tokens[this.platformName].api_version = this._platformOptions .vk_api_version; } } isPlatformOnQuery(query, headers) { if (headers?.['x-vk-signature']) { return true; } if (!query) { this.appContext?.logWarn(`VkAdapter.isPlatformOnQuery(): ${Base_1.EMPTY_QUERY_ERROR}`); return false; } return (query.type !== undefined && query.group_id !== undefined && (query.object !== undefined || query.secret !== undefined || query.type === 'confirmation')); } async setQueryData(query, controller) { if (!this.appContext) { console.error(`VkAdapter.setQueryData(): ${Base_1.EMPTY_CONTEXT_ERROR}`); return false; } if (!query) { controller.platformOptions.error = `VkAdapter.setQueryData(): ${Base_1.EMPTY_QUERY_ERROR}`; return false; } controller.requestObject = query; switch (query.type) { case 'confirmation': controller.platformOptions.sendInInit = this._platformOptions ?.vk_confirmation_token; return true; case 'message_new': if (query.object !== undefined) { const object = query.object; controller.userId = object.message.from_id; const rawText = object.message.text ?? ''; controller.userCommand = rawText.toLowerCase().trim(); controller.originalUserCommand = rawText.trim(); controller.messageId = object.message.id; controller.payload = (0, utils_1.tryParse)(object.message.payload || null); const user = await new API_1.VkRequest(this.appContext).usersGet(controller.userId); if (user) { const thisUser = { username: null, first_name: user.first_name || null, last_name: user.last_name || null, }; controller.nlu.setNlu({ thisUser }); } return true; } return false; case 'message_event': if (query.object?.payload) { controller.userCommand = (typeof query.object.payload === 'string' ? query.object.payload : JSON.stringify(query.object.payload))?.toLowerCase(); controller.userId = query.object.user_id; controller.payload = (0, utils_1.tryParse)(query.object.payload); controller.messageId = query.object.conversation_message_id || 0; return true; } return false; default: controller.platformOptions.error = 'VkAdapter:setQueryData(): Некорректный тип данных!'; break; } return false; } async getContent(controller) { if (!controller.skipAutoReply) { const keyboard = controller.isButtonsInit() ? controller.buttons.getButtonJson(Button_1.buttonProcessing) : null; const params = {}; if (keyboard) { params.keyboard = keyboard; } if (controller.isCardInit() && controller.card.images.length) { const attach = await controller.card.getCards(Card_1.cardProcessing, controller); if (attach.type === undefined) { params.attachments = attach; } else { params.template = attach; } } if (controller.isSoundInit() && controller.sound.sounds.length) { const attach = await controller.sound.getSounds(controller.tts, Sound_1.soundProcessing, controller); params.attachments = { ...attach, ...params.attachments }; } const vkApi = new API_1.VkRequest(this.appContext); await vkApi.messagesSend(controller.userId, index_1.Text.resize(controller.text, 4096), params); } return 'ok'; } static isVoice() { return false; } getQueryExample(query, userId, count) { return { type: 'message_new', object: { message: { from_id: +userId, text: query, id: count, }, }, }; } } exports.VkAdapter = VkAdapter;