Skip to content

Pièges transverses & API dépréciée (appli + widget) ​

Ce corpus est 100 % V2. Les formes ci-dessous traînent dans du vieux code et des exemples périmés — elles ne fonctionnent pas dans le runtime actuel. Ne les génère jamais. (Pièges spécifiques : voir PITFALLS.md côté appli et côté widget.)

Table V1 (mort) → V2 (correct) ​

V1 — à bannirV2 — correct
kapp.onChatMessage(cb)kapp.chat.onMessage((user, ev) => …)
kapp.onChatCommand(kw, cb)kapp.chat.onCommand(kw, (user, ev) => …)
kapp.playMedia(file)kapp.medias.playAudio(path, vol) / playImage(path) / playVideo(path, vol)
kapp.playAnnounceSet(...)kapp.announces.announce(data) ou directement kapp.textToSpeech.speech(...)
kapp.getUsers(login)await kapp.users.get(login)
kapp.tts.speak(...) (n'existe pas)await kapp.textToSpeech.speech('texte')
kapp.media.play({url, volume}) (n'existe pas)await kapp.medias.playAudio('chemin', volume)
alias Appli / Kapps.App / kapp.appkapp (alias k)

medias / announces / textToSpeech : les bons noms ​

  • C'est kapp.medias (pluriel), kapp.announces, kapp.textToSpeech.
  • kapp.media, kapp.tts, kapp.announce (singulier) n'existent pas → undefined → crash.

Annonces : la préférence du streamer se joue, elle ne se retouche pas ​

  • Une préférence de type announces porte une référence (_ref) vers sa configuration en base. La jouer diffuse ce que le streamer a réglé : kapp.announces.play('mes.messages.onWin', tags).
  • Retoucher l'objet avant de le passer à announce() ne change rien — la référence gagne. Pour décider du contenu toi-même, construis un objet littéral (et déclare les scopes des tracks).
  • discord.webhook d'une préférence est un booléen, jamais l'URL : le secret ne sort pas du serveur. Réécrire la préférence avec ce booléen n'efface pas le webhook du streamer, mais ne sert à rien non plus.
  • await sur une annonce = « acceptée », pas « diffusée » : la diffusion est asynchrone côté serveur.

Bibliothèque publique Kappapps (library / getLibrary / playLibrary) ​

  • Slug ≠ name : kapp.medias.get(name) cherche dans les médias du channel par nom de fichier ; getLibrary(slug) / playLibrary(slug) cherchent dans la bibliothèque publique Kappapps par slug (identifiant stable type kapp-ding). Ne les mélange pas.
  • playLibrary / getLibrary renvoient null (pas d'exception) si le slug est inconnu ou dépublié — gère ce cas.
  • Un asset dépublié disparaît du catalogue (library()) mais reste jouable là où il était déjà référencé (pref existante).

Pièges async (les deux runtimes) ​

  • Attendre les méthodes qui renvoient une Promise. Les lectures synchrones, l'affichage et l'inscription aux événements ne sont pas tous asynchrones ; vérifier leur signature. Un appel lancé sans attendre peut encore être en cours à la fin du script.
  • Getters User qui touchent le réseau : await user.getProfileImageUrl(), await user.getCurrency(), await user.getRankingPoints()… Les paralléliser : const [url, coins] = await Promise.all([u.getProfileImageUrl(), u.getCurrency()]);.
  • Getters User synchrones (pas d'await) : getId(), getLogin(), getDisplayName(), isModerator(), getRole() (et les propriétés .id, .login, .display_name).

Arguments de commande chat ​

  • chatEvent.getArg(n) est 1-based : getArg(1) = 1er argument.
  • .number() ne renvoie un nombre que pour un entier positif (/^\d+$/) ; sinon null. Pour un montant/décimal : Number(ev.getArg(1).string()).
  • chatEvent.getArg(n).user() est async (await).

Persistance par viewer : appli vs widget ​

  • user.getAppData() / user.setAppData() = appli uniquement (lèvent une erreur en widget).
  • En widget, persiste via kapp.variables (variables partagées du channel). En appli, utiliser dataStorageV2 / userDataStorageV2 ; les formes V1 historiques sont dépréciées, pas un contrat widget.

IA : endpoints retirés ​

  • Les routes /ai/leonardo/*, /ai/generator/v1 et /ai/advanced-generator/v1 sont à bannir : elles répondent 410, sans fallback. Utiliser kapp.ai.draw() ou kapp.ai.generate() ; voir IA.