Actions
Une action est un morceau de HTML, CSS et JavaScript qui s'affiche dans l'overlay. Chacune tourne à part, sans réseau et sans accès aux mots de passe : ce dont elle a besoin de l'extérieur, elle le demande à Vovó.
Commencer
« Nouvelle action » en crée une vide ou une à partir d'un exemple : alertes et chat, ce qui joue, compte à rebours, objectif, tirage, compteur de morts et d'autres. L'exemple devient une copie à vous, à modifier librement.
En trois marches
Du HTML seul : un <template> qui s'affiche quand l'événement arrive, avec les champs de l'événement entre accolades.
<template data-on="follow" data-seconds="5">
<div class="alerte">{user} vient de suivre !</div>
</template>
Un peu de JavaScript : vovo.on("raid", (e) => { ... }) et vovo.show("nom", e). Et toute l'API pour le reste.
Déclencheurs
Une action ne reçoit que les événements de sa liste de déclencheurs, dans l'éditeur. Un bouton du pad est le déclencheur button.
Conditions
L'icône de curseurs à côté d'un déclencheur ouvre ses conditions : le déclencheur ne part que quand toutes sont remplies. Un raid de 50 ou plus, un message qui commence par !participer, la bonne récompense.
Minuterie et raccourci
Le déclencheur Minuterie part de temps en temps : sa condition every dit combien de secondes entre deux (sans elle, chaque minute). Le déclencheur Raccourci part sur une combinaison de touches, sa condition keys, avec le jeu au premier plan aussi.
Contrôles
Dans la carte Contrôles de l'éditeur, l'action déclare ce que le pad peut changer pendant qu'elle tourne : activé ou désactivé, un choix entre options, un compteur (avec un objectif, si vous voulez) ou un texte. Chacun est gardé dans vovo.state, sous la clé que montre la fenêtre, et chaque changement arrive comme l'événement control, sans besoin de déclencheur. Les exemples Alertes et chat, Objectif de followers et Compteur de morts montrent comment.
vovo.on("control", () =>
{
document.getElementById("chat").hidden = !vovo.state.chat;
});
Personnaliser
Une action peut laisser qui l'utilise la changer sans ouvrir son code : sa couleur, la taille de son texte, sa police, un côté de l'écran, une image ou un son à vous. La palette à côté du nom de son panneau, ou sur sa ligne dans la liste des actions, ouvre Personnaliser : une ligne par réglage, avec ce qu'il contient, sa valeur par défaut quand elle diffère, et le chemin pour y revenir. Un changement se voit aussitôt dans les scènes qui montrent l'action, sans la redémarrer, et chacun est une version que le journal annule. Il se choisit sur cet ordinateur seulement : un téléphone ou une autre Vovó ne le voit jamais. Le paquet de l'action porte les valeurs par défaut, jamais vos choix ; un paquet qui prend la place de l'action garde les choix pour lesquels il a encore la place.
La personne qui écrit l'action les déclare dans la carte Personnaliser de l'éditeur, ou sous settings dans son action.json : chacun avec un type (une couleur, un nombre d'un minimum à un maximum, activé ou désactivé, un choix, un texte, une image, un son ou une vidéo, une police), un nom, une clé et une valeur par défaut. L'action les lit dans vovo.settings, et entend l'événement settings quand l'un change ; son CSS les lit comme var(--vovo-clé) (un nombre avec son unité, comme 32px), et un activé ou désactivé ou un choix comme un attribut de la page, pour les sélecteurs :
.chat
{
color: var(--vovo-color);
font-size: var(--vovo-size);
font-family: var(--vovo-font), sans-serif;
}
html[data-vovo-side="Right"] .chat
{
right: 40px;
}
Un paramètre peut aussi être une caméra : qui utilise l'action choisit l'une des caméras de son ordinateur dans Personnaliser, et l'action la montre là où elle la place (vovo.camera.place, avec l'autorisation camera.show). Une action vient sans caméra et ne sait jamais laquelle a été choisie, ni ne voit ses images : vovo.settings dit seulement si une caméra est choisie, par true ou false. L'exemple « Caméra » est une caméra dans un cadre.
Panneaux
Ce qu'un bouton ne peut pas contenir (les noms d'un tirage, les objectifs avec leurs chiffres, un appui qui devrait demander deux fois) va dans le panneau de l'action : panel dans son manifeste, affiché dans Panneaux, dans la barre latérale (son icône au bord droit de la fenêtre, présente tant qu'une action a un panneau). Un panneau est une liste de pièces que Vovó dessine : heading et note, un control par sa clé, un button (avec confirm, il demande d'abord « Sûr ? »), un form jusqu'à quatre champs, et une list lue dans vovo.state (sa key, et un path dedans), chaque ligne avec jusqu'à trois boutons.
Une action qui a beaucoup à offrir le répartit de deux façons. { "kind": "panel", "label": "Tirage", "icon": "gift" } commence un autre panneau : une entrée à lui dans Panneaux, avec son nom et son icône (une icône de Vovó par son nom, ou un emoji ; sans elle, l'icône du premier bouton du pad de l'action). Les pièces qui suivent, jusqu'au suivant, sont à lui, et celles d'avant le premier s'affichent en haut de chacun. Dans un panneau, tab commence une section (jusqu'à douze) : les pièces qui suivent, jusqu'à l'onglet suivant, s'affichent quand elle est choisie, et celles d'avant le premier onglet s'affichent sur toutes. Ainsi, un tirage est un panneau avec une section pour le tirage, une autre pour qui participe et une autre pour qui a gagné, plutôt qu'une longue page. Une action qui ne déclare aucun { "kind": "panel" } en a un, à son nom.
L'en-tête de Panneaux nomme celui qui est devant ; un appui les liste tous, chacun disant si une scène ouverte le montre et à qui il est, avec une recherche dès qu'il y en a plus de huit. Les sections s'affichent comme des onglets sous l'en-tête : celles qui tiennent, et le reste sous « Plus ». Un titre ouvre un groupe : les pièces qui suivent partagent une carte, les boutons qui se suivent partagent une ligne, une liste est une carte à elle avec son compte, et une note va entre les cartes. Un formulaire d'un champ se tape dans le panneau même, Entrée l'envoyant, et un contrôle texte aussi ; un formulaire de plusieurs champs ouvre une petite fenêtre. Un compteur avec objectif (max) montre où il en est.
Une liste peut avoir des milliers de lignes. Une de plus de huit a sa propre recherche, qui reste en vue pendant que la liste défile. Quand elle est la dernière pièce de sa section, elle s'affiche en entier ; avec des pièces après elle, elle montre ses huit premières lignes et le chemin vers toutes, alors mettez une longue liste à la fin, ou dans une section à elle.
Ce qui y est fait arrive comme l'événement panel, sans besoin de déclencheur : son name, les values d'un formulaire, et l'item et l'index d'une ligne. Les noms sont ceux de l'action, quel que soit le panneau qui les montre. Une action n'entend son panneau que tant qu'une scène ouverte la montre, dans OBS ou dans la fenêtre d'aperçu : sans aucune, le panneau le dit, ses boutons attendent estompés et « Ouvrir l'aperçu » ouvre celui de la scène ; ses contrôles et listes s'affichent toujours, puisque Vovó les garde. Seule la personne qui mène le live s'en sert, ici ou sur un appareil à qui vous avez permis les panneaux, et rien n'atteint l'action pendant la panique.
Écrire dans le chat
Avec la permission chat.send, vovo.chat.send("...") écrit dans le chat du live en votre nom. Vovó tient le rythme (20 lignes en 30 secondes) et écrit une seule fois ce que deux pages montrant l'action demandent ; deux appuis sur un bouton font deux lignes. L'exemple Rappel dans le chat montre comment. Avec { as: "persona" }, la ligne passe plutôt par le compte Twitch propre de la persona (Intégrations, sous Twitch) : ce que la persona dit sans que ce soit une de ses réponses, comme une ligne que quelqu'un tape pour elle. Tant que ce compte n'est pas connecté, rien n'est écrit, et rien en votre nom à sa place.
Vovó distingue l'appel d'une page de celui d'une autre par l'événement que l'action traitait quand elle a appelé. Un appel fait plus tard, après un await ou dans une minuterie, dit à quel événement il répond avec { event: e }, e étant ce que votre fonction a reçu : vovo.chat.send("Bienvenue !", { event: e }). Il en va de même pour vovo.emit, vovo.pad.play, vovo.webhook.send, vovo.draw, vovo.media.play et les appels à OBS. Sans cela, deux pages écriraient la ligne deux fois, et le lien d'un modérateur attendrait dans la cloche.
Le micro, l'écran et vos mouvements
Une action peut suivre le niveau de votre micro (audio.level), la couleur de l'écran (screen.color) et vos mouvements dans un jeu (input.move) : de combien la caméra a tourné, où vous marchez et si vous sautez, à la souris, avec W, A, S et D ou les flèches, et une manette, pour qu'une scène se balance avec la caméra. Les exemples « Lueur d'écran » et « Balancement de caméra » montrent comment. Vovó ne lit chacun que tant qu'un overlay ouvert montre une action qui l'attend, et la barre d'état montre son icône en son milieu tant qu'elle le fait, avec le nom des actions dans son info-bulle. Du clavier elle ne lit que les touches de déplacement, comme une direction, jamais quelle touche, et pas tant que la fenêtre de Vovó est au premier plan, où ce que vous tapez ferait balancer la scène ; la souris et la manette la font toujours bouger alors, sauf si « Mettre le mouvement en pause quand Vovó est au premier plan » est activé (Paramètres, Général). Le son ne quitte jamais l'ordinateur, seulement son niveau.
Clips et vidéos
Avec la permission media.play, vovo.media.play(lien) montre un clip Twitch, une vidéo Twitch ou une vidéo YouTube dans son lecteur officiel, là où vovo.media.place(élément) l'a mis, avec son son. Une action que seul l'opérateur déclenche le joue aussitôt ; toute autre, que quelqu'un du chat a pu déclencher, attend dans la cloche jusqu'à ce que vous (ou un appareil autorisé à approuver) le laissiez passer. Le lecteur ne sait pas quand un clip finit : donnez { seconds: 60 }, ou appelez vovo.media.stop(). L'exemple Clips sur une télé accepte !clip et un lien des modérateurs.
Vos modérateurs sont les personnes à qui vous confiez le chat : dans Intégrations, sous Twitch, « Les liens des modérateurs passent tout de suite » laisse un lien que l'un d'eux (ou vous) colle passer à l'antenne sans attendre, quand l'action le montre à cause de son message. Désactivé tant que vous ne l'activez pas ; le lien de tous les autres attend toujours.
Appels vocaux
Avec la permission call, une action peut vous mettre au téléphone avec un modèle d'IA, à l'antenne : vous parlez au micro, il répond à voix haute, et le live entend les deux. vovo.call.start({ instructions, voice }) ouvre l'appel avec votre clé OpenAI (Intégrations, IA) ; instructions dit qui est le modèle et comment il parle. L'appel s'ouvre en silence, pour que l'action puisse d'abord faire sonner un téléphone ; vovo.call.answer() ouvre le micro et fait parler le modèle en premier, vovo.call.tell() lui dit quelque chose pendant l'appel, et vovo.call.end() raccroche. call.started, call.answered, call.text (ce qui est dit, par écrit) et call.ended disent ce qui se passe.
Ce que dit le modèle s'entend au moment où il le dit, sans que personne ne le lise avant, donc un appel ne commence que par quelque chose que vous avez fait à la main : un bouton du pad, un raccourci, un contrôle ou le panneau de l'action. Le chat, les récompenses et les webhooks n'en lancent aucun. OpenAI le facture à la seconde dès l'ouverture, donc chaque appel a un plafond (cinq minutes au plus). Tant qu'il y en a un, un téléphone rouge s'affiche dans la barre d'état : appuyez dessus, ou sur la panique, pour raccrocher aussitôt. Utilisez un casque, sinon le modèle s'entend lui-même par vos haut-parleurs.
Webhooks
Avec la permission webhook, vovo.webhook.send("nom", { ... }) demande à Vovó d'envoyer le JSON à un webhook configuré dans Paramètres, Webhooks : celui d'un salon Discord, une automatisation, un outil de votre réseau. L'adresse reste dans le coffre de cet ordinateur, hors des sauvegardes et des paquets, et l'action ne connaît que le nom. L'exemple Annoncer sur Discord montre comment.
Webhooks entrants
Dans l'autre sens, un service sur Internet prévient Vovó : dans Paramètres, Webhooks, créez un webhook entrant, copiez son adresse et collez-la dans le service (une page de dons, une boutique, un script). Chaque appel arrive aux actions comme l'événement webhook, avec hook (le nom) et data (ce qui a été envoyé). Utilisez le déclencheur webhook avec la condition que hook soit le nom. Chaque webhook a son adresse : donnez-la seulement au service qui l'appelle. Le relais garde un appel scellé pour cet ordinateur un jour au plus, donc un appel fait quand Vovó est fermée arrive à son ouverture. Ce qui arrive est le texte de quelqu'un d'autre : les actions le montrent seulement comme du texte.
Depuis un programme de cet ordinateur
Un programme de cet ordinateur peut dire à une action ce qu'il sait : un script qui lit le journal d'un jeu, un outil qui tient le score d'un tournoi, une macro. L'action écoute un événement avec un nom à elle, parmi les déclencheurs de son action.json (comme dans un dossier que suit vovo dev) :
"triggers": ["score"]
et l'entend comme n'importe quel autre :
vovo.on("score", (e) =>
{
document.getElementById("home").textContent = e.home;
document.getElementById("away").textContent = e.away;
});
Le programme le lui dit avec vovo emit, le nom et les champs :
vovo emit score home=2 away=1
Un nombre, true et false arrivent tels quels, tout le reste comme du texte. Les listes et les objets passent entiers en JSON, c'est ainsi qu'un programme l'appelle :
import json, subprocess
subprocess.run(["vovo", "emit", "score", "--fields", json.dumps({"home": 2, "away": 1})])
Il dit quelles actions l'ont entendu, et échoue (code de sortie 1, avec la raison) quand aucune ne l'entendrait : aucune action n'a ce nom parmi ses déclencheurs, leurs conditions ne sont pas remplies, ou aucune page ouverte ne les montre. Il va là où irait le propre vovo.emit d'une action, jamais pendant la panique, 30 en 10 secondes au plus, et le journal dit que la ligne de commande l'a déclenché. Une action réservée à l'opérateur ne l'entend pas. Ce qu'envoie un programme est le texte de ce programme : l'action le montre seulement comme du texte. Pour faire comme si un événement de l'API avait eu lieu, comme un follow, utilisez vovo simulate.
Aperçu et Simuler
L'éditeur montre l'action en direct pendant que vous tapez, et les boutons Simuler déclenchent les déclencheurs sans attendre le vrai événement et bougent les contrôles comme le ferait le bouton du pad. Rien de l'aperçu n'atteint le live. L'icône dans le coin du code ou de l'aperçu lui donne toute la fenêtre ; la même icône, ou Échap, le remet à côté de l'autre.
Lecteurs d'écran
Les lecteurs d'écran ne savent pas lire l'éditeur de code. Le bouton Texte brut, au-dessus du code, met à sa place une zone de texte que le Narrateur, NVDA et JAWS lisent en entier, par ligne, mot et caractère. Il démarre activé quand Windows dit qu'un lecteur d'écran tourne ; Tab passe à la suite, alors indentez avec des espaces.
Fichiers
Dans l'onglet Fichiers de l'éditeur, ajoutez des images, des sons, des vidéos et des polices. L'action les utilise par leur nom : <img src="logo.png">. Pour faire passer un de ses propres sons ou vidéos par Web Audio (un compresseur, un vumètre), demandez-le avec crossOrigin = "anonymous" avant de donner son nom : une action tourne à l'écart de tout, et pour elle même ses propres fichiers viennent d'ailleurs, ce que Web Audio entend sinon comme du silence.
Permissions
Ce que l'action peut demander à Vovó est sous Comportement : écrire dans le chat, appeler un webhook, montrer l'écran partagé, montrer une caméra, afficher des sources et activer des filtres dans OBS. Désactivé, l'action ne le peut pas.
OBS depuis une action
Avec la permission obs.toggle, vovo.obs.source("Scène", "Source", true) affiche une source dans une scène d'OBS (false la masque ; sans, il bascule), et vovo.obs.filter("Source", "Filtre", true) fait de même avec un filtre. Les noms sont ceux d'OBS, quelles que soient la casse et les accents ; un nom qu'OBS n'a pas est signalé dans la Console, avec celui qui était voulu. C'est tout ce qu'une action atteint dans OBS : elle ne peut ni arrêter le stream ni lire sa clé.
Réservée à l'opérateur
Sous Comportement, « Seulement pour qui mène le live » fait que l'action ne se déclenche que par le pad, les raccourcis, les minuteries et ses contrôles : jamais par les spectateurs, le chat, les récompenses, les webhooks ni l'événement d'une autre action. Utilisez-le pour ce que personne qui regarde ne devrait pouvoir faire, comme vider le chat ou changer de scène.
Versions
Chaque enregistrement garde une version. « Historique » ramène n'importe laquelle.
Paquets
L'icône d'export, dans la liste des actions, écrit l'action dans un .zip avec son code et ses fichiers, à donner à quelqu'un. Sous Comportement, son auteur, son site et une ligne sur ce qu'elle fait l'accompagnent, pour que qui l'importe sache ce que c'est et d'où ça vient. « Importer une action » montre ce que le paquet apporte et ce qu'il demande avant de le garder, et ouvre l'action dans l'éditeur : lisez-la avant de l'utiliser. Un paquet portant le nom d'une action que vous avez est très probablement cette action dans une version plus récente, alors il propose de prendre sa place : l'action garde ses scènes, ses boutons et son état, et la version qu'elle avait reste dans son historique. Dans un terminal, vovo export et vovo import font de même, et vovo import --replace prend la place de l'action de son nom. Un paquet fait pour d'autres peut indiquer un id sous Comportement, le nom de son auteur et celui de l'action séparés par un point (example.raffle). Sa version suivante retrouve alors l'action qu'elle met à jour même après que vous l'avez renommée, et deux actions de même nom, d'auteurs différents, ne prennent jamais la place l'une de l'autre ; vovo import --replace s'y fie aussi. Dans tous les cas, l'import dit quelle version prend la place de laquelle, et le signale quand le fichier est la même version ou une plus ancienne, et ce que vous avez choisi dans Personnaliser reste partout où la nouvelle version a encore ce réglage. Un paquet peut dire sous quelle licence il est remis : le nom d'une licence ou une ligne à vous sous Comportement, et le texte complet de la licence, choisi là depuis un fichier ou placé sous le nom LICENSE à côté de action.json dans un dossier. Qui importe l'action voit la ligne, et lit le texte depuis la boîte de dialogue d'import avant qu'elle n'arrive. Vovó dit ce que vous avez écrit et n'y contraint personne : elle ne vérifie ni clé, ni compte, ni achat, et la vente d'une action se fait en dehors de Vovó. L'icône de copie, à côté, duplique l'action et ouvre la copie dans l'éditeur, pour partir d'une action qui marche vers une variante : son code, ses fichiers et ses déclencheurs suivent ; son état, ses scènes et ses boutons non, et un déclencheur de raccourci arrive sans sa combinaison, pour qu'une touche ne déclenche pas les deux.
Dans votre propre éditeur
Une action peut s'écrire dans l'éditeur que vous préférez, ou par un build à vous : gardez ses parties dans un dossier comme un paquet les contient (action.json, index.html, style.css, script.js et files/) et, dans un terminal, lancez vovo dev avec le dossier. Vovó ouvre son éditeur sur l'action de ce nom, en la créant à partir du dossier quand le profil n'en a pas, et montre aussitôt dans l'aperçu chaque changement enregistré dans le dossier ; Simuler marche comme toujours. Comme un changement tapé ici, il n'atteint le live que quand vous Enregistrez. vovo dev stop, ou Arrêter le suivi en haut de l'éditeur, lâche le dossier.
vovo new <dossier> crée ce dossier pour vous, vierge ou à partir d'un des exemples (vovo new --list les nomme, et --from goal en prend un), et vovo check <dossier> dit d'un coup tout ce qui ne va pas dans un dossier ou un paquet, sans rien créer ni ouvrir : chaque problème avec son fichier, et ce que Vovó accepterait en l'ignorant, comme une clé dont elle n'a pas l'usage. Les deux répondent aussi quand Vovó est fermée. vovo export <action> <dossier> écrit sous la forme d'un tel dossier une action que vous avez déjà.
vovo dev écrit aussi vovo.d.ts dans le dossier, l'API telle que cette Vovó l'a, et un jsconfig.json quand il n'y en a pas, pour qu'un éditeur comme VS Code complète vovo., les noms des événements dans vovo.on(" et les champs de chaque événement. Aucun des deux ne fait partie de l'action, et un paquet ne les porte jamais ; sous gestion de versions, gardez-les ou ignorez-les à votre guise. Pour qu'un champ erroné soit souligné, ajoutez "checkJs": true aux compilerOptions du jsconfig.
Il y écrit aussi action.schema.json, qui ne fait pas non plus partie de l'action : avec "$schema": "./action.schema.json" en tête de action.json, l'éditeur complète ses clés, propose les événements et les autorisations par leur nom et souligne ce que Vovó refuserait.
L'aperçu s'ouvre aussi dans votre navigateur, à l'adresse qu'affiche vovo dev ou depuis la flèche dans le coin de l'aperçu : le même brouillon, exécuté par le même vovo qu'à l'antenne, rechargé à chaque changement, atteint par Simuler, et avec les outils de développement du navigateur (sa console, les points d'arrêt, les éléments).
Pour l'afficher dans le live
L'action doit être dans une scène, et la scène dans OBS.