Skip to content

kapp.users ​

Récupérer et manipuler les viewers (User) du channel : pseudo, avatar, monnaie interne, modération.

Service partagé appli + widget. La persistance par viewer et les scopes applicatifs dépendent du contexte. En appli, utiliser kapp.userDataStorageV2.get(user.id) / set(user.id, data). user.getAppData() / user.setAppData() sont dépréciés et restent sur V1. En widget, persiste via kapp.variables. Pour une appli avec plugins, migrer ensemble ces getters, les écritures userDataStorageV2 et le helper V3 : son KappappsHost.data() retourne les données viewers V2 dans appli_data. Les helpers V1/V2 et les objets User historiques ne basculent pas automatiquement. V1 et V2 ne sont plus synchronisés après la copie initiale.

Quand l'utiliser (vs alternative) ​

  • Côté widget, kapp.triggerRequest.setter te donne déjà le User qui a déclenché — pas besoin de get() pour lui.
  • kapp.users.get(login) : récupérer un viewer par son login (ex. argument d'une commande).

Méthodes ​

  • get(login: string, method = 'login'): Promise<User | null> — un viewer par login. async.
  • get(logins: string[]): Promise<User[]> — plusieurs viewers. async.
  • get(id: number, 'id'): Promise<User | null> — par id Twitch. async.
  • getActiveUsers(options): User[] — viewers actifs récemment. sync.
  • getViewersDashboardUrl(): string : URL publique de la page viewers du channel, à citer dans le chat. sync.
  • moderation : versions par login des actions de l'objet User, par exemple await kapp.users.moderation.timeout(login, durée, raison). Méthodes : timeout / untimeout, warn, vip(login, durée?) / unvip, mod(login, durée?) / unmod, blacklist / unblacklist, ban / unban. Mêmes scopes que les méthodes User ci-dessous.
  • items.use(login, user_item_id, args = '') : utilise un item possédé par le viewer (identifiant de l'instance possédée, pas de l'item du catalogue). Scope d'appli items:manage. async.

Objet User ​

Synchrones (propriétés / getters, pas d'await) :

  • .id, .login, .display_name ; getId(), getLogin(), getDisplayName(), isModerator(), getRole(), isGranted(role), isActive().
  • onUpdate(callback) : callback(user) à chaque mise à jour de ce viewer par le serveur (monnaie, rôle, items…).

Async (touchent le réseau → await) :

  • getProfileImageUrl(): Promise<string>, getCurrency(): Promise<number>, getRankingPoints(): Promise<number>, getBroadcasterType(): Promise<string>, getItems(), getAvatarData().
  • Chargés depuis le serveur au premier appel : getGamesPlayed(), getGamesWon() (parties Kappapps), getBanTime() (durée restante de timeout), isBlacklist(), getFollowAnnounce() (annonce de follow activée), getAiBotContext() (contexte personnalisé du bot IA), isDeveloper(), isOfficialDeveloper().
  • getSubscriptionStatus(): Promise<{ subscribed, tier, is_gift }> — statut d'abonnement Twitch live (tier: 1|2|3|null).
  • getFollowStatus(): Promise<{ following, followed_at }> — statut de follow Twitch live (followed_at ISO-8601 ou null).
  • getAvatarPng(options?): Promise<string> — avatar Kappapps (le perso customisé, pas la pdp Twitch) rendu en PNG, renvoyé en data URL utilisable en <img src> dans l'appli (ou convertie en Blob via kapp.Utils.Media.base64ToBlob). Options : width/height (512), animation ('Idle'), equip: ['weapon'|'bow'|'shield'], flipX, trim (true), padding, settleDelay (300 ms), timeout.
  • Actions monnaie : addCurrency(n), removeCurrency(n), setCurrency(n) (renvoient this). Scope d'appli currency:manage.
  • Items : addItem(item, quantité?), removeItem(item). Scope d'appli items:manage.
  • Avertissement : setWarning(raison) avec moderation:manage. VIP/modérateur : setVip() / setModerator() et leurs retraits avec chat-roles:manage.
  • Blacklist Kappapps du channel : await user.setBlacklist(true) ajoute le viewer ; await user.setBlacklist(false) le retire. Sans argument (ou avec undefined), setBlacklist() ajoute le viewer. user.removeBlacklist() et kapp.users.moderation.unblacklist(login) permettent aussi le retrait ; kapp.users.moderation.blacklist(login) permet l'ajout. Les méthodes User renvoient le User et les refus du backend rejettent la Promise. Scope d'appli : blacklist:manage ; les widgets ne déclarent pas de scopes applicatifs.
  • Ban définitif du chat Twitch : setBan(raison?) ou kapp.users.moderation.ban(login, raison), accessibles aux widgets et à toutes les applis. Les applis déclarent moderation:ban dès le contrat de manifeste 4 ; les versions antérieures restent exemptées jusqu'à leur prochaine nouvelle version. Ce scope est distinct de moderation:manage et hard-moderation:manage. Les autorisations Twitch et les protections du viewer restent applicables.
  • Débannissement Twitch : await user.removeBan() ou await kapp.users.moderation.unban(login), avec le même scope moderation:ban et les mêmes exemptions que le ban. Ces méthodes utilisent DELETE /ban/v1 et retirent la sanction Twitch active, même sans timeout enregistré dans Kappapps. Twitch retire aussi un timeout par cette opération. removeBan() renvoie le User ; unban() ne renvoie pas de valeur. Un refus du backend ou de Twitch rejette la Promise.
  • Timeouts : setTimeout(durée, raison?) / removeTimeout() et kapp.users.moderation.timeout() / untimeout() utilisent moderation:manage pour les applis (exemption des contrats antérieurs à 2). Les widgets ne déclarent pas de scopes. La route historique DELETE /timeout/v1 reste compatible : elle peut aussi lever un ban permanent, avec cette permission historique.
  • Rôle Kappapps du channel : setRole(role) ou kapp.users.role.set(login, role), accessibles aux widgets et aux applis officielles uniquement. Une appli tierce reçoit 403 quels que soient ses scopes et son ancienneté. Valeurs attribuables : admin, animator, ou null pour retirer le rôle ; le rôle superadmin du streamer ne s'attribue pas par cet appel.
  • Les widgets sont configurés par le streamer ou ses administrateurs et ne déclarent pas de scopes applicatifs : leurs droits de bannissement et de gestion des rôles sont conservés.
  • Appli uniquement, déprécié : getAppData() / setAppData() (V1). Pour V2, lire/écrire explicitement kapp.userDataStorageV2.

Exemple (V2, exécutable) ​

js
const user = await kapp.users.get('toto');
if (user) {
    const [avatar, coins, sub, follow] = await Promise.all([ // getters réseau en parallèle
        user.getProfileImageUrl(),
        user.getCurrency(),
        user.getSubscriptionStatus(),
        user.getFollowStatus(),
    ]);
    console.log(user.display_name, avatar, coins, sub, follow);
}

Pièges ​

  • getProfileImageUrl() = photo de profil Twitch ; getAvatarPng() = avatar Kappapps (perso Spine). Ne pas confondre les deux.
  • Le PNG de getAvatarPng() reste dans l'appli : le visual des annonces/notifications n'accepte ni data URL ni URL externe (seulement médiathèque, asset d'appli, CDN Twitch) — il sera retiré silencieusement.
  • getAvatarPng() charge Phaser + le module avatar au premier appel (quelques centaines de Ko) et rend une frame hors écran : garde le résultat en variable plutôt que de rappeler la méthode, et ne l'appelle pas dans une boucle sur tous les viewers.
  • get(x, 'id') avec un id non numérique (NaN, undefined, string non chiffrée) ne part pas en réseau : unitaire → résout null, batch → entrées invalides ignorées (warn console). Assainis quand même tes ids (Number.isFinite) avant l'appel.
  • Ne fais pas await user.getDisplayName() : c'est synchrone. À l'inverse, getProfileImageUrl / getCurrency SONT async.
  • Parallélise les getters réseau avec Promise.all plutôt que des await en série.
  • getSubscriptionStatus() / getFollowStatus() ne sont jamais cachés : chaque appel interroge Twitch. Ne les appelle pas en boucle sur tous les viewers. En appli, ils exigent channel-stats:read dans le manifeste ; en widget, il n'y a pas de scope applicatif. Dans les deux cas, la Promise est rejetée si le streamer doit reconnecter sa chaîne pour accorder le scope Twitch correspondant.
  • getAppData / setAppData = anciennes données V1, même si l'appli utilise la V2 ailleurs. User ne bascule pas automatiquement.
  • Anciennes API : kapp.getUsers(login) → await kapp.users.get(login) ; kapp.updateUsersData(...) → actions User / kapp.userDataStorageV2 (appli) / kapp.variables (widget).