API Vovó 1
Создано из собственного кода Vovó, поэтому всегда соответствует этой версии. Текст от зрителей всегда приходит как простой текст, а не как HTML.
Простые события
Одинаковы на всех платформах; {platform} говорит, на какой. Для того, что есть только у одной платформы, используйте её собственное событие ниже.
follow
Кто-то начал отслеживать канал. Источник twitch.follow.
user(текст): Кто это сделал, как показано на платформе.platform(платформа): Где это произошло.
sub
Кто-то подписался, продлил подписку или получил её в подарок. Источник twitch.sub.
user(текст): Кто это сделал, как показано на платформе.tier(число): 1, 2 или 3.months(число): Всего месяцев подписки.gift(да или нет): Был ли это подарок.platform(платформа): Где это произошло.
raid
Другой канал устроил рейд на этот. Источник twitch.raid.
user(текст): Кто это сделал, как показано на платформе.viewers(число): Сколько пришло.platform(платформа): Где это произошло.
chat
Сообщение в чате. Источник twitch.chat.
user(текст): Кто это сделал, как показано на платформе.text(текст): Сообщение как простой текст.parts(текст и эмоуты): Сообщение по частям, по порядку:textкаждой части, а для эмоута ещё и его картинка вimage, которую отдаёт Vovó.vovo.chat.parts(e)превращает их в узлы для показа.platform(платформа): Где это произошло.
tip
Кто-то отправил деньги или Bits. Источник twitch.cheer.
user(текст): Кто это сделал, как показано на платформе.amount(число): Сколько, вcurrency.currency(текст):bitsили код валюты, напримерBRL.text(текст): Сообщение как простой текст.platform(платформа): Где это произошло.
Twitch
twitch.follow
Отслеживание на Twitch.
user(текст): Кто это сделал, как показано на платформе.
twitch.sub
Подписка, продление или подарочная подписка на Twitch.
user(текст): Кто это сделал, как показано на платформе.tier(число): 1, 2 или 3.months(число): Всего месяцев подписки.gift(да или нет): Был ли это подарок.gifter(текст): Кто подарил, если это подарок.text(текст): Сообщение как простой текст.
twitch.raid
Рейд на Twitch.
user(текст): Кто это сделал, как показано на платформе.viewers(число): Сколько пришло.
twitch.chat
Сообщение в чате Twitch.
user(текст): Кто это сделал, как показано на платформе.text(текст): Сообщение как простой текст.parts(текст и эмоуты): Сообщение по частям, по порядку:textкаждой части, а для эмоута ещё и его картинка вimage, которую отдаёт Vovó.vovo.chat.parts(e)превращает их в узлы для показа.color(текст): Цвет имени,#RRGGBB.badges(текст): Значки через запятую:moderator,subscriber.persona(да или нет): True, если строка от самой персоны, написана в чат с её аккаунта.
twitch.viewers
Сколько человек смотрит стрим. Twitch опрашивается примерно раз в минуту, пока идёт стрим; событие приходит, когда число меняется, и с live = false, когда стрим заканчивается.
viewers(число): Сколько смотрят сейчас.live(да или нет): True, пока идёт стрим.
twitch.cheer
Bits, отправленные на Twitch.
user(текст): Кто это сделал, как показано на платформе.bits(число): Сколько Bits.text(текст): Сообщение как простой текст.
twitch.redemption
Получена награда за баллы канала.
user(текст): Кто это сделал, как показано на платформе.reward(текст): Название награды.reward_id(текст): Идентификатор награды в Twitch, который не меняется при переименовании.input(текст): Что ввёл зритель, для наград, которые это просят.redemption(текст): Идентификатор этого получения в Twitch: тот же, что в егоtwitch.redemption.resolved.
twitch.redemption.resolved
Получение, ждавшее в очереди награды, одобрено или отклонено (отклонение возвращает баллы).
user(текст): Кто это сделал, как показано на платформе.reward(текст): Название награды.reward_id(текст): Идентификатор награды в Twitch, который не меняется при переименовании.input(текст): Что ввёл зритель, для наград, которые это просят.status(текст):approved(одобрено) илиrejected(отклонено).redemption(текст): Идентификатор этого получения в Twitch, как в егоtwitch.redemption.
twitch.hypetrain
Хайп-трейн начался, продвинулся или закончился.
level(число): Текущий уровень.progress(число): Очки в этом уровне.goal(число): Очки, нужные для этого уровня.ended(да или нет): Закончился ли он только что.
От Vovó и OBS
button
Нажата её кнопка на паде.
label(текст): Надпись кнопки.
hotkey
Нажата глобальная горячая клавиша — с игрой на переднем плане или нет. Триггер задаёт сочетание условием, keys равно Ctrl+Alt+1, и приложение слушает его, пока профиль активен.
keys(текст): Сочетание, напримерCtrl+Alt+1.
timer
Сработал таймер. Триггер задаёт частоту условием, every — число секунд (5 или больше); без него срабатывает каждую минуту. Отсчёт идёт с момента появления триггера и останавливается во время паники.
every(число): Его интервал в секундах.
control
Один из элементов управления действия изменён на паде. Его новое значение есть и в vovo.state под ключом элемента, так что страница, открытая позже, его покажет. Действие, предлагающее элементы управления, получает это, не добавляя как триггер.
key(текст): Ключ элемента управления, как его объявляет действие.value(значение элемента управления): Новое значение: true или false, вариант, целое число или строка текста.
settings
Изменилось выбранное в настройках действия, в «Настроить»: vovo.settings, его переменные --vovo-<key> и атрибуты data-vovo-<key> уже содержат новые значения. Действие, объявляющее настройки, получает это, не добавляя как триггер.
key(текст): Ключ настройки или пусто, если все вернулись к исходным значениям действия.
panel
В панели действия что-то сделали (panel в его манифесте, показана в «Панелях» на боковой панели): нажали кнопку, отправили форму или нажали кнопку в строке списка. Как и control, действие с панелью получает это, не добавляя как триггер; запускает это только ведущий стрим.
name(текст): Имя кнопки, формы или кнопки строки, как его объявляет панель.values(значение элемента управления): Поля формы по ключам, каждое — строка текста; пусто для кнопки.item(значение элемента управления): Для строки списка — элемент, который она показывает, как он хранится в состоянии.index(число): Для строки списка — её место в списке, с 0; иначе -1.
webhook
Вызван входящий вебхук.
hook(текст): Имя вебхука.data(данные): То, что прислали, без доверия: показывайте только как текст.
obs.scene
OBS переключил сцену.
scene(текст): Сцена, которая сейчас в эфире.previous(текст): Предыдущая сцена.
media.track
Изменилось то, что играет на этом компьютере: другой трек, или воспроизведение и пауза. Приходит от любого приложения, которое сообщает Windows, что играет (Spotify, браузер, плеер).
title(текст): Название трека.artist(текст): Исполнитель.album(текст): Альбом, если известен.playing(да или нет): True, пока играет; false на паузе или при остановке.art(текст): Адрес обложки для<img src>; пусто, если её нет.source(текст): Приложение, в котором играет.
audio.level
Громкость микрофона, примерно 20 раз в секунду, пока она меняется: для двигающегося рта, индикатора, свечения. Vovó слушает, только пока открытый оверлей показывает действие, ждущее этого; сам звук никогда не покидает компьютер, только его громкость.
level(число): Громкость от 0 (тишина) до 1 (максимум), по шкале, которая следует слуху.peak(число): Самый громкий момент с прошлого раза, от 0 до 1.speaking(да или нет): True, пока есть голос; держится мгновение в коротких паузах.
screen.color
Цвет основного экрана, несколько раз в секунду, пока он меняется: для свечения или рамки, которые следуют за игрой. Считывается, только пока открытый оверлей показывает действие, ждущее этого; экранный оверлей самой Vovó в него не попадает.
color(текст): Средний цвет,#RRGGBB.vivid(текст): Самый яркий цвет на экране,#RRGGBB: средний тянет к серому, этот — нет.brightness(число): Яркость экрана, от 0 (чёрный) до 1 (белый).
input.move
Как стример двигается в игре, до 60 раз в секунду, пока это меняется: насколько повернулась камера, куда он идёт и прыгает ли. Для сцены, которая покачивается вместе с камерой, наклоняется при стрейфе и проседает при прыжке. Приходит от мыши, клавиш движения (W, A, S и D по их месту на клавиатуре, какой бы ни была раскладка, или стрелок, и пробела) и первого подключённого контроллера (его стиков и кнопки A), всегда как направление, а не как клавиша. Считывается, только пока открытый оверлей показывает действие, ждущее этого, ничего из остальной клавиатуры, и клавиши — не тогда, когда окно Vovó на переднем плане (мышь и контроллер — да, если компьютер не приостанавливает и их). Игра, запущенная от имени администратора, может скрывать свой ввод от Vovó, которая работает без этих прав.
dx(число): Насколько камера повернулась вбок с прошлого раза, вправо — положительно: собственное движение мыши в её отсчётах (не положение указателя, которое игра удерживает на месте), плюс правый стик контроллера.dy(число): Насколько повернулась вверх или вниз, вниз — положительно.walk(число): От -1 (назад) до 1 (вперёд): W или S, либо стрелки, дают 1 или -1, левый стик контроллера — насколько отклонён; 0 на месте.strafe(число): От -1 (влево, A) до 1 (вправо, D), так же.jump(да или нет): True, пока удерживается пробел или кнопка A контроллера.
speech.text
Что стример сказал в микрофон, записанное по фразам, для субтитров: Whisper на этом компьютере или OpenAI, если стример выбрал его («Настройки > Голос», «Речь в текст»). Микрофон считывается, только пока открытый оверлей показывает действие, которое это слушает; каждая фраза приходит, когда заканчивается её пауза, через секунду-две после сказанного, и ничего не сохраняется.
text(текст): Фраза в виде текста.
screen.shared
Общий экран вышел в эфир или ушёл из него: экран, окно или вкладка браузера — собственный экран стримера (захваченный самой Vovó или со страницы показа в браузере) или экран гостя, которого стример вывел в эфир. Действие, которое его размещает (vovo.screen.place), его показывает. Оно приходит снова, по-прежнему с истинным on, когда что-то другое занимает место того, что показывалось.
on(да или нет): True, пока что-то показывается.kind(текст): Что показывается:screen,windowилиtab(вкладка — только со страницы показа); пусто, если ничего.audio(да или нет): True, если идёт и звук.guest(текст): Гость, чей это экран, под именем, которое дал ему стример; пусто для экрана самого стримера.
camera
Камера, которую действие разместило (vovo.camera.place), появилась на его странице или пропала: стример включил или выключил камеру, паника её выключила, её отключили или её использует другая программа. Как и settings, действие, которое размещает камеру, получает это, не добавляя как триггер.
camera(текст): Ключ настройки камеры, которую оно показывает, как его объявляет действие.on(да или нет): true, пока её изображение видно.
persona.answer
Персона ответила кому-то, с одобрением, если оно включено. Приложение само отправляет ответ в чат и озвучивает его, если так настроено; действие его показывает.
persona(текст): Имя персоны.user(текст): Кто это сделал, как показано на платформе.question(текст): Что спросили.answer(текст): Её ответ.mood(текст): Что ответ просит сделать персону, по слову в квадратных скобках в начале или в конце ([dancing] мы победили!), строчными буквами; пусто, если его нет. Слово убирается из ответа, который попадает в чат и речь без него, так что характер может велеть персоне действовать, пока она говорит.
tts.spoken
Приложение прочитало что-то вслух в эфире: сообщение из чата, которое ведущий выбрал для чтения, или текст награды после одобрения. Оно произносит это само, голосом для чтения («Настройки > Голос»); действие это показывает или даёт работу рту персонажа. Строка, которую сама персона написала в чат, приходит с persona = true, и приложение произносит её голосом персоны, только если персоне задано говорить, так что действие, озвучивающее персону, говорит её вместо приложения.
user(текст): Кто это сделал, как показано на платформе.text(текст): Что прочитано.source(текст): Откуда пришло:chatилиreward.persona(да или нет): True, если строка от самой персоны, написана в чат с её аккаунта.
music.request
Зритель заказал трек из музыкального плеера Vovó, через награду или команду в чате («Настройки > Музыка»), и вот что с заказом стало: ждёт одобрения, попал в очередь, начал играть, был отклонён, или не принят и почему. Сама Vovó ничего не пишет в чат; действие отвечает там или показывает, кто заказал то, что играет.
user(текст): Кто это сделал, как показано на платформе.text(текст): Что написали, чтобы заказать.song(текст): Найденный трек, название и исполнитель; пусто, если ничего не нашлось.state(текст): Что с ним стало:waiting,queued,playing,discardedилиrefused.why(текст): Почему не принят:none(ни один трек не подошёл),many(подошло несколько одинаково),busy(один уже ждёт или в очереди),full(слишком много ждут),queued(трек уже в очереди) илиagain(он играл недавно); в остальных случаях пусто.source(текст): Как заказали:rewardилиchat.
sound.played
Звуковая кнопка пада воспроизвела свой звук или выбранный случайно из своих звуков.
label(текст): Название кнопки.button(число): Идентификатор кнопки.file(текст): Имя воспроизведённого файла — какой из нескольких, если кнопка выбирает случайно.seconds(число): Длительность файла в секундах с точностью до десятой; 0, если Vovó не смогла определить.
video.played
Видеокнопка пада воспроизвела своё видео поверх сцены или выбранное случайно из своих видео.
label(текст): Название кнопки.button(число): Идентификатор кнопки.file(текст): Имя воспроизведённого файла — какой из нескольких, если кнопка выбирает случайно.seconds(число): Длительность файла в секундах с точностью до десятой; 0, если Vovó не смогла определить.
remote.talk
Кто-то говорит в эфир с телефона, удерживая кнопку, как у рации: его голос звучит сейчас во всех оверлеях стрима, со страницы сцены. Действие показывает, кто говорит, пока он говорит.
name(текст): Телефон, под именем, которое стример дал ему при привязке.seconds(число): Длительность голоса в секундах, с точностью до десятой.
call.started
Голосовой звонок, запрошенный действием (vovo.call.start), открыт: модель на линии, слышит тишину, а её слова пока не воспроизводятся — до vovo.call.answer. Каждая страница, показывающая действие, получает это, чтобы каждая могла звонить своим телефоном и отвечать синхронно.
seconds(число): Предел звонка в секундах, считая с момента запроса.
call.answered
На звонок ответили (vovo.call.answer, с любой страницы): микрофон доходит до модели, а её голос звучит на стриме.
call.text
Только что сказанное в звонке, записанное по несколько слов, по мере речи: стороны могут перекрываться. Для субтитров или расшифровки; сам голос воспроизводит страница сцены.
who(текст):caller— ведущий стрим у микрофона, илиmodel.text(текст): Слова, которые нужно присоединить к предыдущим в порядке поступления.start(число): Когда они начались в звонке, в миллисекундах.end(число): Когда закончились, в миллисекундах.
call.ended
Звонок окончен или так и не открылся: голос остановлен на всех страницах.
reason(текст):hangup(действие или приложение),panic,limit(предел),content(модерация модели) или что-то иное для звонка, который оборвался или не открылся.seconds(число): Сколько длился, с момента запроса.
overlay.connected
Подключилась страница оверлея активного профиля: OBS загрузил или перезагрузил сцену. Действия этой страницы тоже это получают, когда загрузятся.
scene(текст): Название сцены.pages(число): Сколько страниц сейчас показывают эту сцену.
JavaScript
vovo.on: Вызываетlistenerкаждый раз, когда происходит событие. Событие должно быть среди триггеров действия.vovo.show: Показывает шаблон с пометкойdata-name="name", заполняя{fields}изeкак простой текст.vovo.emit: Сообщает приложению, что что-то произошло, например закончилась анимация: это получают действия, у которыхnameсреди триггеров. Две страницы, показывающие действие, отправляют это один раз, обрабатывая одно событие; вызов, сделанный позже (когда анимация закончилась), указывает черезeventсобытие, на которое отвечает, как вvovo.chat.send, а без события за ним то же имя с теми же данными в течение 5 секунд считается одним событием.vovo.say: Произноситtextвслух на стриме, голосом профиля или голосом изvoice(часть его имени, язык вродеpt-BRили голос из папки Piper, напримерpiper:pt_BR-faber-medium). Голос, который этот компьютер не может синтезировать (нет Piper или его голоса, нет ключа OpenAI), заменяется голосом профиля, и консоль приложения об этом сообщает.pitch(от 0,5 до 2) делает голос выше или ниже при той же длительности,ring(от 0 до 1) добавляет металлический оттенок, аsmallубирает грудной резонанс: голос персонажа из любого голоса. Приложение синтезирует речь один раз для страниц, которые просят её, обрабатывая одно событие, и каждая воспроизводит один и тот же файл;eventкак вvovo.chat.send, а без события за ним тот же текст тем же голосом в течение 5 секунд синтезируется один раз. Выполняется, когда речь заканчивается.vovo.draw: Выбирает один изentries, все с равной вероятностью. Выбирает приложение, поэтому розыгрыш честный, а журнал записывает победителя. Две страницы, показывающие действие (OBS и окно предпросмотра), которые разыгрывают при обработке одного события, получают один ответ: один победитель, один розыгрыш в журнале.eventкак вvovo.chat.send.vovo.chat.send: Пишетtextв чат стрима через приложение: одна строка до 500 символов, от имени стримера или, сas: "persona", через собственный аккаунт персоны в Twitch (Интеграции, под Twitch). Пока этот аккаунт не подключён, такая строка отклоняется, и вместо неё ничего не пишется от имени стримера. Нужно разрешениеchat.send, а приложение держит темп (20 строк за 30 секунд, одна в секунду на действие, каким бы аккаунтом они ни писались); строка сверх этого или во время паники пропускается, и промис отклоняется. Две страницы, показывающие действие, пишут один раз то, что просят при обработке одного события; вызов после возврата слушателя (послеawait, в таймере) указывает вeventсобытие, на которое он отвечает, — тот самый объект, полученный слушателем, иначе приложение не отличит его от второго. В предпросмотре редактора ничего не пишется: редактор показывает строку.vovo.pad.play: Нажимает одну из кнопок звука или видео на паде по надписи (без учёта регистра), как это сделало бы обычное нажатие: награда или команда чата может воспроизвести звук, который стример поставил на пад, а действия, слушающиеsound.played, это услышат. Только кнопки звука и видео. Нужно разрешениеpad.play; паника отказывает, журнал записывает, что нажало действие, а две страницы, обрабатывающие одно событие, нажимают один раз. Промис отклоняется, если такой кнопки нет.eventкак вvovo.chat.send. В предпросмотре редактора ничего не играет: редактор говорит, что сыграло бы.vovo.pad.busy: Показывает одну из кнопок этого действия (кнопку действия или элемента управления, по надписи, без учёта регистра) в работе на паде наseconds: её низ опустошается со временем, на компьютере и на телефонах, чтобы ведущий знал, что это ещё идёт, как у кнопки звука во время воспроизведения. Сlock: trueнажатие до этого момента ничего не делает, а консоль объясняет почему.0завершает сразу. Видно, только пока страница показывает действие, заканчивается с паникой и длится не больше 15 минут; разрешение не нужно, ведь это касается только кнопок самого действия. В предпросмотре редактора пад не меняется: редактор говорит, что изменилось бы.vovo.pad.lock: Блокирует одну из кнопок этого действия (по надписи, как вvovo.pad.busy): она тускнеет на паде и на телефонах, а нажатие лишь сообщает об этом в консоли, пока действие не отпустит её черезfalse. Для состояния действия, а не для чего-то идущего (кнопка, которая ничего не значит, пока её часть сцены скрыта), поэтому ничего не опустошается: для того, что длится какое-то время, —vovo.pad.busy. Блокирует, только пока страница показывает действие, а паника снимает блокировку; действие, начавшее заново, говорит это снова. В предпросмотре редактора пад не меняется: редактор говорит, что изменилось бы.vovo.obs.source: Показывает (true) или скрывает (false) источник в сцене OBS по именам, которые даёт им OBS, без учёта регистра и диакритики; безonпереключает состояние. Нужно разрешениеobs.toggle; паника отказывает, журнал записывает, а две страницы, обрабатывающие одно событие, просят один раз. Промис выполняется, как только запрос отправлен OBS; имя, которого в OBS нет, сообщается в консоли вместе с подразумеваемым.eventкак вvovo.chat.send, вместоon, если тот опущен. В предпросмотре редактора ничего не меняется: редактор говорит, что изменилось бы.vovo.obs.filter: Включает (true) или выключает (false) фильтр источника OBS по их именам в OBS; безonпереключает состояние. То же разрешение и те же правила, что уvovo.obs.source.vovo.chat.parts: Сообщение события чата в виде узлов для страницы: его слова как текст, никогда не разметка, а эмоуты как<img class="vovo-emote">с именем эмоута вalt. Сообщение без частей — это его текст.vovo.webhook.send: Просит приложение отправитьdataв виде JSON (не больше 16 КБ) на вебхук профиля с именемname, настроенный в разделе «Настройки > Вебхуки». Действие никогда не видит адрес и не выходит в сеть. Нужно разрешениеwebhook; приложение держит темп (30 в минуту, один в секунду на действие), отправляет один раз то, что просят две страницы вместе, и ничего не вызывает во время паники. Промис выполняется, когда вебхук отвечает 2xx, и отклоняется в остальных случаях.eventкак вvovo.chat.send. В предпросмотре редактора ничего не отправляется: редактор показывает, что ушло бы.vovo.screen.place: Показывает общий экран там, где находитсяelement, под рисунком самого действия (так что элемент и то, что за ним, там должны быть прозрачными), и следует за ним при движении;nullубирает его.fit—contain(целиком, по умолчанию) илиcover(заполняя место);radiusскругляет углы, в пикселях;background— цвет (#000000) для места, котороеcontainоставляет вокруг изображения другой формы: без него оно остаётся прозрачным и показывает то, что за сценой. Нужно разрешениеscreen.show.vovo.camera.place: Показывает камеру, которую стример выбрал в одной из настроек камеры действия (camera, её ключ; первая, если не указан), там, где находитсяelement, под рисунком самого действия (так что эта часть должна быть прозрачной), и следует за ним при движении;nullубирает её.fit—cover(заполняя место, по умолчанию) илиcontain(целиком);radiusиbackgroundкак вvovo.screen.place;mirrorпоказывает её как зеркало. Камера открывается, только пока какая-то страница её показывает, камера стримера включена и паника выключена; событиеcameraсообщает, когда она видна. Действие никогда не видит её изображений и не узнаёт, какая это камера. Нужно разрешениеcamera.show.vovo.media.play: Воспроизводит клип Twitch, видео Twitch или видео YouTube по ссылке, в официальном плеере, там, куда его поместилvovo.media.place(иначе на всей сцене), со звуком; более новое занимает его место. Действие, которое запускает только ведущий стрим, воспроизводит его сразу; любое другое ждёт, пока кто-нибудь одобрит, здесь или с телефона, которому это разрешено, ведь его мог попросить зритель. Промис выполняется, когда видео выходит в эфир, и отклоняется, если его отклонили, отбросили или запросили во время паники.secondsубирает его через это время: плеер не знает, когда кончается клип;eventкак вvovo.chat.send. В предпросмотре редактора оно играет там без звука. Нужно разрешениеmedia.play.vovo.media.place: Где воспроизводится клип или видео: там, где находитсяelement, под рисунком самого действия (так что элемент и то, что за ним, там должны быть прозрачными), следуя за ним при движении;nullснова означает всю сцену. Плеер сохраняет форму видео внутри места;radiusскругляет углы, в пикселях.vovo.media.stop: Убирает со сцены клип или видео действия на всех страницах, которые его показывают.vovo.call.start: Начинает голосовой звонок с ИИ-моделью в эфире: ведущий стрим говорит в микрофон, модель отвечает вслух, и стрим слышит обоих. Приложение открывает звонок с ключом OpenAI стримера и держит его; страницы только воспроизводят голос.instructions— кто модель и как она говорит;voice— один из голосов модели;seconds— предел звонка (не больше 300, это же значение по умолчанию);backoffice— чем отвечать на вопрос, который модель передаёт «системе»;phoneвоспроизводит голос как через телефонную линию. Промис выполняется, когда звонок открыт, модель слышит тишину и ещё не воспроизводится (call.started); отвечайте черезvovo.call.answer. Отклоняется при отказе. Нужно разрешениеcall, и звонок начинается только с того, что ведущий сделал вручную (кнопка пада, горячая клавиша, элемент управления, панель действия), или в действии только для ведущего: звонок оплачивается посекундно, передаёт микрофон модели и выводит в эфир сказанное моделью без проверки. Один звонок за раз; паника кладёт трубку и отказывает; предпросмотр редактора звонков не совершает.eventкак вvovo.chat.send.vovo.call.answer: Отвечает на звонок: с этого момента микрофон доходит до модели, а её голос звучит на стриме. Модель ждёт, пока заговорит звонящий; чтобы она заговорила первой,instructionговорит, как ответить,opening— с чего начать, аcontext— что ей знать, но не говорить, отправляется в этом порядке. Если на звонок ответили с одной страницы, он принят: повторный ответ ничего не делает.vovo.call.tell: Сообщает модели что-то во время звонка, одной строкой:context(по умолчанию) — знать, но не говорить,instruction— выполнить,aloud— сказать. Две страницы, обрабатывающие одно событие, сообщают один раз;eventкак вvovo.chat.send.vovo.call.end: Завершает звонок: голос сразу останавливается на всех страницах, затем приходитcall.ended.vovo.state: Объект, который переживает перезагрузки оверлея и перезапуски приложения. Его ключи верхнего уровня сохраняются, как только вы их задаёте.vovo.settings: Выбранное в настройках, которые объявляет действие (settingsвaction.json), по ключу, или каждое как в действии: цвет как#RRGGBB, число, true или false, вариант, строка, адрес файла (null, если нет), семейство шрифта, а для камеры true или false — выбрана ли какая-то, но никогда какая. Выбирается в «Настроить», за компьютером, никогда самим действием; событиеsettingsсообщает, когда это меняется.
Шаблоны
{field} внутри шаблона заполняется этим полем события как простой текст.
data-on: На<template>: событие, которое его показывает, с полями этого события.data-name: На<template>: имя, по которомуvovo.showпоказывает его из JavaScript.data-seconds: На<template>: сколько он держится, прежде чем исчезнуть. Без этого остаётся.data-vovo-<key>: На корне документа, для каждой настройки вкл./выкл., выбора или камеры:onилиoff(камера выбрана или нет) либо выбранный вариант, для селекторов вродеhtml[data-vovo-side="Справа"] .chat.
CSS
--vovo-accent: Цвет акцента, выбранный в Vovó.--vovo-<key>: Каждая настройка действия в виде CSS: цвет, число с единицей (34px), 1 или 0 для вкл. или выкл. и для выбранной или невыбранной камеры, вариант, строка или семейство шрифта в кавычках, файл какurl(...)илиnone.font-family: var(--vovo-font), sans-serif;
Разрешения
Действие запрашивает их в манифесте, а тот, кто его устанавливает, их одобряет.
chat.send: Писать в чат канала через приложение: от имени стримера или через собственный аккаунт персоны.media.play: Клипы и видео на стриме, в их официальных плеерах; то, что запросил не ведущий, ждёт одобрения.call: Голосовые звонки с ИИ-моделью в эфире: начинает только ведущий стрим, оплачиваются посекундно ключом OpenAI стримера; микрофон уходит модели, а её слова звучат без проверки.screen.show: Показывать на стриме то, чем стример делится со страницы показа Vovó.camera.show: Показывать на стриме камеру этого компьютера, которую стример выбрал для действия в «Настроить», никогда не отдавая действию её изображения.pad.play: Воспроизводить кнопки звука и видео пада по их надписям.obs.toggle: Показывать или скрывать источники и включать или выключать фильтры в OBS.webhook: Просить приложение вызвать один из исходящих вебхуков профиля.