# Riferimento del widget builder

> Riferimento del codice per i widget del widget builder di KickBot: nomi e payload degli eventi di Kick, globalValues, userVariables, helper per la chat e anteprima.

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

Questa pagina elenca cosa può usare il tuo codice in un widget del [widget builder](https://kickbot.com/it/docs/widgets/widget-builder) di KickBot: gli eventi `widgetEvent`, l'oggetto `globalValues`, l'oggetto `userVariables` e gli helper di `window.kickbotWidget`. Ogni widget è semplice HTML, CSS e JavaScript che gira come fonte browser in OBS. KickBot si collega a Kick al posto tuo e invia gli eventi al tuo codice.

## Come gira un widget

Quando OBS apre l'URL del widget, KickBot:

1. Carica la pagina del widget con lo sfondo trasparente.
2. Aggiunge il tuo CSS in un elemento `<style>` e inserisce il tuo HTML nella pagina.
3. Carica da Kick i dati del tuo canale (numero di follower, numero di spettatori, stato della live e chat recente) in `globalValues`.
4. Esegue il tuo JavaScript. Viene eseguito una volta, dopo il punto 3, quindi `globalValues` è pronto quando parte il tuo codice.
5. Invia gli eventi in tempo reale al tuo codice come eventi `widgetEvent` su `document`.

Il tuo JavaScript può leggere due oggetti senza importare nulla: `globalValues` e `userVariables`. Gli helper sono su `window.kickbotWidget`.

Limiti:

| Elemento | Limite |
| --- | --- |
| Larghezza e altezza | Si impostano in **Impostazioni di base**. Un nuovo widget vuoto è 800 × 600. La finestra Nuovo widget accetta fino a 7680 × 4320. |
| HTML, CSS e JavaScript | Fino a 2.000.000 di caratteri per file |
| Nome del widget | Fino a 500 caratteri |
| File per le variabili utente | Fino a 25 MB per file |
| Widget del builder con il piano gratuito | 10 (nessun limite con Premium) |

## Ascolta gli eventi

Aggiungi un listener per `widgetEvent` su `document`. Ogni evento ha `event.detail` con tre campi:

| Campo | Tipo | Valore |
| --- | --- | --- |
| `event_name` | string | L'evento, per esempio `followEvent` |
| `source` | string | Sempre `kick` |
| `data` | object | Il payload dell'evento (vedi sotto) |

```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');
    }
});
```

### Elenco degli eventi

| Nome dell'evento | Quando parte | Pulsante di prova |
| --- | --- | --- |
| `subEvent` | Uno spettatore si abbona | Sub |
| `subGiftEvent` | Uno spettatore regala dei sub | Sub regalato |
| `kicksEvent` | Uno spettatore invia dei KICKs | KICKs |
| `followEvent` | Uno spettatore inizia a seguirti | Follow |
| `unfollowEvent` | Uno spettatore smette di seguirti | Unfollow |
| `chatMessageEvent` | Viene inviato un messaggio in chat | Messaggio |
| `chatMessageDeletedEvent` | Un moderatore elimina un messaggio | Messaggio eliminato |
| `chatMessagePinnedEvent` | Un messaggio viene fissato | Messaggio fissato |
| `chatMessageUnpinnedEvent` | Il messaggio fissato viene rimosso | Messaggio non più fissato |
| `chatClearedEvent` | Un moderatore svuota la chat | Chat svuotata |
| `followerCountUpdatedEvent` | Kick invia un nuovo numero di follower | Numero di follower aggiornato |
| `subCountUpdatedEvent` | Il numero di sub su Kick è cambiato | Numero di sub aggiornato |
| `viewerCountUpdatedEvent` | Kick invia un nuovo numero di spettatori | Numero di spettatori aggiornato |
| `raidEvent` | Un altro canale ti fa un raid (host) | Raid |
| `streamOnline` | La tua live inizia | Live iniziata |
| `streamOffline` | La tua live finisce | Live terminata |

Non esiste un evento per le donazioni. Per gli alert delle donazioni, usa il [widget degli alert delle donazioni](https://kickbot.com/it/docs/tipping/tip-alerts).

### Payload degli eventi

Questi sono i payload in `event.detail.data`. Corrispondono agli eventi di prova dell'editor. Gli eventi reali possono avere più campi. Nomi, numeri e ID qui sono esempi.

`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` e `unfollowEvent` (stessa struttura; `followers_count` è il nuovo numero)

```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 }]
        }
    }
}
```

Le emote di Kick sono in `content` come `[emote:ID:NAME]`. Usa `createChatMessageFragment` (vedi [Mostra il testo della chat in modo sicuro](#show-chat-text-safely)) per trasformarle in immagini.

`chatMessageDeletedEvent`

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

Usa `data.message.id` per trovare e rimuovere il messaggio che hai mostrato.

`chatMessagePinnedEvent` (`data.message` ha la stessa struttura del payload di `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` è un array vuoto (`[]`).

`chatClearedEvent`

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

`followerCountUpdatedEvent` (nota il camelCase di `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 }
    }
}
```

## Valori globali

`globalValues` contiene lo stato attuale del tuo canale. KickBot lo riempie prima che parta il tuo codice e lo tiene aggiornato man mano che arrivano gli eventi. Usalo per disegnare il widget all'inizio, prima che arrivi qualsiasi evento.

```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'
    }
}
```

| Valore | Come si aggiorna |
| --- | --- |
| `subCount` | Caricato da Kick. Sale di 1 per ogni `subEvent` e di 1 per ogni sub regalato, e viene reimpostato da `subCountUpdatedEvent`. |
| `followerCount` | Caricato da Kick. Impostato da `followEvent`, `unfollowEvent` e `followerCountUpdatedEvent`. |
| `viewerCount` | Caricato da Kick (0 quando sei offline). Impostato da `viewerCountUpdatedEvent`. |
| `lastFollower`, `lastSub`, `lastGiftedSub` | L'ultimo che KickBot ha visto sul tuo canale, oppure `null`. Aggiornato dall'evento corrispondente. |
| `chatMessages` | La chat recente da Kick quando il widget si carica, poi ogni nuovo messaggio. Tiene i 100 più recenti. `chatClearedEvent` lo svuota. Per nascondere i messaggi eliminati, gestisci `chatMessageDeletedEvent` nel tuo codice. |
| `streamerInfo.kick` | Il tuo profilo Kick. Non cambia mentre il widget gira. |
| `currentStream` | Caricato da Kick quando il widget si carica. Non viene aggiornato da `streamOnline` né da `streamOffline`. Ascolta questi eventi se ti serve sapere se sei in live. |

## Variabili utente

Le variabili utente sono le impostazioni che gli streamer vedono quando aprono il tuo widget in Widget salvati. Le aggiungi in **Variabili utente** nell'editor. Nel tuo codice, leggi il valore con `userVariables.<variable name>.value`.

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

Campi di una variabile:

| Campo | Cos'è |
| --- | --- |
| Titolo | L'etichetta che vedono gli streamer. |
| Nome variabile | Il nome nel tuo codice. Solo lettere, numeri e `_`. Non puoi cambiarlo dopo aver creato la variabile. |
| Tooltip | Un testo di aiuto in più sotto il titolo. |
| Tipo di variabile | Vedi la tabella qui sotto. |
| Valore predefinito | Il valore prima che lo streamer lo cambi. Può essere vuoto. |
| Obbligatoria | Gli streamer devono inserire un valore prima di poter salvare. |

| Tipo | Cosa vede lo streamer | `value` nel tuo codice |
| --- | --- | --- |
| Testo | Una casella di testo | Una stringa |
| Numero | Una casella per numeri | Un numero o una stringa numerica. Usa `Number()` per sicurezza. |
| Colore | Un selettore di colore | Una stringa con un colore esadecimale, per esempio `#ffffff` |
| Menu a tendina | Un menu con le tue opzioni | L'opzione scelta come stringa. Il predefinito è la prima opzione. |
| Interruttore | Un interruttore on/off | `true` o `false` |
| Immagine/GIF | Una casella per l'URL e un pulsante per caricare | Un URL del file |
| Video | Una casella per l'URL e un pulsante per caricare | Un URL del file |
| Audio | Una casella per l'URL e un pulsante per caricare | Un URL del file |

I file caricati sono salvati da KickBot, e `value` è l'URL del file. Usa il menu accanto a una variabile per spostarla su o giù, modificarla o eliminarla. L'ordine nell'editor è l'ordine che vedono gli streamer.

## Mostra il testo della chat in modo sicuro

Tratta ogni campo degli eventi e ogni variabile utente come testo scritto da uno sconosciuto. KickBot pulisce il testo della chat e degli eventi prima che arrivi al tuo codice, quindi è sicuro come testo HTML, ma non come URL, CSS o script. Non inserire i campi grezzi degli eventi in `innerHTML`. Usa questi helper:

| Helper | Cosa fa |
| --- | --- |
| `window.kickbotWidget.createChatMessageFragment(content, font_size)` | Restituisce un `DocumentFragment` con nodi di testo e immagini delle emote di Kick. Le emote sono di `font_size + 3` pixel. `font_size` vale 20 se non lo indichi. |
| `window.kickbotWidget.createTextNode(value)` | Restituisce un nodo di testo per qualsiasi valore. |
| `window.kickbotWidget.escapeHtmlText(value)` | Fa l'escape del testo da usare tra i tag HTML quando devi costruire una stringa HTML. Non usarlo per URL, CSS o 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);
});
```

Per altro testo, usa `textContent` o `createTextNode`.

## L'anteprima

L'anteprima nell'editor funziona come OBS, con qualche differenza per i test:

- Quando cambi il codice o una variabile utente, l'anteprima esegue di nuovo il tuo JavaScript. Prima KickBot rimuove i listener di `widgetEvent` dell'esecuzione precedente. I timer di `setInterval` e `setTimeout` non vengono rimossi, quindi clicca il pulsante di ricarica se si accumulano.
- Quando cambi larghezza o altezza, l'anteprima si ricarica.
- Gli eventi di prova arrivano solo all'anteprima. Un **Follow** di prova aggiunge 1 a `globalValues.followerCount`, e **Unfollow** toglie 1. **Numero di spettatori aggiornato** invia un numero di esempio. **Messaggio eliminato** rimuove un messaggio a caso dalla chat dell'anteprima.
- Se il tuo canale non ha ancora un ultimo follower, sub o sub regalato, l'anteprima usa dati di esempio per `lastFollower`, `lastSub` e `lastGiftedSub`.
- Per vedere l'output di `console.log` e gli errori, clicca il pulsante per aprire l'anteprima in una finestra separata e apri gli strumenti per sviluppatori in quella finestra.

## Esempio: obiettivo follower

Questo è un breve obiettivo follower. Usa un listener di eventi, `globalValues` e due variabili utente: `follower_goal` (Numero) e `bar_color` (Colore).

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);
```

Per una versione completa con più impostazioni, crea un nuovo widget dal modello **Simple Follower Goal**.

## Consigli

- Disegna lo stato iniziale da `globalValues`, poi cambialo con gli eventi. Un widget che aspetta un evento resta vuoto finché non succede qualcosa.
- Widget salvati mostra i pulsanti di prova solo per i nomi degli eventi che compaiono nel tuo JavaScript. Scrivi il nome completo dell'evento (per esempio `'followEvent'`) nel tuo codice, così gli streamer possono provare il tuo widget.
- Tieni lo sfondo trasparente, a meno che uno sfondo non faccia parte del design, così il widget sta sopra la scena.
- Puoi anche gestire i widget del builder con l'API di KickBot. Vedi il [riferimento API dei widget](https://kickbot.com/docs/api/reference/widgets).
