Vovó API 1
Generated from Vovó's own code, so it always matches this version. Text from viewers always arrives as plain text, never as HTML.
Simple events
The same on every platform; {platform} says which one. For what only one platform has, use its own event below.
follow
Someone followed the channel. Made from twitch.follow.
user(text): Who did it, as shown on the platform.platform(platform): Where it happened.
sub
Someone subscribed, resubscribed or got a gifted sub. Made from twitch.sub.
user(text): Who did it, as shown on the platform.tier(number): 1, 2 or 3.months(number): Months subscribed in all.gift(yes or no): Whether it was a gift.platform(platform): Where it happened.
raid
Another channel raided this one. Made from twitch.raid.
user(text): Who did it, as shown on the platform.viewers(number): How many came along.platform(platform): Where it happened.
chat
A message in the chat. Made from twitch.chat.
user(text): Who did it, as shown on the platform.text(text): Their message, as plain text.parts(text and emotes): The message in parts, in order: each one'stext, and for an emote its picture too, asimage, served by Vovó.vovo.chat.parts(e)makes them into nodes to show.platform(platform): Where it happened.
tip
Someone sent money or bits. Made from twitch.cheer.
user(text): Who did it, as shown on the platform.amount(number): How much, incurrency.currency(text):bits, or a currency code such asBRL.text(text): Their message, as plain text.platform(platform): Where it happened.
Twitch
twitch.follow
A follow on Twitch.
user(text): Who did it, as shown on the platform.
twitch.sub
A sub, resub or gifted sub on Twitch.
user(text): Who did it, as shown on the platform.tier(number): 1, 2 or 3.months(number): Months subscribed in all.gift(yes or no): Whether it was a gift.gifter(text): Who gave it, when it was a gift.text(text): Their message, as plain text.
twitch.raid
A raid on Twitch.
user(text): Who did it, as shown on the platform.viewers(number): How many came along.
twitch.chat
A chat message on Twitch.
user(text): Who did it, as shown on the platform.text(text): Their message, as plain text.parts(text and emotes): The message in parts, in order: each one'stext, and for an emote its picture too, asimage, served by Vovó.vovo.chat.parts(e)makes them into nodes to show.color(text): The colour of their name,#RRGGBB.badges(text): Their badges, comma-separated:moderator,subscriber.persona(yes or no): True when the line is the persona's own, written in chat by its account.
twitch.viewers
How many people watch the stream. Twitch is read about once a minute while it is live; this arrives when the number changes, and with live false when the stream ends.
viewers(number): How many watch now.live(yes or no): True while the stream is live.
twitch.cheer
Bits cheered on Twitch.
user(text): Who did it, as shown on the platform.bits(number): How many bits.text(text): Their message, as plain text.
twitch.redemption
A channel point reward redeemed.
user(text): Who did it, as shown on the platform.reward(text): The reward's title.reward_id(text): Twitch's id for the reward, which stays the same when it is renamed.input(text): What they typed, for rewards that ask.redemption(text): Twitch's id for this redemption: the same in itstwitch.redemption.resolved.
twitch.redemption.resolved
A redemption waiting in the reward's queue was approved or rejected (rejected gives the points back).
user(text): Who did it, as shown on the platform.reward(text): The reward's title.reward_id(text): Twitch's id for the reward, which stays the same when it is renamed.input(text): What they typed, for rewards that ask.status(text):approvedorrejected.redemption(text): Twitch's id for this redemption, as in itstwitch.redemption.
twitch.hypetrain
A hype train started, moved or ended.
level(number): The current level.progress(number): Points into this level.goal(number): Points this level needs.ended(yes or no): Whether it just ended.
From Vovó and OBS
button
Its button on the pad was pressed.
label(text): The button's label.
hotkey
A global hotkey was pressed, with the game in front or not. The trigger names its combination with a condition, keys is Ctrl+Alt+1, and the app listens for it while the profile is on air.
keys(text): The combination, such asCtrl+Alt+1.
timer
A timer went off. The trigger sets how often with a condition, every is a number of seconds (5 or more); without one, it goes off every minute. It counts from when the trigger appears, and stops during panic.
every(number): Its interval, in seconds.
control
One of the action's controls was changed on the pad. Its new value is in vovo.state under the control's key too, so a page that opens later shows it. An action that offers controls receives this without adding it as a trigger.
key(text): The control's key, as the action declares it.value(a control's value): Its new value: true or false, an option, a whole number, or a line of text.
settings
What was chosen of the action's settings changed, in Customize: vovo.settings, its --vovo-<key> variables and its data-vovo-<key> attributes already hold the new values. An action that declares settings receives this without adding it as a trigger.
key(text): The setting's key, or empty when all of them went back to how the action comes.
panel
Something was done in the action's panel (panel in its manifest, shown in Panels, in the side bar): a button pressed, a form sent, or a button on one of a list's lines. Like control, an action with a panel receives this without adding it as a trigger; only whoever runs the live sets it off.
name(text): The button's, form's or line button's name, as the panel declares it.values(a control's value): A form's fields, by their keys, each one line of text; empty for a button.item(a control's value): For a list's line, the item it shows, as the state holds it.index(number): For a list's line, its place in the list, from 0; -1 otherwise.
webhook
An inbound webhook was called.
hook(text): The webhook's name.data(data): What was sent, untrusted: show it only as text.
obs.scene
OBS switched scenes.
scene(text): The scene now on air.previous(text): The scene before it.
media.track
What is playing on this computer changed: another track, or play and pause. It comes from whatever app tells Windows what it plays (Spotify, a browser, a media player).
title(text): The track's title.artist(text): Who performs it.album(text): Its album, when known.playing(yes or no): True while it plays; false when paused or stopped.art(text): The cover's address, for an<img src>; empty when there is none.source(text): The app it plays in.
audio.level
How loud the microphone is, about 20 times a second while it changes: for a mouth that moves, a meter, a glow. Vovó listens only while an open overlay shows an action waiting for this; the sound itself never leaves the computer, only how loud it is.
level(number): Loudness from 0 (silence) to 1 (as loud as it gets), on a scale that follows the ear.peak(number): The loudest moment since the last one, 0 to 1.speaking(yes or no): True while there is voice, held a moment through short pauses.
screen.color
The main screen's colour, a few times a second while it changes: for a glow or a frame that follows the game. Read only while an open overlay shows an action waiting for this; Vovó's own screen overlay is never in it.
color(text): The average colour,#RRGGBB.vivid(text): The most striking colour on screen,#RRGGBB: the average leans grey, this one does not.brightness(number): How bright the screen is, 0 (black) to 1 (white).
input.move
How the streamer moves in a game, up to 60 times a second while it changes: how far the camera turned, where they walk and whether they jump. For a scene that sways with the camera, leans when strafing and dips on a jump. It comes from the mouse, the movement keys (W, A, S and D by their place on the keyboard, whatever its layout, or the arrows, and the space bar) and the first controller connected (its sticks and its A button), always as a direction, never as which key. Read only while an open overlay shows an action waiting for this, none of the rest of the keyboard, and the keys not while Vovó's own window is in front (the mouse and a controller still are, unless the computer pauses them too). A game run as administrator may keep its input from Vovó, which runs without.
dx(number): How far the camera turned sideways since the last time, right positive: the mouse's own movement, in its counts (not the pointer's place, which a game holds still), with a controller's right stick as more of it.dy(number): How far it turned up or down, down positive.walk(number): From -1 (back) to 1 (forward): W or S, or the arrows, give 1 or -1, a controller's left stick as far as it is pushed; 0 standing.strafe(number): From -1 (left, A) to 1 (right, D), the same way.jump(yes or no): True while the space bar, or a controller's A, is held.
speech.text
What the streamer said into the microphone, written down a phrase at a time, for captions: by Whisper on this computer, or by OpenAI when the streamer chose it (Settings > Voice, Speech to text). The microphone is read only while an open overlay shows an action listening for it; each phrase comes once its pause ends, a second or two after it was said, and nothing is kept.
text(text): The phrase, as text.
screen.shared
A shared screen went on air or left it: a screen, a window or a browser tab, the streamer's own (captured by Vovó itself, or from its share page in the browser) or a guest's the streamer put on air. An action that places it (vovo.screen.place) shows it. It comes again, with on still true, when something else takes the place of what was shared.
on(yes or no): True while something is shared.kind(text): What is shared:screen,windowortab(a tab only from the share page); empty when nothing is.audio(yes or no): True when its sound comes too.guest(text): The guest whose screen it is, by the name the streamer gave them; empty for the streamer's own.
camera
A camera the action placed (vovo.camera.place) began to show in its page, or stopped: the streamer switched the camera on or off, panic turned it off, it was unplugged, or another program holds it. Like settings, an action that places a camera receives this without adding it as a trigger.
camera(text): The key of the camera setting it shows, as the action declares it.on(yes or no): True while its picture shows.
persona.answer
The persona answered someone, approved when approval is on. The app already sends it to chat and speaks it when set to; an action shows it.
persona(text): The persona's name.user(text): Who did it, as shown on the platform.question(text): What was asked.answer(text): Its answer.mood(text): What the answer asks the persona to do, from a word in brackets at its start or end ([dancing] we won!), in lower case; empty without one. The word is taken off the answer, which reaches chat and speech without it, so the personality can tell the persona to act as it speaks.
tts.spoken
The app read something aloud on air: a chat message whoever runs the live chose to read, or a reward's text once approved. It speaks it itself, in the voice for reading (Settings > Voice); an action shows it, or gives a character's mouth something to do. A line the persona itself wrote in chat comes with persona true, and the app speaks it in the persona's voice only when the persona is set to speak, so an action that voices the persona says it instead.
user(text): Who did it, as shown on the platform.text(text): What was read.source(text): Where it came from:chatorreward.persona(yes or no): True when the line is the persona's own, written in chat by its account.
music.request
A viewer asked for a song of Vovó's music player, by its reward or its chat command (Settings > Music), and this is what became of it: it waits for approval, went into the queue, started playing, was discarded, or was refused and why. Vovó itself writes nothing in chat; an action answers there, or shows who asked for what plays.
user(text): Who did it, as shown on the platform.text(text): What they wrote to ask for it.song(text): The song it found, as its title and artist; empty when it found none.state(text): What became of it:waiting,queued,playing,discardedorrefused.why(text): Why it was refused:none(no song matched),many(several did, alike),busy(they have one waiting or queued),full(too many wait),queued(the song is in line already) oragain(it played lately); empty otherwise.source(text): How they asked:rewardorchat.
sound.played
A sound button on the pad played its sound, or the one it drew of its sounds.
label(text): The button's name.button(number): The button's id.file(text): The name of the file that played, which of several when the button draws one.seconds(number): How long the file plays, in seconds to a tenth; 0 when Vovó could not tell.
video.played
A video button on the pad played its video over the stage, or the one it drew of its videos.
label(text): The button's name.button(number): The button's id.file(text): The name of the file that played, which of several when the button draws one.seconds(number): How long the file plays, in seconds to a tenth; 0 when Vovó could not tell.
remote.talk
Someone talked on air from their phone, holding its button to talk as with a walkie-talkie: their voice plays on every overlay of the live now, from the scene's page. An action shows who is talking, for as long as they talk.
name(text): The phone, by the name the streamer gave it when pairing.seconds(number): How long the voice lasts, in seconds, to a tenth.
call.started
The voice call the action asked for (vovo.call.start) is open: the model is there, hearing silence, and what it says is not played yet, until vovo.call.answer. Every page that shows the action hears this, so each can ring its telephone and answer in step.
seconds(number): The call's ceiling, in seconds, counted from when it was asked for.
call.answered
The call was answered (vovo.call.answer, from any page): the microphone reaches the model and its voice plays on the stream.
call.text
What was just said in the call, written down, a few words at a time and as it is said: the two sides may overlap. For a caption or a transcript; the voice itself is played by the scene's page.
who(text):caller, whoever runs the live at the microphone, ormodel.text(text): The words, to join to the ones before as they came.start(number): When they started in the call, in milliseconds.end(number): When they ended, in milliseconds.
call.ended
The call is over, or never opened: the voice stopped on every page.
reason(text):hangup(the action, or the app),panic,limit(its ceiling),content(the model's moderation), or anything else for a call that dropped or never opened.seconds(number): How long it lasted, from when it was asked for.
overlay.connected
An overlay page of the active profile connected: OBS loaded or reloaded a scene. The page's own actions hear it too, once they are loaded.
scene(text): The scene's name.pages(number): How many pages show that scene now.
JavaScript
vovo.on: Callslistenerevery time the event happens. The action must list the event in its triggers.vovo.show: Shows the template markeddata-name="name", with{fields}filled fromeas plain text.vovo.emit: Tells the app something happened, such as an animation ending: actions that listnamein their triggers get it. Two pages showing the action emit it once while handling one event; a call made later (when the animation ends) names the event it answers withevent, as invovo.chat.send, and with no event behind it the same name and data within 5 seconds are one event.vovo.say: Saystextaloud on the stream, in the profile's voice or the one named invoice(part of its name, a language such aspt-BR, or a voice from Piper's folder aspiper:pt_BR-faber-medium). A voice this computer cannot make (Piper or its voice missing, no OpenAI key) speaks in the profile's voice instead, and the app's console says so.pitch(0.5 to 2) makes it higher or lower at the same length,ring(0 to 1) gives it a metallic edge andsmalltakes its chest out: a character's voice from any voice. The app makes the speech once for the pages that ask for it while handling one event, and each plays the same file;eventas invovo.chat.send, and with no event behind it the same text in the same voice within 5 seconds is one speech. It resolves when the speech ends.vovo.draw: Draws one ofentries, each as likely as the others. The app draws it, so a raffle is fair, and the audit records the winner. Two pages showing the action (OBS and the preview window) that draw while handling the same event get the same answer: one winner, one draw in the audit.eventas invovo.chat.send.vovo.chat.send: Writestextin the live's chat through the app: one line, up to 500 characters, as the streamer, or withas: "persona"through the persona's own Twitch account (Integrations, under Twitch). While that account is not connected, such a line is refused and nothing is written as the streamer in its place. It needs thechat.sendpermission, and the app keeps the pace (20 lines in 30 seconds, one a second per action, whichever account writes them); a line past it, or during panic, is left out and the promise rejects. Two pages showing the action write once what they ask while handling one event; a call made after its listener returned (after anawait, in a timer) names the event it answers withevent, the very object the listener was given, or the app cannot tell it from a second one. In the editor's preview nothing is written: the editor shows the line.vovo.pad.play: Presses one of the pad's sound or video buttons, by its label (whatever the case), as a press of it would: a reward or a chat command can play a sound the streamer put on the pad, and actions listening tosound.playedhear it. Only sound and video buttons. It needs thepad.playpermission; panic refuses it, the audit says the action pressed it, and two pages handling one event press it once. The promise rejects when no such button exists.eventas invovo.chat.send. In the editor's preview nothing plays: the editor says what would.vovo.pad.busy: Shows one of this action's own buttons (an action or control button, by its label, whatever the case) as at work on the pad forseconds: its foot drains as the time goes, on the computer and on phones, so whoever runs the live knows it is still on, as a sound's button does while it plays. Withlock: true, pressing it does nothing until then, and the console says why.0ends it at once. It shows only while a page shows the action, ends with panic, and lasts 15 minutes at most; it needs no permission, since it reaches no button but the action's own. In the editor's preview the pad does not change: the editor says what would.vovo.pad.lock: Holds one of this action's own buttons (by its label, asvovo.pad.busytakes it): faded on the pad and on phones, and pressing it does nothing but say so in the console, until the action lets it go withfalse. For a state of the action rather than something under way (a button that means nothing while its part of the scene is hidden), so nothing drains: for what lasts a while,vovo.pad.busy. It holds only while a page shows the action, and panic lets go; an action that starts again says it again. In the editor's preview the pad does not change: the editor says what would.vovo.obs.source: Shows (true) or hides (false) a source in an OBS scene, by the names OBS has for them, whatever the case and the accents; withouton, it switches from how it is. It needs theobs.togglepermission; panic refuses it, the audit records it, and two pages handling one event ask once. The promise resolves once OBS was asked; a name OBS lacks is said in the console, with the one meant.eventas invovo.chat.send, in the place ofonwhen that is left out. In the editor's preview nothing changes: the editor says what would.vovo.obs.filter: Turns a filter of an OBS source on (true) or off (false), by their names in OBS; withouton, it switches from how it is. The same permission and rules asvovo.obs.source.vovo.chat.parts: A chat event's message as nodes to put in the page: its words as text, never markup, and its emotes as<img class="vovo-emote">with the emote's name asalt. A message without parts is its text.vovo.webhook.send: Asks the app to postdata, as JSON (16 KB at most), to the profile's webhook calledname, set up in Settings > Webhooks. The action never sees the address and never reaches the network. It needs thewebhookpermission; the app keeps the pace (30 a minute, one a second per action), posts once what two pages ask together, and calls nothing during panic. The promise resolves when the webhook answers 2xx and rejects otherwise.eventas invovo.chat.send. In the editor's preview nothing is posted: the editor shows what would be.vovo.screen.place: Shows the shared screen whereelementis, under the action's own drawing (so the element and what is behind it must be see-through there), and follows it as it moves;nulltakes it away.fitiscontain(all of it, the default) orcover(filling the place);radiusrounds its corners, in pixels;backgroundis a colour (#000000) for the roomcontainleaves round a picture of another shape, which is see-through without it and shows what is behind the scene. Needs thescreen.showpermission.vovo.camera.place: Shows the camera the streamer chose in one of the action's camera settings (camera, its key; the first one when not given) whereelementis, under the action's own drawing (so that part must be see-through), and follows it as it moves;nulltakes it away.fitiscover(filling the place, the default) orcontain(all of it);radiusandbackgroundas invovo.screen.place;mirrorshows it as a mirror would. The camera is opened only while some page shows it, the streamer's camera is switched on and panic is off; thecameraevent says when it shows. The action never sees its pictures nor learns which camera it is. Needs thecamera.showpermission.vovo.media.play: Plays a Twitch clip, a Twitch video or a YouTube video, from its link, in the official player, wherevovo.media.placeput it (the whole stage otherwise), with its sound; a newer one takes its place. An action that only the operator sets off plays it at once; any other waits for someone to approve it, here or from a phone allowed to, since a viewer may have asked. The promise resolves when it goes on air and rejects when it is refused, discarded, or asked during panic.secondstakes it away after that long: a player cannot tell when a clip ends;eventas invovo.chat.send. In the editor's preview it plays there, silent. Needs themedia.playpermission.vovo.media.place: Where the clip or video plays: whereelementis, under the action's own drawing (so the element and what is behind it must be see-through there), following it as it moves;nullis the whole stage again. The player keeps the video's shape inside the place;radiusrounds its corners, in pixels.vovo.media.stop: Takes the action's clip or video off the stage, on every page that shows it.vovo.call.start: Starts a voice call with an AI model, on air: whoever runs the live talks at the microphone, the model answers aloud, and the stream hears both. The app opens it with the streamer's OpenAI key and holds it; pages only play the voice.instructionsis who the model is and how it talks;voiceone of the model's voices;secondsthe call's ceiling (300 at most, which is also the default);backofficewhat a question the model hands on "to the system" is answered with;phoneplays the voice as through a telephone line. The promise resolves when the call is open, with the model hearing silence and not yet played (call.started); answer it withvovo.call.answer. It rejects when refused. It needs thecallpermission, and starts only from something whoever runs the live did by hand (a pad button, a hotkey, a control, the action's panel) or in an action that is only theirs: the call is billed by the second, takes the microphone to the model and puts what the model says on air unread. One call at a time; panic hangs up and refuses; the editor's preview makes none.eventas invovo.chat.send.vovo.call.answer: Answers the call: from here the microphone reaches the model and its voice plays on the stream. A model waits for the caller to speak; to have it speak first,instructiontells it how to answer,openingis what it should open with, andcontextwhat it should know and not say, sent in that order. Answered from one page, it is answered: a second answer is nothing.vovo.call.tell: Tells the model something during the call, in one line:context(the default) is something to know and not say,instructionsomething to follow,aloudsomething to say. Two pages handling one event tell it once;eventas invovo.chat.send.vovo.call.end: Hangs the call up: the voice stops at once on every page, andcall.endedfollows.vovo.state: An object that survives reloads of the overlay and restarts of the app. Its top-level keys are saved as you set them.vovo.settings: What was chosen of the settings the action declares (settingsinaction.json), by key, or each as the action comes: a colour as#RRGGBB, a number, true or false, an option, a line, a file's address (null for none), a font's family, and for a camera true or false, whether one is chosen, never which. Chosen in Customize, at the computer, never by the action; thesettingsevent says when it changes.
Templates
{field} inside a template is filled with that field of the event, as plain text.
data-on: On a<template>: the event that shows it, filled with that event's fields.data-name: On a<template>: the namevovo.showuses to show it from JavaScript.data-seconds: On a<template>: how long it stays before it is removed. Without it, it stays.data-vovo-<key>: On the document's root, for each on-or-off, choice or camera setting:onoroff(a camera chosen or not), or the option chosen, for selectors such ashtml[data-vovo-side="Right"] .chat.
CSS
--vovo-accent: The accent colour chosen in Vovó.--vovo-<key>: Each of the action's settings, as CSS: a colour, a number with its unit (34px), 1 or 0 for on or off or a camera chosen or not, a quoted option, line or font family, a file asurl(...)ornone.font-family: var(--vovo-font), sans-serif;
Permissions
An action asks for these in its manifest, and the person installing it approves them.
chat.send: Write in the channel's chat, through the app: as the streamer, or through the persona's own account.media.play: Clips and videos on the stream, in their official players; what the operator did not ask for waits for approval.call: Voice calls with an AI model, on air: started only by whoever runs the live, paid by the second with the streamer's OpenAI key; the microphone goes to the model, and what it says is heard unread.screen.show: Show on the stream what the streamer shares from Vovó's share page.camera.show: Show on the stream the camera of this computer the streamer chose for the action in Customize, never its pictures to the action.pad.play: Play the pad's sound and video buttons, by their labels.obs.toggle: Show or hide sources and turn filters on or off in OBS.webhook: Ask the app to call one of the profile's outbound webhooks.