Skip to content

Types de préférences et options ​

Ce catalogue décrit les champs disponibles pour les applis. Les options se placent dans wuOptions, sauf mention contraire. Les propriétés communes, libellés et modèles sont dans schéma.

Texte, nombres et choix ​

TypeValeur lue au runtimeOptions
stringChaîne, éventuellement vide/null selon le réglageminLength, maxLength, confidential, password, list, regex, uniqueKey.
textareaTexte multiligneOptions de string + rows.
numberNombremin, max, step, unit (texte/localisé), confidential, uniqueKey. Les bornes peuvent référencer un autre champ numérique.
rangeNombre choisi au curseurmin, max, step, uniqueKey.
durationNombre entier en millisecondesmin, max, dans la même unité.
dualRange{ start, end }min, max.
booleanBooléenyes, no : libellés des deux états.
colorChaîne de couleurAucune option spécifique.
keywordsTableau de chaînesAucune option spécifique ; la forme stockée est une chaîne séparée par des virgules, normalisée à la lecture.
regex{ pattern, flags }Aucune option spécifique.
choiceClé du choix, ou valeur vide si facultatifchoices obligatoire, expanded, uniqueKey.
multipleChoiceTableau de clés de choixchoices obligatoire ; cartes via appearance.choicesStyle.
codeTexte du codelanguage : json, js, javascript, html, css.

minLength > 0 rend un texte requis. confidential demande une confirmation pour l'afficher ; password masque visuellement le texte. Ces options ne chiffrent pas la donnée et ne l'empêchent pas d'être reçue par l'appli.

uniqueKey est disponible uniquement sur les types indiqués. Les champs qui partagent cette clé arbitraire doivent avoir des valeurs différentes dans le formulaire.

Choix statiques et localisés ​

Fragment à ajouter dans groupItems :

json
{
  "difficulty": {
    "type": "choice",
    "label": { "fr": "Difficulté", "en": "Difficulty" },
    "default": "normal",
    "wuOptions": {
      "choices": {
        "easy": { "fr": "Facile", "en": "Easy" },
        "normal": { "fr": "Normale", "en": "Normal" },
        "hard": { "fr": "Difficile", "en": "Hard" }
      }
    }
  }
}

Le default est une clé (normal), pas son libellé. Pour multipleChoice, c'est une liste de clés. Ces deux types sont requis par défaut ; déclare required: false si l'absence de choix est autorisée.

Choix issus d'une collection ​

wuOptions.choices peut aussi être un chemin :

  • "names" : collection de chaînes ;
  • "rounds#title" : champ scalaire d'une collection de groupes ;
  • "rounds#title->label" : même valeur stockée, libellé dynamique du groupe affiché.

Prévois un default cohérent sur la collection source. Une modification de ses valeurs peut rendre un ancien choix invalide : tester la sauvegarde et la migration. Pour des choix dynamiques, garder le rendu select ; le mode cartes est réservé aux choix statiques.

Structure et champs spécialisés ​

TypeValeur / rôleRéférence et contraintes
groupObjet d'enfants nommésgroupItems obligatoire ; groupes et collections.
collectionTableau d'élémentscollectionItems obligatoire ; min/max, tri et prototypes dans collections.
mediaFile{ file, volume, position, timeline } ou null ; file peut être nullallowedTypes, withPosition ; défaut portable de bibliothèque, médias.
containerAreaZone { x, y, w, h }settings au niveau du champ ; placements.
containerAreasObjet de zones nomméessettings.areas ; placements.
announcesConfiguration hydratée portant _reftags ; annonces.
triggerRéférence de trigger persistant avec son étattypes, arguments ; triggers persistants.
dynamicTriggerDynamicTriggerConfig ou nulltypes ; détail ci-dessous, création à l'exécution.
runTarget{ type: 'app', slug } / { type: 'widget', id } / null`targets: 'app'
viewerDonnées JSON overlay du Player sélectionné ou nullAucun défaut ni option spécifique ; voir ci-dessous.
channelItemObjet JSON de l'item du channel ou nullDéfaut interdit ; aucun wuOptions spécifique.
channelVariableInstantané { id, name, value, _ref } ou nullSélection réservée au streamer, défaut interdit ; scope variables:read, voir ci-dessous.
status{ id, name, keyword } ou nullDéfaut interdit, jamais requis ; statut supprimé → null.
rolenull (tout le monde), animator, admin, superadminAucun wuOptions spécifique.
youtubeVideoDonnées de la vidéo sélectionnée ou nulldynamicLabel affiche son titre ; défaut interdit.
keyboardMacroDonnées JSON de la macro saisieÉditeur spécialisé ; aucun wuOptions spécifique.
customPanelPanneau d'édition HTML, sans valeur propresource, height, autoResize ; prefs-panels.
hiddenUuidIdentifiant techniqueInjecté par la plateforme pour les collections ; ne pas gérer soi-même leurs identités.

Ne déclare pas default / defaults pour les types dont les références dépendent du channel et qui les interdisent. Une valeur hydratée n'est pas automatiquement une instance de classe SDK.

Variable du channel choisie par le streamer ​

Un item channelVariable propose les variables du channel. Le streamer choisit la variable ; aucun default ni defaults n'est autorisé. preferences.get(path) renvoie un instantané {id, name, value, _ref} ou null. await kapp.variables.getFromPreference(path) relit sa valeur actuelle côté serveur.

Le scope variables:read protège les deux voies : sans le scope requis, l'instantané est null et l'appel dédié est refusé. L'appli ne peut pas modifier la sélection avec preferences.set, même via un groupe ou une collection. Ses méthodes variables.get/set/create sont absentes et les appels directs correspondants sont refusés. Pour ses données internes, utiliser les stockages V2. Le contrat des variables détaille les valeurs supprimées, les exemptions et les autorisations.

Viewer sélectionné ​

Utilise le sélecteur natif type: 'viewer' pour demander un viewer au streamer. La référence stockée est interne ; la lecture SDK rend du JSON, pas un objet User avec méthodes. Le Twitch ID est value.twitchUser.id, pas un hypothétique Player.id public.

js
const selected = kapp.preferences.get('winner');
const twitchId = selected?.twitchUser?.id;
if (twitchId) console.info('Viewer choisi', twitchId);

Prévois null si rien n'est choisi ou si le viewer ne peut plus être résolu. Pour des méthodes SDK, passe ensuite par le service users.

dynamicTrigger : configuration du déclencheur ​

Un item dynamicTrigger affiche le formulaire d'un trigger à l'exécution et hydrate une valeur DynamicTriggerConfig | null. La valeur est prête à être transmise directement à kapp.dynamicTriggers.createFromConfig() : ne la remodèle pas dans l'appli. La même méthode V2 accepte aussi une DynamicTriggerConfig construite manuellement ; elle n'est pas réservée aux préférences.

Pour recevoir des arguments typés propres au callback, le code de l'app peut enrichir une copie de cette valeur avec arguments : config === null ? null : {...config, arguments: schema}. Le schéma n'appartient ni à la préférence, ni à ses default/wuOptions, ni à infos.json. Il est immuable après création. Voir dynamic-triggers.md.

js
// Fragment à ajouter dans groupItems de preferences.config.js.
viewerAction: {
    type: 'dynamicTrigger',
    label: { en: 'Viewer action', fr: 'Action viewers' },
    required: false,
    wuOptions: {
        types: ['CHATCMD', 'PLDASHB'],
    },
    default: {
        type: 'CHATCMD',
        title: 'Action',
        keyword: 'action',
    },
},

wuOptions.types est optionnel : absent, les neuf types sont disponibles. S'il est présent, il doit être une liste non vide, sans doublon, composée de CHATCMD, KEYWORD, REGEX, BITSCMD, BITS, CHDASHB, PLDASHB, INTERVAL et TWREW. Avec un seul type, le sélecteur est masqué.

required: false permet au streamer de ne rien configurer : la valeur hydratée est alors null. default, defaults localisés, collections, conditions et migrations suivent les conventions habituelles des WorkUnits. Lors d'un changement de type, les champs devenus inapplicables sont retirés de la valeur stockée.

Matrice des champs ​

Tous les types portent type et title. Les champs supplémentaires sont strictement limités à cette matrice :

TypeChamps spécifiques
CHATCMD, KEYWORD, REGEXkeyword, cost, description, cooldown, user_cooldown, max_per_stream, max_per_player_per_stream, authorization_level
BITSCMDkeyword, cost, description
BITScost, description
CHDASHBaucun
PLDASHBcost, description, cooldown, user_cooldown, max_per_stream, max_per_player_per_stream
INTERVALinterval_duration
TWREWcost, prompt, color, needs_input, cooldown, max_per_stream, max_per_player_per_stream

La forme hydratée est complète et normalisée pour le type choisi :

  • cost: 0 quand le champ existe, sauf TWREW à 500 ;
  • description: '' et prompt: '' ;
  • interval_duration: 300 ;
  • color: '#546a7b' ;
  • needs_input: false pour TWREW ;
  • cooldowns, limites et authorization_level à null quand ils ne sont pas limités.

Contraintes produit : keyword est requis pour CHATCMD, KEYWORD, REGEX et BITSCMD ; l'intervalle minimal est 300 secondes ; le coût Twitch minimal est 10 ; le titre est limité à 25 caractères, ou 45 pour TWREW ; les valeurs négatives sont refusées.

Pour CHDASHB et PLDASHB, la présence d'un formulaire dépend uniquement des arguments déclarés par l'appli. L'ancien champ needs_input est accepté puis ignoré pour préserver les applis déjà compilées. Il reste pertinent pour TWREW, car sa valeur configure directement la collecte d'une saisie par Twitch.

Exemple de valeur CHATCMD réellement lue dans l'appli :

js
{
    type: 'CHATCMD',
    title: 'Action',
    keyword: 'action',
    cost: 0,
    description: '',
    cooldown: null,
    user_cooldown: null,
    max_per_stream: null,
    max_per_player_per_stream: null,
    authorization_level: null,
}

Utilisation dans une fonction async :

js
const trigger = await kapp.dynamicTriggers.createFromConfig(
    kapp.preferences.get('viewerAction') ?? null,
    async (_trigger, request, resolve) => {
        console.info('Action reçue', request.setter.display_name);
        await resolve();
        return 'ok';
    },
);

// `trigger` vaut null si la préférence optionnelle n'a pas été configurée.

Déclare le scope triggers:manage dans infos.json. Le type TWREW exige aussi l'accès à la feature Twitch Rewards du channel. Voir dynamic-triggers.md pour la séparation stricte entre cette voie V2 et create() historique.