Widget-Builder-Referenz
Diese Seite listet, was dein Code in einem Widget aus dem KickBot Widget Builder nutzen kann: die widgetEvent-Events, das Objekt globalValues, das Objekt userVariables und die Helfer in window.kickbotWidget. Jedes Widget ist einfaches HTML, CSS und JavaScript, das als Browser-Source in OBS läuft. KickBot verbindet sich für dich mit Kick und schickt Events an deinen Code.
So läuft ein Widget
Abschnitt betitelt „So läuft ein Widget“Wenn OBS die Widget-URL öffnet, macht KickBot Folgendes:
- Lädt die Widget-Seite mit transparentem Hintergrund.
- Fügt dein CSS in einem
<style>-Element ein und setzt dein HTML in die Seite. - Lädt deine Kanaldaten von Kick (Follower-Zahl, Zuschauerzahl, Stream-Status und letzte Chat-Nachrichten) in
globalValues. - Führt dein JavaScript aus. Es läuft einmal, nach Schritt 3.
globalValuesist also bereit, wenn dein Code startet. - Schickt Live-Events als
widgetEvent-Events aufdocumentan deinen Code.
Dein JavaScript kann zwei Objekte lesen, ohne etwas zu importieren: globalValues und userVariables. Die Helfer liegen in window.kickbotWidget.
Limits:
| Punkt | Limit |
|---|---|
| Breite und Höhe | Wird unter Grundeinstellungen eingestellt. Ein neues leeres Widget hat 800 × 600. Das Popup Neues Widget erlaubt bis zu 7680 × 4320. |
| HTML, CSS und JavaScript | Bis zu 2.000.000 Zeichen pro Datei |
| Widget-Name | Bis zu 500 Zeichen |
| Dateien für Nutzervariablen | Bis zu 25 MB pro Datei |
| Builder-Widgets im Gratis-Plan | 10 (kein Limit mit Premium) |
Auf Events hören
Abschnitt betitelt „Auf Events hören“Füge einen Listener für widgetEvent auf document hinzu. Jedes Event hat event.detail mit drei Feldern:
| Feld | Typ | Wert |
|---|---|---|
event_name | string | Das Event, zum Beispiel followEvent |
source | string | Immer kick |
data | object | Die Payload des Events (siehe unten) |
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 der Events
Abschnitt betitelt „Liste der Events“| Event-Name | Wann es ausgelöst wird | Test-Button |
|---|---|---|
subEvent | Ein Zuschauer subbt | Sub |
subGiftEvent | Ein Zuschauer verschenkt Subs | Gifted Sub |
kicksEvent | Ein Zuschauer sendet KICKs | KICKs |
followEvent | Ein Zuschauer folgt | Follow |
unfollowEvent | Ein Zuschauer entfolgt | Unfollow |
chatMessageEvent | Eine Chat-Nachricht wird gesendet | Nachricht |
chatMessageDeletedEvent | Ein Moderator löscht eine Nachricht | Nachricht gelöscht |
chatMessagePinnedEvent | Eine Nachricht wird angepinnt | Nachricht angepinnt |
chatMessageUnpinnedEvent | Die angepinnte Nachricht wird entfernt | Nachricht abgepinnt |
chatClearedEvent | Ein Moderator leert den Chat | Chat geleert |
followerCountUpdatedEvent | Kick schickt eine neue Follower-Zahl | Follower-Zahl aktualisiert |
subCountUpdatedEvent | Die Sub-Zahl auf Kick hat sich geändert | Sub-Zahl aktualisiert |
viewerCountUpdatedEvent | Kick schickt eine neue Zuschauerzahl | Viewer-Zahl aktualisiert |
raidEvent | Ein anderer Kanal raidet (hostet) dich | Raid |
streamOnline | Dein Stream startet | Stream online |
streamOffline | Dein Stream endet | Stream offline |
Es gibt kein Tip-Event. Für Tip-Alerts nutze das Tip-Alert-Widget.
Payloads der Events
Abschnitt betitelt „Payloads der Events“Das sind die Payloads in event.detail.data. Sie entsprechen den Test-Events im Editor. Echte Events können mehr Felder haben. Namen, Zahlen und IDs hier sind Beispiele.
subEvent
{ months: 1, username: 'viewer_one', chatroom_id: 3847194}subGiftEvent
{ chatroom_id: 3847194, gifted_usernames: ['viewer_one', 'viewer_two', 'viewer_three'], gifter_username: 'big_gifter'}kicksEvent
{ 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 und unfollowEvent (gleicher Aufbau; followers_count ist die neue Zahl)
{ 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
{ 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 }] } }}Kick-Emotes stehen in content als [emote:ID:NAME]. Mit createChatMessageFragment (siehe Chat-Text sicher anzeigen) machst du daraus Bilder.
chatMessageDeletedEvent
{ id: '9cd3788a-ecd2-4051-a162-a7ea9be8ce7a', message: { id: '89d6be86-63db-4581-922e-14a6c4a9c2e6' }}Mit data.message.id findest und entfernst du die Nachricht, die du angezeigt hast.
chatMessagePinnedEvent (data.message hat denselben Aufbau wie eine chatMessageEvent-Payload)
{ 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 ist ein leeres Array ([]).
chatClearedEvent
{ id: '47e3596f-0274-46e0-85b1-029fa3bfc5ea' }followerCountUpdatedEvent (achte auf das camelCase in followersCount)
{ followersCount: 1532, channel_id: 4599, created_at: 1715639984 }subCountUpdatedEvent
{ subscriber_count: 184, channel_id: 4599 }viewerCountUpdatedEvent
{ viewer_count: 320, channel_id: 5937485 }raidEvent
{ chatroom_id: 839485, optional_message: 'gg stream', number_viewers: 150, host_username: 'raiding_channel'}streamOnline
{ livestream: { id: 3984507, channel_id: 3984507, session_title: 'Test stream!', created_at: '2024-05-13T22:30:41+00:00' }}streamOffline
{ livestream: { id: 3984507, channel: { id: 3984507, is_banned: false } }}Globale Werte
Abschnitt betitelt „Globale Werte“globalValues enthält den aktuellen Stand deines Kanals. KickBot füllt es, bevor dein Code läuft, und hält es aktuell, während Events eintreffen. Nutze es, um dein Widget zum Start zu zeichnen, bevor ein Event ankommt.
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' }}| Wert | Wie er aktualisiert wird |
|---|---|
subCount | Wird von Kick geladen. Steigt bei jedem subEvent um 1 und bei jedem Gifted Sub um 1 und wird durch subCountUpdatedEvent neu gesetzt. |
followerCount | Wird von Kick geladen. Wird durch followEvent, unfollowEvent und followerCountUpdatedEvent gesetzt. |
viewerCount | Wird von Kick geladen (0, wenn du offline bist). Wird durch viewerCountUpdatedEvent gesetzt. |
lastFollower, lastSub, lastGiftedSub | Der letzte, den KickBot auf deinem Kanal gesehen hat, oder null. Wird durch das passende Event aktualisiert. |
chatMessages | Die letzten Chat-Nachrichten von Kick beim Laden des Widgets, danach jede neue Nachricht. Behält die neuesten 100. chatClearedEvent leert es. Um gelöschte Nachrichten auszublenden, verarbeite chatMessageDeletedEvent in deinem eigenen Code. |
streamerInfo.kick | Dein Kick-Profil. Ändert sich nicht, während das Widget läuft. |
currentStream | Wird beim Laden des Widgets von Kick geladen. Es wird nicht durch streamOnline oder streamOffline aktualisiert. Hör auf diese Events, wenn du den Live-Status brauchst. |
Nutzervariablen
Abschnitt betitelt „Nutzervariablen“Nutzervariablen sind die Einstellungen, die Streamer sehen, wenn sie dein Widget unter Gespeicherte Widgets öffnen. Du fügst sie im Editor unter Nutzervariablen hinzu. In deinem Code liest du den Wert mit userVariables.<variable name>.value.
const goal = Number(userVariables.follower_goal.value);document.body.style.color = userVariables.text_color.value;Felder einer Variable:
| Feld | Was es ist |
|---|---|
| Titel | Das Label, das Streamer sehen. |
| Variablenname | Der Name in deinem Code. Nur Buchstaben, Zahlen und _. Du kannst ihn nicht ändern, nachdem du die Variable erstellt hast. |
| Tooltip | Zusätzlicher Hilfetext unter dem Titel. |
| Variablentyp | Siehe die Tabelle unten. |
| Standardwert | Der Wert, bevor der Streamer ihn ändert. Er darf leer sein. |
| Pflichtfeld | Streamer müssen einen Wert eingeben, bevor sie speichern können. |
| Typ | Was der Streamer sieht | value in deinem Code |
|---|---|---|
| Text | Ein Textfeld | Ein String |
| Zahl | Ein Zahlenfeld | Eine Zahl oder ein numerischer String. Nutze Number(), um sicherzugehen. |
| Farbe | Eine Farbauswahl | Ein Hex-Farbwert als String, zum Beispiel #ffffff |
| Dropdown | Ein Menü mit deinen Optionen | Die gewählte Option als String. Standard ist die erste Option. |
| Schalter | Ein An/Aus-Schalter | true oder false |
| Bild/GIF | Ein URL-Feld und ein Upload-Button | Eine URL zur Datei |
| Video | Ein URL-Feld und ein Upload-Button | Eine URL zur Datei |
| Audio | Ein URL-Feld und ein Upload-Button | Eine URL zur Datei |
Hochgeladene Dateien speichert KickBot, und value ist die URL der Datei. Mit dem Menü neben einer Variable verschiebst du sie nach oben oder unten, bearbeitest oder löschst sie. Die Reihenfolge im Editor ist die Reihenfolge, die Streamer sehen.
Chat-Text sicher anzeigen
Abschnitt betitelt „Chat-Text sicher anzeigen“Behandle jedes Event-Feld und jede Nutzervariable wie Text von einem Fremden. KickBot bereinigt Chat- und Event-Texte, bevor dein Code sie bekommt. Sie sind also als HTML-Text sicher, aber nicht als URL, CSS oder Skript. Setz rohe Event-Felder nicht in innerHTML ein. Nutze diese Helfer:
| Helfer | Was er macht |
|---|---|
window.kickbotWidget.createChatMessageFragment(content, font_size) | Gibt ein DocumentFragment mit Textknoten und Kick-Emote-Bildern zurück. Emotes sind font_size + 3 Pixel groß. font_size ist standardmäßig 20. |
window.kickbotWidget.createTextNode(value) | Gibt für jeden Wert einen Textknoten zurück. |
window.kickbotWidget.escapeHtmlText(value) | Escapt Text für die Nutzung zwischen HTML-Tags, wenn du einen HTML-String bauen musst. Nutze es nicht für URLs, CSS oder Skripte. |
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);});Für anderen Text nutze textContent oder createTextNode.
Die Vorschau
Abschnitt betitelt „Die Vorschau“Die Vorschau im Editor funktioniert wie OBS, mit ein paar Unterschieden zum Testen:
- Wenn du den Code oder eine Nutzervariable änderst, führt die Vorschau dein JavaScript neu aus. KickBot entfernt vorher die
widgetEvent-Listener des letzten Durchlaufs. Timer aussetIntervalundsetTimeoutwerden nicht entfernt. Klick also auf den Neu-laden-Button, wenn sie sich ansammeln. - Wenn du Breite oder Höhe änderst, lädt die Vorschau neu.
- Test-Events gehen nur an die Vorschau. Ein Test-Follow zählt 1 zu
globalValues.followerCountdazu, und Unfollow zieht 1 ab. Viewer-Zahl aktualisiert sendet eine Beispielzahl. Nachricht gelöscht entfernt eine zufällige Nachricht aus dem Chat der Vorschau. - Wenn dein Kanal noch keinen letzten Follower, Sub oder Gifted Sub hat, nutzt die Vorschau Beispieldaten für
lastFollower,lastSubundlastGiftedSub. - Um die Ausgabe von
console.logund Fehler zu sehen, klick auf den Pop-out-Button und öffne in diesem Fenster die Entwicklertools.
Beispiel: Follower-Ziel
Abschnitt betitelt „Beispiel: Follower-Ziel“Das ist ein kurzes Follower-Ziel. Es nutzt einen Event-Listener, globalValues und zwei Nutzervariablen: follower_goal (Zahl) und bar_color (Farbe).
HTML:
<div class="goal"> <span id="count"></span> / <span id="target"></span> <div class="bar"><div class="fill"></div></div></div>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:
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);Für eine vollständige Version mit mehr Einstellungen starte ein neues Widget mit der Vorlage Simple Follower Goal.
- Zeichne den ersten Zustand aus
globalValuesund ändere ihn dann bei Events. Ein Widget, das auf ein Event wartet, sieht leer aus, bis etwas passiert. - Gespeicherte Widgets zeigt Test-Buttons nur für Event-Namen, die in deinem JavaScript vorkommen. Schreib den vollen Event-Namen (zum Beispiel
'followEvent') in deinen Code, damit Streamer dein Widget testen können. - Lass den Hintergrund transparent, außer ein Hintergrund gehört zum Design. So liegt das Widget über der Szene.
- Du kannst Builder-Widgets auch mit der KickBot-API verwalten. Siehe die API-Referenz für Widgets.