# Référence de l'éditeur de widgets

> Référence du code pour les widgets de l'éditeur KickBot : chaque nom d'événement Kick et ses données, globalValues, userVariables, les helpers de chat et l'aperçu.

Source: https://kickbot.com/fr/docs/widgets/widget-builder-reference

Cette page liste ce que ton code peut utiliser dans un widget de l'[éditeur de widgets](https://kickbot.com/fr/docs/widgets/widget-builder) KickBot : les événements `widgetEvent`, l'objet `globalValues`, l'objet `userVariables` et les helpers `window.kickbotWidget`. Chaque widget est du HTML, du CSS et du JavaScript classiques qui tournent comme source navigateur dans OBS. KickBot se connecte à Kick pour toi et envoie les événements à ton code.

## Comment un widget tourne

Quand OBS ouvre l'URL du widget, KickBot :

1. Charge la page du widget avec un fond transparent.
2. Ajoute ton CSS dans un élément `<style>` et met ton HTML dans la page.
3. Charge les données de ta chaîne depuis Kick (nombre de followers, nombre de viewers, statut du stream et chat récent) dans `globalValues`.
4. Lance ton JavaScript. Il tourne une seule fois, après l'étape 3, donc `globalValues` est prêt quand ton code démarre.
5. Envoie les événements en direct à ton code sous forme d'événements `widgetEvent` sur `document`.

Ton JavaScript peut lire deux objets sans rien importer : `globalValues` et `userVariables`. Les helpers sont sur `window.kickbotWidget`.

Limites :

| Élément | Limite |
| --- | --- |
| Largeur et hauteur | Réglées dans **Paramètres de base**. Un nouveau widget vide fait 800 × 600. La fenêtre Nouveau widget accepte jusqu'à 7680 × 4320. |
| HTML, CSS et JavaScript | Jusqu'à 2 000 000 caractères par fichier |
| Nom du widget | Jusqu'à 500 caractères |
| Fichiers des variables utilisateur | Jusqu'à 25 Mo par fichier |
| Widgets de l'éditeur avec le forfait Gratuit | 10 (sans limite avec Premium) |

## Écoute les événements

Ajoute un seul listener pour `widgetEvent` sur `document`. Chaque événement contient `event.detail` avec trois champs :

| Champ | Type | Valeur |
| --- | --- | --- |
| `event_name` | string | L'événement, par exemple `followEvent` |
| `source` | string | Toujours `kick` |
| `data` | object | Les données de l'événement (voir plus bas) |

```javascript
document.addEventListener('widgetEvent', (event) => {
    const { event_name, data } = event.detail;

    if (event_name === 'followEvent') {
        showAlert(data.user.username + ' followed!');
    }
    if (event_name === 'subEvent') {
        showAlert(data.username + ' subscribed for ' + data.months + ' months');
    }
});
```

### Liste des événements

| Nom de l'événement | Quand il se déclenche | Bouton de test |
| --- | --- | --- |
| `subEvent` | Un viewer s'abonne | Sub |
| `subGiftEvent` | Un viewer offre des subs | Sub offert |
| `kicksEvent` | Un viewer envoie des KICKs | KICKs |
| `followEvent` | Un viewer follow | Follow |
| `unfollowEvent` | Un viewer unfollow | Unfollow |
| `chatMessageEvent` | Un message est envoyé dans le chat | Message |
| `chatMessageDeletedEvent` | Un modérateur supprime un message | Message supprimé |
| `chatMessagePinnedEvent` | Un message est épinglé | Message épinglé |
| `chatMessageUnpinnedEvent` | Le message épinglé est retiré | Message désépinglé |
| `chatClearedEvent` | Un modérateur efface le chat | Chat effacé |
| `followerCountUpdatedEvent` | Kick envoie un nouveau nombre de followers | Compteur de followers mis à jour |
| `subCountUpdatedEvent` | Le nombre de subs sur Kick a changé | Compteur de subs mis à jour |
| `viewerCountUpdatedEvent` | Kick envoie un nouveau nombre de viewers | Compteur de viewers mis à jour |
| `raidEvent` | Une autre chaîne te raid (host) | Raid |
| `streamOnline` | Ton stream commence | Stream en ligne |
| `streamOffline` | Ton stream se termine | Stream hors ligne |

Il n'y a pas d'événement de tip. Pour les alertes de tip, utilise le [widget d'alerte de tip](https://kickbot.com/fr/docs/tipping/tip-alerts).

### Données des événements

Voici les données dans `event.detail.data`. Elles correspondent aux événements de test de l'éditeur. Les vrais événements peuvent avoir plus de champs. Les noms, nombres et ID ci-dessous sont des exemples.

`subEvent`

```javascript
{
    months: 1,
    username: 'viewer_one',
    chatroom_id: 3847194
}
```

`subGiftEvent`

```javascript
{
    chatroom_id: 3847194,
    gifted_usernames: ['viewer_one', 'viewer_two', 'viewer_three'],
    gifter_username: 'big_gifter'
}
```

`kicksEvent`

```javascript
{
    message: 'Great stream!',
    sender: { id: 12345678, username: 'viewer_one', username_color: '#93EBE0' },
    gift: {
        gift_id: 'full_send',
        name: 'Full Send',
        amount: 100,
        type: 'BASIC',
        tier: 'BASIC',
        character_limit: 0,
        pinned_time: 0
    },
    channel: 'channel_3984507'
}
```

`followEvent` et `unfollowEvent` (même forme ; `followers_count` est le nouveau nombre)

```javascript
{
    id: 'd4e5f6a7-89b0-12c3-d456-78901e2f3a4b',
    channel: { id: 3984507, slug: 'kickbotdev' },
    user: { id: 14873539, slug: 'viewer_one', username: 'viewer_one' },
    followers_count: 36,
    created_at: '2024-05-13T22:19:07+00:00'
}
```

`chatMessageEvent`

```javascript
{
    id: '85c884b3-7377-478c-b6aa-22b7db752b93',
    chatroom_id: 3974112,
    content: 'hello [emote:37226:KEKW]',
    type: 'message',
    created_at: '2024-05-13T22:29:52+00:00',
    sender: {
        id: 4063326,
        username: 'viewer_one',
        slug: 'viewer_one',
        identity: {
            color: '#72ACED',
            badges: [{ type: 'subscriber', text: 'Subscriber', count: 3 }]
        }
    }
}
```

Les emotes Kick sont dans `content` sous la forme `[emote:ID:NAME]`. Utilise `createChatMessageFragment` (consulte [Afficher le texte du chat en toute sécurité](#show-chat-text-safely)) pour les transformer en images.

`chatMessageDeletedEvent`

```javascript
{
    id: '9cd3788a-ecd2-4051-a162-a7ea9be8ce7a',
    message: { id: '89d6be86-63db-4581-922e-14a6c4a9c2e6' }
}
```

Utilise `data.message.id` pour retrouver et retirer le message que tu as affiché.

`chatMessagePinnedEvent` (`data.message` a la même forme que les données d'un `chatMessageEvent`)

```javascript
{
    message: {
        id: '5d798a38-ad17-45e4-8169-bda2faa85b79',
        chatroom_id: 3974112,
        content: 'This is a pinned message!',
        type: 'message',
        created_at: '2024-05-13T22:30:41+00:00',
        sender: { id: 4063326, username: 'kickbotdev', slug: 'kickbotdev', identity: { color: '#72ACED', badges: [] } }
    }
}
```

`chatMessageUnpinnedEvent` : `data` est un tableau vide (`[]`).

`chatClearedEvent`

```javascript
{ id: '47e3596f-0274-46e0-85b1-029fa3bfc5ea' }
```

`followerCountUpdatedEvent` (attention au camelCase `followersCount`)

```javascript
{ followersCount: 1532, channel_id: 4599, created_at: 1715639984 }
```

`subCountUpdatedEvent`

```javascript
{ subscriber_count: 184, channel_id: 4599 }
```

`viewerCountUpdatedEvent`

```javascript
{ viewer_count: 320, channel_id: 5937485 }
```

`raidEvent`

```javascript
{
    chatroom_id: 839485,
    optional_message: 'gg stream',
    number_viewers: 150,
    host_username: 'raiding_channel'
}
```

`streamOnline`

```javascript
{
    livestream: {
        id: 3984507,
        channel_id: 3984507,
        session_title: 'Test stream!',
        created_at: '2024-05-13T22:30:41+00:00'
    }
}
```

`streamOffline`

```javascript
{
    livestream: {
        id: 3984507,
        channel: { id: 3984507, is_banned: false }
    }
}
```

## Valeurs globales

`globalValues` contient l'état actuel de ta chaîne. KickBot le remplit avant que ton code tourne et le tient à jour quand les événements arrivent. Utilise-le pour dessiner ton widget au démarrage, avant l'arrivée du moindre événement.

```javascript
globalValues = {
    subCount: 184,
    followerCount: 1532,
    viewerCount: 320,
    lastFollower: { /* the last follow */ },
    lastSub: { /* the last sub, for example { username, months } */ },
    lastGiftedSub: { /* the last gift, for example { gifter_username, gifted_usernames } */ },
    chatMessages: [ /* chatMessageEvent payloads */ ],
    streamerInfo: {
        kick: {
            username: 'KickBotDev',
            slug: 'kickbotdev',
            profile_picture: 'https://files.kick.com/images/user/.../fullsize.webp',
            user_id: '4063326',
            channel_id: '3984507',
            chatroom_id: '3974112',
            bio: 'Channel bio',
            subscriber_badges: [ /* your channel's sub badges from Kick */ ]
        }
    },
    currentStream: {
        is_live: true,
        title: 'Stream title',
        started_at: '2026-10-24 18:00:00'
    }
}
```

| Valeur | Comment elle se met à jour |
| --- | --- |
| `subCount` | Chargée depuis Kick. Augmente de 1 à chaque `subEvent` et de 1 pour chaque sub offert, et est remise à jour par `subCountUpdatedEvent`. |
| `followerCount` | Chargée depuis Kick. Mise à jour par `followEvent`, `unfollowEvent` et `followerCountUpdatedEvent`. |
| `viewerCount` | Chargée depuis Kick (0 hors ligne). Mise à jour par `viewerCountUpdatedEvent`. |
| `lastFollower`, `lastSub`, `lastGiftedSub` | Le dernier que KickBot a vu sur ta chaîne, ou `null`. Mis à jour par l'événement correspondant. |
| `chatMessages` | Le chat récent de Kick au chargement du widget, puis chaque nouveau message. Garde les 100 plus récents. `chatClearedEvent` le vide. Pour masquer les messages supprimés, gère `chatMessageDeletedEvent` dans ton propre code. |
| `streamerInfo.kick` | Ton profil Kick. Ne change pas pendant que le widget tourne. |
| `currentStream` | Chargée depuis Kick au chargement du widget. Elle n'est pas mise à jour par `streamOnline` ni `streamOffline`. Écoute ces événements si tu as besoin de l'état du live. |

## Variables utilisateur

Les variables utilisateur sont les paramètres que les streamers voient quand ils ouvrent ton widget dans Widgets enregistrés. Tu les ajoutes sous **Variables utilisateur** dans l'éditeur. Dans ton code, lis la valeur avec `userVariables.<variable name>.value`.

```javascript
const goal = Number(userVariables.follower_goal.value);
document.body.style.color = userVariables.text_color.value;
```

Champs d'une variable :

| Champ | Ce que c'est |
| --- | --- |
| Titre | Le libellé que les streamers voient. |
| Nom de la variable | Le nom dans ton code. Lettres, chiffres et `_` uniquement. Tu ne peux plus le changer après avoir créé la variable. |
| Tooltip | Un texte d'aide en plus sous le titre. |
| Type de variable | Consulte le tableau ci-dessous. |
| Valeur par défaut | La valeur avant que le streamer la change. Elle peut être vide. |
| Obligatoire | Les streamers doivent saisir une valeur avant de pouvoir enregistrer. |

| Type | Ce que le streamer voit | `value` dans ton code |
| --- | --- | --- |
| Texte | Un champ de texte | Une string |
| Nombre | Un champ de nombre | Un nombre ou une string numérique. Utilise `Number()` pour être sûr. |
| Couleur | Un sélecteur de couleur | Une couleur hexadécimale en string, par exemple `#ffffff` |
| Menu déroulant | Un menu avec tes options | L'option choisie, en string. Par défaut, c'est la première option. |
| Interrupteur | Un interrupteur on/off | `true` ou `false` |
| Image/GIF | Un champ d'URL et un bouton d'import | Une URL vers le fichier |
| Vidéo | Un champ d'URL et un bouton d'import | Une URL vers le fichier |
| Audio | Un champ d'URL et un bouton d'import | Une URL vers le fichier |

Les fichiers importés sont stockés par KickBot, et `value` est l'URL du fichier. Utilise le menu à côté d'une variable pour la monter, la descendre, la modifier ou la supprimer. L'ordre dans l'éditeur est l'ordre que voient les streamers.

## Afficher le texte du chat en toute sécurité

Traite chaque champ d'événement et chaque variable utilisateur comme du texte venant d'un inconnu. KickBot nettoie le texte du chat et des événements avant que ton code le reçoive, donc il est sûr comme texte HTML, mais pas comme URL, CSS ou script. Ne mets pas les champs bruts d'un événement dans `innerHTML`. Utilise ces helpers :

| Helper | Ce qu'il fait |
| --- | --- |
| `window.kickbotWidget.createChatMessageFragment(content, font_size)` | Renvoie un `DocumentFragment` avec des nœuds texte et les images des emotes Kick. Les emotes font `font_size + 3` pixels. `font_size` vaut 20 par défaut. |
| `window.kickbotWidget.createTextNode(value)` | Renvoie un nœud texte pour n'importe quelle valeur. |
| `window.kickbotWidget.escapeHtmlText(value)` | Échappe le texte à placer entre des balises HTML quand tu dois construire une string HTML. Ne l'utilise pas pour des URL, du CSS ou du script. |

```javascript
document.addEventListener('widgetEvent', (event) => {
    if (event.detail.event_name !== 'chatMessageEvent') return;
    const data = event.detail.data;

    const line = document.createElement('div');
    line.id = 'msg-' + data.id;
    const name = document.createElement('strong');
    name.style.color = data.sender.identity.color;
    name.append(window.kickbotWidget.createTextNode(data.sender.username + ': '));
    line.append(name);
    line.append(window.kickbotWidget.createChatMessageFragment(data.content, 20));
    document.getElementById('chat').append(line);
});
```

Pour les autres textes, utilise `textContent` ou `createTextNode`.

## L'aperçu

L'aperçu de l'éditeur fonctionne comme OBS, avec quelques différences pour les tests :

- Quand tu changes le code ou une variable utilisateur, l'aperçu relance ton JavaScript. KickBot retire d'abord les listeners `widgetEvent` du lancement précédent. Les minuteurs de `setInterval` et `setTimeout` ne sont pas retirés, donc clique sur le bouton de rechargement s'ils s'accumulent.
- Quand tu changes la largeur ou la hauteur, l'aperçu se recharge.
- Les événements de test vont seulement dans l'aperçu. Un **Follow** de test ajoute 1 à `globalValues.followerCount`, et **Unfollow** retire 1. **Compteur de viewers mis à jour** envoie un nombre d'exemple. **Message supprimé** retire un message au hasard du chat de l'aperçu.
- Si ta chaîne n'a encore aucun dernier follower, sub ou sub offert, l'aperçu utilise des données d'exemple pour `lastFollower`, `lastSub` et `lastGiftedSub`.
- Pour voir la sortie de `console.log` et les erreurs, clique sur le bouton qui ouvre l'aperçu dans une nouvelle fenêtre, puis ouvre les outils de développement dans cette fenêtre.

## Exemple : objectif de followers

Voici un objectif de followers court. Il utilise un listener d'événements, `globalValues` et deux variables utilisateur : `follower_goal` (Nombre) et `bar_color` (Couleur).

HTML :

```html
<div class="goal">
    <span id="count"></span> / <span id="target"></span>
    <div class="bar"><div class="fill"></div></div>
</div>
```

CSS :

```css
body { margin: 0; font-family: Arial, sans-serif; color: #fff; }
.goal { padding: 12px; background: #100c28; border-radius: 16px; font-size: 32px; font-weight: bold; }
.bar { height: 24px; margin-top: 8px; background: #3d3957; border-radius: 12px; overflow: hidden; }
.fill { height: 100%; width: 0; transition: width 0.3s ease; }
```

JavaScript :

```javascript
const target = Number(userVariables.follower_goal.value) || 100;
document.getElementById('target').textContent = target;
document.querySelector('.fill').style.background = userVariables.bar_color.value;

function update(count) {
    document.getElementById('count').textContent = count;
    document.querySelector('.fill').style.width = Math.min((count / target) * 100, 100) + '%';
}

document.addEventListener('widgetEvent', (event) => {
    const { event_name, data } = event.detail;
    if (event_name === 'followEvent' || event_name === 'unfollowEvent') update(data.followers_count);
    if (event_name === 'followerCountUpdatedEvent') update(data.followersCount);
});

update(globalValues.followerCount);
```

Pour une version complète avec plus de paramètres, crée un nouveau widget à partir du modèle **Simple Follower Goal**.

## Astuces

- Dessine l'état de départ à partir de `globalValues`, puis change-le avec les événements. Un widget qui attend un événement reste vide tant que rien ne se passe.
- Widgets enregistrés affiche seulement les boutons de test des noms d'événements présents dans ton JavaScript. Écris le nom complet de l'événement (par exemple `'followEvent'`) dans ton code pour que les streamers puissent tester ton widget.
- Garde le fond transparent, sauf si un fond fait partie du design, pour que le widget se pose par-dessus la scène.
- Tu peux aussi gérer les widgets de l'éditeur avec l'API KickBot. Consulte la [référence de l'API des widgets](https://kickbot.com/docs/api/reference/widgets).
