Skip to content

Exemple — mini-jeu avec résultat et rewards ​

Intention : un tirage au sort express. Le streamer lance l'appli, les viewers tapent !join pendant 20 s, un gagnant est tiré, récompensé, l'appli se termine.

Pars du bootstrap courant. Conserve son index.html (SDK V2 puis script.js après AppliLoaded), style.css et les fichiers de configuration. Fusionne l'extrait de manifeste ci-dessous et remplace script.js. Cet exemple accepte 100 participants distincts au maximum, gagnant et perdants compris, pour respecter la limite de distribution des récompenses.

infos.json (extrait) ​

jsonc
{
  "app-index": "index.html",
  "scopes": ["chat:read", "chat:write", "rewards:distrib"],
  "overlay-formats": ["16:9"]
}

script.js ​

js
(async function () {
    const participants = new Map();   // id Twitch -> User
    let registrationsOpen = true;

    kapp.chat.onCommand('join', (user) => {
        if (!registrationsOpen || participants.has(user.id) || participants.size >= 100) return;
        participants.set(user.id, user);
    });

    kapp.display();
    document.body.innerHTML = '<h1 id="t">Tapez !join — 20s</h1>';

    for (let s = 20; s > 0; s--) {
        document.getElementById('t').textContent = `Tapez !join — ${s}s`;
        await wait(1000);
    }

    registrationsOpen = false;
    const list = [...participants.values()];
    if (list.length === 0) {
        await kapp.chat.say('Personne n\'a joué 😢');
        return kapp.abort('aucun participant');
    }

    const winner = list[Math.floor(Math.random() * list.length)];
    document.getElementById('t').textContent = `🎉 ${winner.display_name} gagne !`;
    await kapp.chat.say(`🎉 Bravo ${winner.display_name} !`);

    kapp.rewards.winner(winner);                 // accumulé...
    list.filter(u => u !== winner).forEach(u => kapp.rewards.loser(u));

    await wait(4000);
    await kapp.finish();                          // ...envoyé ici
})().catch(async error => {
    console.error('Tirage interrompu', error);
    await kapp.abort('Échec du tirage ou de la distribution');
});

Pourquoi ​

  • kapp.finish() explicite : l'appli se ferme d'elle-même à la fin.
  • kapp.rewards.winner/loser accumulent ; finish() déclenche l'envoi (sendRewards()).
  • kapp.display() une fois, puis on met à jour le DOM ; décompte via await wait(1000).
  • scopes contient les permissions de l'appli ; le scope de récompenses n'est pas une autorisation OAuth Twitch.
  • Les inscriptions tardives et au-delà de 100 sont ignorées. En cas d'erreur de distribution, le code abandonne sans renvoyer les récompenses automatiquement.

Vérifier ​

Lance l'appli depuis le DEV HUB, envoie !join avant la fermeture des inscriptions, puis vérifie le gagnant et la fin de l'appli. Ce scénario envoie de vrais messages Twitch et peut attribuer les récompenses configurées sur le channel ; pour vérifier les doublons et la limite de 100 sans ces effets, utilise des doublures du chat et du service de récompenses.