UNPKG

umbot

Version:

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

201 lines (200 loc) 9.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.YandexImageRequest = void 0; const YandexRequest_1 = require("./YandexRequest"); const index_1 = require("../../../index"); const path_1 = __importDefault(require("path")); /** * Адрес, на который будет отправляться запрос * */ const STANDARD_URL = 'https://dialogs.yandex.net/api/v1/'; const ALLOWED_IMAGE_EXT = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']; /** * Класс отвечающий за загрузку изображений в навык Алисы. * @see (https://yandex.ru/dev/dialogs/alice/doc/resource-upload-docpage/) Смотри тут * * @class YandexImageRequest */ class YandexImageRequest extends YandexRequest_1.YandexRequest { /** * Идентификатор навыка, необходимый для корректного сохранения изображения * @see YandexRequest Базовый класс для работы с API Яндекса */ skillId; /** * Создает экземпляр класса для работы с изображениями в навыке Алисы * @param oauth Авторизационный токен для загрузки изображений * @param skillId Идентификатор навыка * @param appContext Контекст приложения * @see https://tech.yandex.ru/dialogs/alice/doc/resource-upload-docpage/ Документация по загрузке ресурсов * @see https://oauth.yandex.ru/verification_code Получение OAuth-токена */ constructor(oauth = null, skillId = null, appContext) { super(oauth, appContext); this.skillId = skillId || null; this._request.url = STANDARD_URL; } /** * Получение адреса для загрузки изображения. * * @return string */ #getImagesUrl() { return STANDARD_URL + `skills/${this.skillId}/images`; } /** * Проверка занятого места в хранилище изображений * @returns {Promise<IYandexCheckOutPlace | null>} Информация о занятом месте: * - total: общий доступный объем хранилища * - used: использованный объем хранилища */ async checkOutPlace() { this._request.url = STANDARD_URL + 'status'; const query = await this.call(); if (query?.images?.quota !== undefined) { return query.images.quota; } this._log('checkOutPlace() Не удалось проверить занятое место под изображения.'); return null; } /** * Загрузка изображения из интернета по URL * @param imageUrl URL-адрес изображения в интернете * @returns {Promise<IYandexRequestDownloadImage | null>} Информация о загруженном изображении: * - id: уникальный идентификатор изображения * - origUrl: оригинальный URL изображения * - size: размер изображения в байтах * - createdAt: дата и время загрузки */ async downloadImageUrl(imageUrl) { if (this.skillId) { this._request.url = this.#getImagesUrl(); this._request.header = index_1.Request.HEADER_JSON; this._request.post = { url: imageUrl }; const query = await this.call(); if (query?.image?.id === undefined) { this._log('downloadImageUrl() Не удалось загрузить изображение из web-ресурса.'); } else { return query.image; } } else { this._log('downloadImageUrl() Не указан навык, в который необходимо загрузить изображение.'); } return null; } /** * Загрузка изображения из локального файла * @param imageDir Путь к файлу изображения на сервере * @returns {Promise<IYandexRequestDownloadImage | null>} Информация о загруженном изображении: * - id: уникальный идентификатор изображения * - origUrl: оригинальный URL изображения * - size: размер изображения в байтах * - createdAt: дата и время загрузки */ async downloadImageFile(imageDir) { if (this.skillId) { const ext = path_1.default.extname(imageDir).toLowerCase(); if (!ALLOWED_IMAGE_EXT.includes(ext)) { this._log(`downloadImageFile() Недопустимый тип файла: ${ext}. Ожидаются изображения.`); return null; } this._request.url = this.#getImagesUrl(); this._request.header = index_1.Request.HEADER_FORM_DATA; this._request.attach = imageDir; const query = await this.call(); if (query?.image?.id === undefined) { this._log(`downloadImageFile() Не удалось загрузить изображение по пути "${imageDir}".`); } else { return query.image; } } else { this._log('downloadImageFile() Не указан навык, в который необходимо загрузить изображение.'); } return null; } /** * Получение списка всех загруженных изображений * @returns {Promise<IYandexRequestDownloadImage[] | null>} Массив с информацией о загруженных изображениях */ async getLoadedImages() { if (this.skillId) { this._request.url = this.#getImagesUrl(); const query = await this.call(); return query?.images || null; } else { this._log('getLoadedImages() Не указан навык, у которого необходимо получить все загруженные изображения.'); } return null; } /** * Удаление конкретного изображения по его идентификатору * @param imageId Идентификатор изображения для удаления * @returns {Promise<string | null>} 'ok' при успешном удалении, null при ошибке */ async deleteImage(imageId) { if (this.skillId) { if (imageId) { this._request.url = `${this.#getImagesUrl()}/${imageId}`; this._request.customRequest = 'DELETE'; const query = await this.call(); this._request.customRequest = null; if (query?.result === undefined) { this._log('deleteImage() Не удалось удалить изображение.'); } else { return query.result; } } else { this._log('deleteImage() Не выбрано изображение для удаления.'); } } else { this._log('deleteImage() Не указан навык, в котором необходимо удалить изображение.'); } return null; } /** * Удаление всех загруженных изображений * @returns {Promise<boolean>} true если все изображения успешно удалены, false при ошибке * @remarks Если при удалении произойдет ошибка, некоторые изображения могут остаться в хранилище */ async deleteImages() { if (this.skillId) { const images = await this.getLoadedImages(); if (images) { const results = await Promise.allSettled(images.map(async (image) => { try { await this.deleteImage(image.id); // Добавить задержку между запросами await new Promise((resolve) => setTimeout(resolve, 200).unref()); return true; } catch (e) { this._log(`deleteImages() Ошибка при удалении изображения "${image.id}": ${e instanceof Error ? e.message : JSON.stringify(e)}`); return false; } })); // Если хотя бы одно изображение не удалено — вернуть false return results.every((r) => r.status === 'fulfilled' && r.value); } else { this._log('deleteImages() Error: Не удалось получить загруженные изображения.'); } } else { this._log('deleteImages() Не указан навык, в котором необходимо удалить изображения.'); } return false; } } exports.YandexImageRequest = YandexImageRequest;