Appearance
kapp.users
Récupérer et manipuler les viewers (User) du channel : pseudo, avatar, monnaie interne, modération.
Service partagé appli + widget. Seule différence : la persistance par viewer.
user.getAppData()/user.setAppData()ne sont disponibles qu'en appli (lèvent une erreur en widget). En widget, persiste viakapp.variables. Voirdata-storage(appli) /users(widget).
Quand l'utiliser (vs alternative)
- Côté widget,
kapp.triggerRequest.setterte donne déjà leUserqui a déclenché — pas besoin deget()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.
Objet User
Synchrones (propriétés / getters, pas d'await) :
.id,.login,.display_name;getId(),getLogin(),getDisplayName(),isModerator(),getRole(),isGranted(role),isActive().
Async (touchent le réseau → await) :
getProfileImageUrl(): Promise<string>,getCurrency(): Promise<number>,getRankingPoints(): Promise<number>,getBroadcasterType(): Promise<string>,getItems(),getAvatarData().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_atISO-8601 ounull).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 enBlobviakapp.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)(renvoientthis). - Modération :
setTimeout(durée, raison?),setVip(),setModerator(),setBan(raison?), etc. - Appli uniquement :
getAppData()/setAppData()(état persistant par viewer, propre à l'appli).
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 : levisualdes 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ésoutnull, 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/getCurrencySONT async. - Parallélise les getters réseau avec
Promise.allplutôt que desawaiten 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 exigentchannel-stats:readdans 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= appli only : en widget, utilisekapp.variables.- V1 mort :
kapp.getUsers(login)→await kapp.users.get(login);kapp.updateUsersData(...)→ actionsUser/setAppData(appli) /kapp.variables(widget).