Skip to content

SDK app V2 — choisir le bon contrat ​

Une installation conserve les préférences et les stockages de l’appli sur un channel. Une exécution possède une mémoire JavaScript temporaire : relancer l’appli ne restaure pas sa partie. Pour travailler avec le DEV HUB, compiler ou prévisualiser, partir du workflow de développement.

Concevoir : où placer chaque donnée ​

Recommandations à adapter au besoin, pas des règles :

NatureSupport conseilléÀ retenir
Réglage réutilisé d’une session à l’autrePréférencePersistant mais modifiable : par le streamer, ou par l’appli via set() quand c’est bien un réglage (y compris à la demande du plugin streamer).
Commande de session : démarrer, manche suivante, choisir un médiaPlugin streamer (emitWithReply), commande chat, triggerL’appli valide puis exécute ; l’envoi n’est pas l’exécution.
État de partie : phase, participants, score courantMémoire de l’exécution, exposée aux plugins par un instantanéL’appli est la source de vérité ; perdu au redémarrage.
Progression à reprendre, données par viewerdataStorageV2, userDataStorageV2Sauvegarder pendant l’exécution, pas seulement dans un hook final.
HistoriquelogsStorageV2Ajout seul.
Lire une variable du channel choisie par le streamerkapp.variables.getFromPreference(path)Lecture seule de la sélection ; voir variables.
Résultat pour un appelantfinish(result)Voir app-to-app.

Répondre aux plugins et aux services par une enveloppe {ok, reason} plutôt que par une exception ; identifier le viewer par le SDK, jamais par data.

Appli ou widget ? Un widget suffit pour réagir à un événement du channel avec médias, annonce ou code court. Préférences, stockages propres, pages plugins, publication au catalogue ou partie longue avec état demandent une appli.

Démarrage et sortie ​

Conserve le bootstrap : index.html écoute AppliLoaded sur document avant de charger le SDK, puis charge le script métier. Dans ce script, kapp existe déjà ; aucune fonction window.executeAppFunction n’est à déclarer. L’exemple mini-jeu précise les fichiers à conserver et remplacer.

kapp.display() affiche ; kapp.undisplay() masque sans arrêter. await kapp.finish(result?) envoie les récompenses accumulées puis termine ; await kapp.abort(reason) interrompt sans les distribuer. La fin du script ne ferme pas l’appli. Verrouille la sortie avant le premier await, nettoie tes abonnements et timers et sauvegarde les étapes importantes pendant l’exécution. Les hooks ne sont pas garantis lors d’un crash. Contrat complet : cycle de vie.

Quel contexte ? ​

PageObjets et contrat
Iframe principale de l’applikapp / k : instance SDK immuable. prefs : arbre courant des préférences. text(key, args?) : traduction dans la langue du channel. wait(ms), $ / jQuery sont aussi disponibles.
Plugin viewers ou streamerHelper V3 KappappsHost ; initialisation indépendante, voir client plugin. Ne pas y supposer les globaux de l’appli.
Panneau HTML de préférencesPont window.KappappsPrefs, voir panneaux personnalisés.

Le SDK remplace prefs au rafraîchissement : applique les préférences une première fois, puis relis-les dans kapp.preferences.EVENTS.UPDATED. Une valeur conservée auparavant ne se met pas à jour seule.

Je veux… ​

BesoinLire avant de coder
Préparer un projet et ses fichiers livrésBootstrap, projet compilé complet, livraison.
Choisir un média, un viewer, une zone ou un avatarComposants visuels, Phaser, sélecteur plugin.
Boucler un fichier ou composer une animation image + sonCompositions média : playClip, playComposition et finished.
Déclarer l’affichage, les scopes, les entrées et le manifesteManifeste, affichage et déclencheurs. Pour distinguer overlay OBS et popout interactive : kapp.overlay.isExternal().
Créer un formulaire, une condition, une collection ou une migrationPréférences, point d’entrée vers les neuf fiches ; exemple préférences + i18n.
Conserver des données globales, par viewer ou un historiqueStockages V2 : dataStorageV2, userDataStorageV2, logsStorageV2 ; exemple compteur.
Déclarer gagnants/perdants, terminer et traiter un échecRécompenses et cycle de vie.
Échanger avec un plugin, confirmer une action, resynchroniser un viewerTransports → service plugin, helper V3, protocole et reprise ; exemple quiz viewers.
Réagir à une préférence trigger ou créer un trigger temporaireTriggers persistants, dynamiques ; exemple trigger configuré.
Lancer une appli ou un widget et récupérer son résultatLanceur partagé, configuration d’appli.
Exposer des actions pilotables par la plateformeDéclarer un service, implémenter et appeler.
Vérifier un refus, un scope ou une autorisation TwitchPermissions par contexte.
Lire une variable du channel choisie par le streamer ou convertir les arguments reçusvariables.getFromPreference(path) via une préférence channelVariable, scope variables:read ; variables, arguments.
Lire/écrire le chat, gérer des commandes et des viewersChat, users, badges et emotes.
Diffuser une annonce, un média ou une voixAnnonces, médias, TTS ; configuration : annonces, médias.
Parcourir le dossier local du streamer et lire ses fichierskapp.localFiles ; contrat du dossier HUB. Sans adresse configurée : liste vide ou null.
Utiliser Twitch, sondages/prédictions ou IATwitch, polls, IA.
Lire le channel, ses teams (teams.get() puis team.getChannels(), scope teams:read), le live, les statuts ou les items ; YouTube, Discord, dashboard, Streamlabs, RCONChannel, teams et live, intégrations.
Adapter l’affichage, les événements et les ressourcesLayout partagé, vertical et formats, overlay, DOM, events, atlas, QR code.
Traduire l’appliTextset et i18n.
Mettre à niveau une ancienne appliChangements, migration des stockages et exemple de migration. Migrer ensemble écritures V2 et helper V3.

Garde-fous ​

Attends les méthodes qui renvoient une Promise ; les getters synchrones, l’affichage et l’inscription aux événements ne sont pas tous asynchrones. Vérifie les signatures dans app-sdk.d.ts.

Une réponse HTTP n’est pas une confirmation métier ; un timeout peut laisser le résultat incertain. Ne renvoie pas automatiquement une récompense ou une mutation. Un événement perdu ne sera pas forcément rejoué : prévoir un état récupérable si le besoin l’exige.

dataStorageV2.set() remplace la valeur complète. Les stockages V1 et V2 ne restent pas synchronisés après la copie initiale.

Avant livraison : pièges des applis, pièges partagés et recette du workflow. Pour une API absente de ce mémo, rechercher sa fiche ou consulter la référence SDK ; l’absence de fiche ne vaut pas garantie de disponibilité.