alice-asset-manager
Node.js API для загрузки изображений и звуков в навык Алисы.
Позволяет:
- загружать/удалять изображения и звуки
- в режиме синхронизации загружать только измененные файлы и удалять неиспользуемые файлы с сервера
- просматривать загруженные изображения/звуки на реальном устройстве через встроенный навык
Содержание
Установка
npm i alice-asset-manager --save-dev
Изображения
new ImageManager()
Создает инстанс менеджера изображений.
Параметры:
Как получить token
и skillId
- описано в документации.
Пример:
const { ImageManager } = require('alice-asset-manager');
const imageManager = new ImageManager({
token: 'TOKEN',
skillId: 'SKILL_ID',
});
.getQuota()
Получить данные о занятом месте.
await imageManager.getQuota();
.upload()
Загрузить изображение из файла.
Параметры:
Пример:
await imageManager.upload('images/test.jpg');
.getItems()
Получить список всех изображений на сервере.
await imageManager.getItems();
.getItem()
Получить данные об отдельном изображении.
Параметры:
Пример:
await imageManager.getItem('213044/aef2a365f198b4435611');
.getUrl()
Получить ссылку на изображение.
Параметры:
Пример:
imageManager.getUrl('213044/aef2a365f198b4435611');
.delete()
Удалить изображение с сервера.
Параметры:
Пример:
await imageManager.delete('213044/aef2a365f198b4435611');
.uploadChanged()
Загрузить новые и измененные изображения на сервер.
Параметры:
Как это работает:
При каждом вызове uploadChanged()
сохраняет результаты загрузки во вспомогательный файл
и при последующих вызовах использует сохраненную информацию, чтобы определить файлы для загрузки.
Чтобы избежать повторной загрузки файла при переименовании,
для каждого файла вычисляется localId
- уникальный идентификатор,
который должен сохраняться при переименовании.
По умолчанию localId
ищется в квадратных скобках []
в имени файла:
image[foo].png -> foo
Пример:
В папке images
лежат два изображения my_image_1[alice].png
и my_image_2[bob].png
.
Их localId
следующие:
my_image_1[alice].png -> alice
my_image_2[bob].png -> bob
Запускаем первую зарузку - на сервер загрузятся оба файла:
await imageManager.uploadChanged({
pattern: 'images/*.png',
dbFile: 'images.json',
});
В images.json
запишется примерно следующее:
{
"ids": {
"alice": "213044/aef2a365f198b4435611",
"bob": "834732/sdg3s44fjh234524j2h4"
},
"meta": {
"alice": {
"file": "images/my_image_1[alice].png",
"url": "https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig",
"mtimeMs": 1576249136829.0754
},
"bob": {
"file": "images/my_image_2[bob].png",
"url": "https://avatars.mds.yandex.net/get-dialogs-skill-card/834732/sdg3s44fjh234524j2h4/orig",
"mtimeMs": 1576249136830.0842
}
}
}
Файл images.json
удобно использовать в коде вашего навыка, вставляя изображения по их localId
.
Главный плюс в том, что при изменении изображения и получении нового image_id
на сервере,
в коде навыка ничего менять не нужно - новый image_id
подтянется по localId
автоматически:
const images = require('./images.json').ids;
response.card.image_id = images.alice;
Если повторно вызвать uploadChanged()
ничего не меняя, то загрузок не произойдет,
т.к. файлы не изменились и уже загружены на сервер:
await imageManager.uploadChanged({
pattern: 'images/*.png',
dbFile: 'images.json',
});
Если изменить в фоторедакторе один из файлов (например my_image_1[alice].png
),
то при вызове uploadChanged()
загрузится только этот измененный файл:
await imageManager.uploadChanged({
pattern: 'images/*.png',
dbFile: 'images.json',
});
Информация в images.json
также обновится - туда запишется новый image_id
для my_image_1[alice].png
.
Использование в коде навыка останется прежним:
const images = require('./images.json').ids;
response.card.image_id = images.alice;
Для обработки загружаемых файлов (например изменения размеров изображений) можно использовать параметр transform
.
Вот готовый пример кода для подгона изображений под размер 776х344
с использованием библиотеки Jimp:
await imageManager.uploadChanged({
pattern: 'images/*.png',
dbFile: 'images.json',
transform: async buffer => {
const image = await Jimp.read(buffer);
return image
.normalize()
.background(0xFFFFFFFF)
.contain(776, 344)
.quality(75)
.getBufferAsync(Jimp.AUTO);
}
});
.deleteUnused()
Удалить неиспользуемые изображения с сервера.
Параметры:
Работает только в связке с .uploadChanged()
.
При частых изменениях файлов и многократных вызовах .uploadChanged()
на сервере накапливаются неиспользуемые изображения.
Их нужно периодически удалять, чтобы освободить место.
Метод .deleteUnused()
сравнивает то, что записано в dbFile
с тем что лежит на сервере, и удаляет с сервера лишнее.
Пример:
В навыке используются два изображения my_image_1[alice].png
и my_image_2[bob].png
.
Они были загружены на сервер через .uploadChanged()
и информация сохранена в dbFile: 'images.json'
.
В новой версии навыка файл my_image_1[alice].png
не используется и был удален.
После вызова .uploadChanged()
в images.json
останется только запись про второй файл images/my_image_2[bob].png
:
{
"ids": {
"bob": "834732/sdg3s44fjh234524j2h4"
},
"meta": {
"bob": {
"file": "images/my_image_2[bob].png",
"url": "https://avatars.mds.yandex.net/get-dialogs-skill-card/834732/sdg3s44fjh234524j2h4/orig",
"mtimeMs": 1576249136830.0842
}
}
}
Но на сервере все еще лежат два файла.
Это нужно для того, чтобы текущая версия навыка продолжала нормально работать.
Когда новая версия навыка выкатится, запись про my_image_1[alice].png
можно удалить с сервера:
await imageManager.deleteUnused({
dbFile: 'images.json',
});
Чтобы предварительно посмотреть, какие изображения будут удалены с сервера - можно вызвать метод
с параметром dryRun: true
:
await imageManager.deleteUnused({
dbFile: 'images.json',
dryRun: true
});
.createViewServer()
Создает HTTP-сервер для просмотра загруженных изображений через навык.
Параметры:
Создаваемый HTTP-сервер позволяет быстро посмотреть загруженные изображения на экране смартфона.
Пример:
const server = imageManager.createViewServer();
server.listen(3000);
Когда сервер запустился на 3000
порту, можно используя любой прокси-навык
(например alice-dev.vitalets.xyz) проверить все изображения на смартфоне.
Изображения в навыке отсортированы по дате загрузки, поэтому в первую очередь будут показаны недавно измененные файлы.
Чтобы рядом с изображениями дополнительно выводилось имя файла и localId, нужно указать в параметрах dbFile
:
const server = imageManager.createViewServer({
dbFile: 'images.json'
});
server.listen(3000);
Чтобы сервер автоматически перезапускался при изменениях images.json
можно использовать nodemon:
nodemon ./image-server.js --watch ./images.json
Звуки
new SoundManager()
Создает инстанс менеджера звуков.
Параметры:
Как получить token
и skillId
- описано в документации.
Пример:
const { SoundManager } = require('alice-asset-manager');
const soundManager = new SoundManager({
token: 'TOKEN',
skillId: 'SKILL_ID',
});
.getQuota()
Получить данные о занятом месте.
await soundManager.getQuota();
.upload()
Загрузить звук из файла.
Параметры:
Пример:
await soundManager.upload('images/test.mp3');
.getItems()
Получить список всех звуков на сервере.
await soundManager.getItems();
.getItem()
Получить данные об отдельном звуке на сервере.
Параметры:
Пример:
await soundManager.getItem('c72463ae-01b5-48a1-a7f2-e657e4594166');
.getUrl()
Получить ссылку на звук.
Параметры:
Пример:
soundManager.getUrl('c72463ae-01b5-48a1-a7f2-e657e4594166');
.getTts()
Получить tts для вставки звука в ответ навыка.
Параметры:
Пример:
soundManager.getTts('c72463ae-01b5-48a1-a7f2-e657e4594166');
.delete()
Удалить звук с сервера.
Параметры:
Пример:
await soundManager.delete('213044/aef2a365f198b4435611');
.uploadChanged()
Загрузить новые и измененные звуки на сервер.
Параметры:
Все работает аналогично методу .uploadChanged() для изображений.
.deleteUnused()
Удалить неиспользуемые звуки с сервера.
Параметры:
Все работает аналогично методу .deleteUnused() для изображений.
.createViewServer()
Создает HTTP-сервер для прослушивания загруженных звуков через навык.
Параметры:
Все работает аналогично методу .createViewServer() для изображений.
Лицензия
MIT @ Vitaliy Potapov