Skip to content

Exemple — trigger dynamique configuré par le streamer ​

Objectif : laisser le streamer choisir entre une commande chat et un bouton viewers, puis utiliser la valeur sans duplication de validation dans l'appli.

Pars du bootstrap courant : garde index.html et ses fichiers de configuration, remplace preferences.config.js et script.js, puis compile les préférences via transpile ou watch. Fusionne les clés de manifeste ci-dessous. L'appli reste à l'écoute jusqu'à son arrêt.

preferences.config.js ​

js
module.exports = {
    type: 'group',
    groupItems: {
        viewerAction: {
            type: 'dynamicTrigger',
            label: { en: 'Viewer action', fr: 'Action viewers' },
            required: false,
            wuOptions: {
                types: ['CHATCMD', 'PLDASHB'],
            },
            default: {
                type: 'CHATCMD',
                title: 'Action',
                keyword: 'action',
            },
        },
    },
};

infos.json (extrait à fusionner) ​

json
{
    "app-index": "index.html",
    "scopes": ["triggers:manage", "chat:write"]
}

config/default_triggers.config.json ​

Pour proposer un démarrage automatique, déclarer ce default dans la configuration (ou sa source compilée par le HUB). Le streamer garde la main sur ce déclencheur ; voir les déclencheurs d'installation.

json
[{"type":"PROCESSUS"}]

script.js ​

js
(async function () {
    let gameIsRunning = true;
    kapp.onBeforeExit('*', () => { gameIsRunning = false; });

    const trigger = await kapp.dynamicTriggers.createFromConfig(
        prefs.viewerAction ?? null,
        async (_trigger, request, resolve, reject) => {
            if (!gameIsRunning) {
                await reject('La partie est terminée');
                return 'rejected';
            }

            await kapp.chat.say(`${request.setter.display_name} déclenche l'action !`);
            await resolve();
            return 'ok';
        },
    );

    if (trigger === null) {
        console.info('Le streamer a laissé le trigger optionnel désactivé.');
    }
})().catch(async error => {
    console.error('Initialisation du trigger impossible', error);
    await kapp.abort('Initialisation du trigger impossible');
});

createFromConfig(null) ne fait aucun appel réseau. Avec une configuration non nulle, le retour est typé non nullable. Un callback peut aussi être ajouté après la création avec trigger.onTrigger(callback).

Si le type TWREW est proposé, la feature Twitch Rewards doit être accessible sur le channel. createFromConfig() peut aussi recevoir une configuration V2 construite manuellement. create() est déprécié mais reste pleinement fonctionnel sur le contrat historique /trigger/v1.

Variante avec un joueur et un montant typés ​

Garde la même préférence et son choix CHATCMD/PLDASHB. Dans l'IIFE ci-dessus, remplace le bloc de création et son if (trigger === null) par celui-ci. Cette variante n'écrit pas dans le chat : triggers:manage suffit si aucune autre action de l'appli n'utilise chat:write. Le streamer peut nommer la commande give ; son schéma est ajouté uniquement dans script.js.

js
const config = prefs.viewerAction ?? null;
const trigger = await kapp.dynamicTriggers.createFromConfig(config === null ? null : {
    ...config,
    arguments: [
        {name: 'Joueur', key: 'player', type: 'Player', required: true},
        {name: 'Montant', key: 'amount', type: 'int', required: true},
    ],
}, async (_trigger, request, resolve, reject) => {
    const {player, amount, _raw} = request.args;
    // !give @viewer 25 ou saisie dans le formulaire viewers.
    // Player devient un User du SDK ; int devient un number.
    if (amount <= 0) {
        await reject('Le montant doit être positif.');
        return 'rejected';
    }
    console.info(player.display_name, amount, _raw);
    await resolve();
    return 'ok';
});

if (trigger !== null) {
    // Les réglages peuvent changer sans renvoyer le schéma.
    await trigger.update(config);
}

arguments n'est pas une préférence ni une déclaration dans infos.json. Les définitions sont ordonnées et restent immuables : recrée le trigger pour changer ses arguments. Les valeurs facultatives absentes valent null. La coercition existante est préservée (abc devient 0 pour int) ; le callback valide ici la contrainte métier positive.