action.json и pad.json
Каждый ключ двух файлов, которые Vovó читает из папки или zip-архива, создан из кода самой Vovó, поэтому всегда соответствует этой версии. Vovó проверяет каждый файл при получении и отклоняет его фразой о том, что не так; незнакомый ключ она молча пропускает, а редактор, читающий схему, его подчёркивает.
Ключ состоит из строчных латинских букв, цифр и _, а имя может содержать ещё и -; каждый не длиннее 32 символов.
Чтобы редактор подсказывал ключи и подчёркивал ошибки, укажите схему в начале файла, как в примерах. vovo dev записывает action.schema.json рядом с частями действия; в исходном коде Vovó обе схемы лежат в папке api.
action.json
Манифест действия: как оно называется, что слушает, что запрашивает и что предлагает ведущему стрим. Он лежит рядом с index.html, style.css, script.js и files/, в пакете или папке.
{
"$schema": "./action.schema.json",
"name": "Raffle",
"id": "example.raffle",
"version": "1.2.0",
"api": 1,
"author": "A maker",
"site": "https://example.com/raffle",
"description": "!join in chat joins the wheel; the panel draws the winner.",
"license": "MIT",
"triggers": ["chat", "timer"],
"bindings": [
{ "event": "chat", "filter": [{ "field": "text", "op": "starts", "value": "!join" }] },
{ "event": "timer", "filter": [{ "field": "every", "op": "is", "value": 300 }] }
],
"permissions": ["chat.send"],
"controls": [
{ "key": "open", "label": "Entries open", "kind": "toggle" },
{ "key": "prize", "label": "Prize", "kind": "text" }
],
"settings": [
{ "key": "color", "label": "Wheel colour", "kind": "color", "default": "#840926" },
{ "key": "size", "label": "Size", "kind": "number", "min": 200, "max": 800, "step": 10, "unit": "px", "default": 420 },
{ "key": "side", "label": "Side", "kind": "choice", "options": ["Left", "Right"], "default": "Right" }
],
"panel": [
{ "kind": "control", "key": "open" },
{ "kind": "control", "key": "prize" },
{ "kind": "form", "name": "add", "label": "Put someone in", "button": "Put", "fields": [{ "key": "who", "label": "Name" }] },
{ "kind": "button", "name": "draw", "label": "Draw", "confirm": true },
{ "kind": "list", "key": "names", "label": "In the wheel", "empty": "Nobody yet", "buttons": [{ "name": "out", "label": "Take out", "confirm": true }] }
]
}
$schema(текст): Где редактор найдёт схему этого файла:./action.schema.json, которыйvovo devзаписывает рядом. Vovó здесь ничего не читает.name(текст; обязательно): Его имя, единственное в профиле: действие, принесённое с именем уже существующего, предлагает занять его место или приходит как «Raffle 2».id(текст, одна строка, не больше 64 символов): Имя, которое автор даёт действию один раз и никогда не меняет: имя автора и имя действия через точку, напримерexample.raffle, строчными буквами, цифрами и-. Принесённая новая версия находит по нему действие, которое обновляет, как бы оно к тому времени ни называлось; без него — по имени. Копия, сделанная в Vovó, его не сохраняет.version(текст, одна строка, не больше 32 символов): Собственная версия, показанная в списке действий и, когда пакет занимает место действия, рядом с той, что была у этого действия, с пометкой, если пакет той же версии или старее. Числа, разделённые точками, читаются как числа (1.10.0новее, чем1.9.2, а1.0.0-beta.1идёт перед1.0.0); при любой другой записи две версии только совпадают или нет. Без неё —1.0.0.api(целое число, 1 или больше; обязательно): Версия API, для которой оно написано:1. Версия новее, чем у этой Vovó, отклоняется с объяснением, что делать.triggers(список событий): События, которые оно слушает: события API или собственные имена, которые запускаютvovo.emitиvovo emit. Имя, похожее на одно из имён API, отклоняется с указанием нужного.control,settingsиpanelприходят к действию, объявившему элементы управления, настройки или панель, без указания в списке.bindings(список): Условия триггеров.permissions(список разрешений): Что оно может просить у Vovó; это показывается тому, кто его приносит. Незнакомое Vovó разрешение отклоняется с указанием нужного.persistent(истина или ложь): Остаётся ли оно на экране (чат, полоса цели), а не появляется, когда приходят его события; так его называют редактор и список действий. На то, как оно работает, это не влияет.operator(истина или ложь): Только для ведущего стрим: оно слушает пад, горячие клавиши, таймеры, свои элементы управления и то, что сообщают OBS и компьютер, но никогда — зрителей, чат, награды, вебхуки или событие другого действия. Триггер, который мог бы запустить кто-то другой, отклоняется.controls(список, не больше 32): Что пад меняет, пока оно работает.settings(список, не больше 32): Что тот, кто им пользуется, может менять без его кода.panel(список): Что оно показывает ведущему стрим, в «Панелях».author(текст, одна строка, не больше 80 символов): Кто его сделал.site(веб-адрес, не больше 200 символов): Где прочитать о нём подробнее или о том, кто его сделал.description(текст, одна строка, не больше 300 символов): Что оно делает, одной строкой; показывается, когда его приносят.license(текст, одна строка, не больше 100 символов): На каких условиях действие передаётся, как говорит его автор: название лицензии (MIT,CC-BY-4.0) или своя строка, показанная при импорте и в списке действий. Полный текст лицензии лежит рядом с этим файлом какLICENSE(илиLICENSE.md,LICENSE.txt), не больше 64 КБ текста, и читается из окна импорта до того, как действие будет принято. Vovó сообщает то, что написано, и никого ни к чему не обязывает: она не проверяет ни ключа, ни учётной записи, ни покупки.
Условия
Каждый триггер ещё раз, с условиями, которые все должны выполняться, чтобы он запустил действие, — так их сохраняет редактор. По одному на каждое имя в triggers, в любом порядке: если они не совпадают один к одному, все условия молча отбрасываются и каждый триггер срабатывает на всё.
event(событие; обязательно): Одно из имён вtriggers.filter(список): Его условия; без них действие запускает каждое такое событие.
Условие
Одно из полей события, сравниваемое со значением. Тексты сравниваются без учёта регистра; число, записанное текстом, читается как число.
field(текст; обязательно): Поле события, как его называет справочник API:viewers,reward,text. Интервалtimer— это полеevery(секунды, 5 или больше), а сочетаниеhotkey— полеkeys, оба сis.op(одно изis,not,above,atleast,below,atmost,contains,starts; обязательно): Как сравнивать:isиnot— как есть,above,atleast,belowиatmost— как числа,containsиstarts— как тексты.value(текст, число или истина/ложь; обязательно): С чем сравнивается поле.
Элементы управления
Что пад меняет, пока действие работает: каждое значение хранится в vovo.state под своим ключом и сообщается действию событием control, которое оно слышит без указания в списке.
key(ключ; обязательно): Где его хранитvovo.state; у двух элементов управления не может быть одного ключа.label(текст; обязательно): Как его называет пад.kind(одно изtoggle,choice,counter,text; обязательно): Включено или выключено; один из вариантов; целое число, на единицу больше или меньше за раз; или строка текста не длиннее 300 символов.options(список текстов): Варианты выбора, два или больше.max(число): Цель счётчика, показанная рядом со значением.
Настройки
Что тот, кто пользуется действием, может менять без его кода, в «Настроить»: читается как vovo.settings.<key>, как --vovo-<key> в его CSS и, для включено/выключено и выбора, как data-vovo-<key> на его документе. Выбранное остаётся с действием, а пакет несёт только значения по умолчанию. Текстовых настроек не больше восьми.
kind(одно изcolor,number,toggle,choice,text,file,font,camera; обязательно): Что это, как сказано в частях ниже.key(ключ; обязательно): Как действие её читает; у двух настроек не может быть одного ключа, и ни один не равенaccent.label(текст, не больше 60 символов; обязательно): Как её называет «Настроить».
Настройки: color
Цвет; винный цвет Vovó, #840926, если действие не укажет другой.
default(цвет,#RRGGBB): Как задано в действии; без этого — значение типа.
Настройки: number
Число от минимума до максимума с шагом; минимум, если действие не укажет другое.
min(число; обязательно): Минимум.max(число; обязательно): Максимум, больше минимума.step(число): Размер шага, больше 0; без него — 1.unit(одно изpx,%,s,ms,em,deg): Единица, с которой идёт её CSS-переменная; без неё — просто число.default(число): Как задано в действии; без этого — значение типа.
Настройки: toggle
Включено или выключено; выключено, если действие не укажет иное.
default(истина или ложь): Как задано в действии; без этого — значение типа.
Настройки: choice
Один из вариантов; первый, если действие не укажет другой.
options(список текстов, от 2 до 12; обязательно): Варианты, каждый по одному разу.default(текст): Как задано в действии; без этого — значение типа.
Настройки: text
Строка текста; пустая, если действие не укажет другую.
default(текст, одна строка, не больше 200 символов): Как задано в действии; без этого — значение типа.
Настройки: file
Картинка, звук или видео, которые выбирает тот, кто пользуется действием, не больше 50 МБ; как задано в действии — один из его собственных файлов по пути или ничего.
accept(одно изimage,sound,video): Чем это может быть: картинкой, если действие не укажет иное.default(путь к файлу илиnull): Как задано в действии; без этого — значение типа.
Настройки: font
Один из шрифтов компьютера, по семейству; Segoe UI, если действие не укажет другой.
default(текст, одна строка, не больше 64 символов): Как задано в действии; без этого — значение типа.
Настройки: camera
Одна из камер компьютера, которую выбирает в «Настроить» тот, кто пользуется действием, показанная там, где её разместит действие (vovo.camera.place, с разрешением camera.show); не больше четырёх. Приходит без камеры, поэтому значения по умолчанию нет.
Панель
Что действие показывает ведущему стрим в «Панелях» на боковой панели: элементы по порядку, каждый задан своим kind и нарисован Vovó. То, что там делают, приходит к действию событием panel, которое оно слышит без указания в списке. Элемент panel начинает ещё одну панель с элементами после него до следующего, а элементы до первого видны на каждой; tab так же делит панель на разделы. Имена кнопок, форм и кнопок списка уникальны в действии. Действие объявляет не больше 24 панелей, в каждой не больше 40 элементов и 12 вкладок.
kind(одно изpanel,tab,heading,note,control,button,form,list; обязательно): Что это, как сказано в частях ниже.
Панель: panel
Здесь начинается ещё одна панель со своим пунктом в «Панелях».
label(текст, не больше 30 символов; обязательно): Его имя в «Панелях».icon(текст, не больше 32 символов): Один из значков Vovó по имени или эмодзи; без него — значок первой кнопки действия на паде.
Панель: tab
Раздел панели: элементы после него до следующей вкладки.
label(текст, не больше 30 символов; обязательно): Её имя.
Панель: heading
Заголовок над следующими элементами, которые делят одну карточку.
label(текст, не больше 60 символов; обязательно): Его текст.
Панель: note
Строка с пояснением.
label(текст, не больше 60 символов; обязательно): Его текст.
Панель: control
Один из элементов управления действия, которым здесь пользуются как на паде.
key(ключ; обязательно): Ключ элемента управления.
Панель: button
Кнопка.
name(имя; обязательно): Что, по событиюpanel, было нажато.label(текст, не больше 60 символов; обязательно): Его текст.confirm(истина или ложь): Первое нажатие спрашивает, второе выполняет.
Панель: form
Несколько полей и кнопка: введённое уходит вместе с нажатием, в values события. Форма из одного поля заполняется прямо на панели.
name(имя; обязательно): Что, по событиюpanel, было отправлено.label(текст, не больше 60 символов; обязательно): Его текст.button(текст): Текст кнопки.fields(список, от 1 до 4; обязательно): Его поля.
Поля формы
Каждое — строка, вводимая на панели и отправляемая с формой под своим ключом.
key(имя; обязательно): Его ключ вvaluesсобытия, один раз в форме.label(текст, не больше 60 символов; обязательно): Как называется поле.
Панель: list
Список из состояния действия, по строке на элемент, хоть тысячи; у списка длиннее восьми строк есть свой поиск.
key(текст; обязательно): Ключvovo.state, где он хранится.path(текст): Внутри него — ключи до списка через точку:round.names.label(текст, не больше 60 символов; обязательно): Её имя.show(текст): Для элементов-объектов: поле, которое показывает строка, или строка с{field}, заполняемыми из каждого элемента.empty(текст): Что он показывает, пока пуст.buttons(список, не больше 3): Кнопки в каждой строке: нажатие сообщает действиюitemиindexстроки.
Кнопки списка
Кнопки в каждой строке списка.
name(имя; обязательно): Что, по событиюpanel, было нажато.label(текст, не больше 60 символов; обязательно): Его текст.confirm(истина или ложь): Первое нажатие спрашивает, второе выполняет.
pad.json
Пакет кнопок для пада: zip или папка со звуками и видео, где в корне лежит pad.json с группами и их кнопками; без него каждая папка — группа, а каждый звук или видео — кнопка с именем файла. Принесённый снова, он обновляет то, что называет, и оставляет остальное как есть.
{
"$schema": "./pad.schema.json",
"groups": [
{
"name": "Sounds",
"color": "#2F6FDB",
"buttons": [
{ "label": "Applause", "icon": "👏", "sound": "sounds/applause.mp3", "favorite": true, "hotkey": "F13" },
{ "label": "Drum roll", "sound": "sounds/drums.ogg", "volume": 130 },
{ "label": "Rain", "video": "videos/rain.mp4", "key": "luma", "loop": true }
]
},
{
"name": "Live",
"buttons": [
{ "label": "Raffle", "action": "Raffle" },
{ "label": "Entries", "action": "Raffle", "control": "open" },
{ "label": "Starting", "scene": "Starting soon" },
{ "label": "Camera", "scene": "Game", "source": "Camera" },
{ "label": "Blur", "source": "Camera", "filter": "Blur" },
{ "label": "One minute", "team": "One minute, then I'm back." }
]
}
]
}
$schema(текст): Где редактор найдёт схему этого файла, например./pad.schema.jsonрядом. Vovó здесь ничего не читает.groups(список; обязательно): Группы по порядку.
Группы
Группа пада и её кнопки по порядку.
name(текст, не больше 60 символов; обязательно): Её имя: группа профиля с таким именем, без учёта регистра, обновляется.color(цвет,#RRGGBB): Её цвет; без него существующая группа сохраняет свой, а новая получает следующий.buttons(список): Её кнопки.
Кнопки
Кнопка и то, что она делает: Vovó читает первое из найденного в таком порядке: sound; video; action с control; action; source с filter или scene с source; scene. Пакет приносит не больше 2000 кнопок.
label(текст, не больше 60 символов; обязательно): Её имя на паде: кнопка её группы с таким именем, без учёта регистра, обновляется.icon(текст): Один из значков Vovó по имени или эмодзи.sound(путь к файлу): Звук из пакета по пути внутри него: MP3, OGG, WAV, M4A, WEBM или FLAC, не больше 20 МБ.video(путь к файлу): Видео из пакета по пути внутри него: MP4 или M4V, не больше 200 МБ; оно играет поверх всей сцены.key(текст): Что убирается из видео, как это делают фильтры OBS:none,luma(чёрный),chroma(зелёный) илиchroma:#RRGGBB.loop(истина или ложь): Видео повторяется, пока его кнопку не нажмут снова.action(текст): Одно из действий профиля по имени, запускаемое как его событиеbutton.control(ключ): Сaction: один из его элементов управления по ключу, которым пользуются так же, как его кнопкой на паде.value(текст): Сcontrol, для выбора: вариант, который он выбирает; без него варианты перебираются по кругу.scene(текст): Сцена OBS по имени, выводимая в эфир.source(текст): Соscene: источник в ней, который показывают или скрывают. Сfilter: источник, на котором стоит фильтр.filter(текст): Сsource: один из его фильтров, включаемый или выключаемый.team(текст, не больше 300 символов): Строка, которую кнопка пишет в разговор команды от имени стримера, никогда в стрим или чат; на паде устройства этой кнопки нет.favorite(истина или ложь): В «Избранном» или нет; без этого существующая кнопка остаётся как есть.hotkey(текст): Сочетание, которое нажимает её из любой программы, как его обычно пишут:F13,Ctrl+Shift+1. У двух кнопок профиля не может быть одного сочетания.volume(целое число, от 0 до 150): Громкость звука или видео в процентах от файла; без неё существующая кнопка сохраняет свою.