Przejdź do głównej zawartości

Kreator widgetów: dokumentacja techniczna

Ta strona opisuje, czego Twój kod może używać w widgecie z kreatora widgetów KickBot: zdarzeń widgetEvent, obiektu globalValues, obiektu userVariables i funkcji pomocniczych window.kickbotWidget. Każdy widget to zwykły HTML, CSS i JavaScript, który działa w OBS jako browser source. KickBot łączy się z Kick za Ciebie i przekazuje zdarzenia do Twojego kodu.

Gdy OBS otwiera URL widgetu, KickBot:

  1. Wczytuje stronę widgetu z przezroczystym tłem.
  2. Dodaje Twój CSS w elemencie <style> i wstawia Twój HTML na stronę.
  3. Wczytuje dane Twojego kanału z Kick (liczbę obserwujących, liczbę widzów, stan streama i ostatnie wiadomości z czatu) do globalValues.
  4. Uruchamia Twój JavaScript. Działa on raz, po kroku 3, więc globalValues jest gotowy, gdy Twój kod startuje.
  5. Wysyła do Twojego kodu zdarzenia na żywo jako zdarzenia widgetEvent na document.

Twój JavaScript może czytać dwa obiekty bez żadnego importu: globalValues i userVariables. Funkcje pomocnicze są w window.kickbotWidget.

Limity:

ElementLimit
Szerokość i wysokośćUstawiasz w sekcji Ustawienia podstawowe. Nowy pusty widget ma 800 × 600. Okienko Nowy widget przyjmuje do 7680 × 4320.
HTML, CSS i JavaScriptDo 2 000 000 znaków na plik
Nazwa widgetuDo 500 znaków
Pliki dla zmiennych użytkownikaDo 25 MB na plik
Widgety z kreatora w planie Darmowym10 (bez limitu w Premium)

Dodaj jeden listener widgetEvent na document. Każde zdarzenie ma event.detail z trzema polami:

PoleTypWartość
event_namestringZdarzenie, np. followEvent
sourcestringZawsze kick
dataobjectDane zdarzenia (zobacz niżej)
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');
}
});
Nazwa zdarzeniaKiedy się pojawiaPrzycisk testowy
subEventWidz subuje kanałSub
subGiftEventWidz podarowuje subySub w prezencie
kicksEventWidz wysyła KICKiKICKs
followEventWidz zaczyna obserwowaćFollow
unfollowEventWidz przestaje obserwowaćUnfollow
chatMessageEventKtoś wysyła wiadomość na czacieWiadomość
chatMessageDeletedEventModerator usuwa wiadomośćWiadomość usunięta
chatMessagePinnedEventWiadomość zostaje przypiętaWiadomość przypięta
chatMessageUnpinnedEventPrzypięta wiadomość zostaje usuniętaWiadomość odpięta
chatClearedEventModerator czyści czatCzat wyczyszczony
followerCountUpdatedEventKick wysyła nową liczbę obserwującychAktualizacja liczby followerów
subCountUpdatedEventLiczba subów na Kick się zmieniłaAktualizacja liczby subów
viewerCountUpdatedEventKick wysyła nową liczbę widzówAktualizacja liczby widzów
raidEventInny kanał robi na Ciebie raid (hostuje Cię)Raid
streamOnlineTwój stream się zaczynaStream online
streamOfflineTwój stream się kończyStream offline

Nie ma zdarzenia napiwku. Do alertów o napiwkach użyj widgetu alertów napiwków.

To są dane w event.detail.data. Odpowiadają zdarzeniom testowym w edytorze. Prawdziwe zdarzenia mogą mieć więcej pól. Nazwy, liczby i ID poniżej to przykłady.

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 i unfollowEvent (ten sam format; followers_count to nowa liczba)

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

Emotki z Kick są w content jako [emote:ID:NAME]. Użyj createChatMessageFragment (zobacz Bezpieczne wyświetlanie tekstu z czatu), żeby zamienić je na obrazki.

chatMessageDeletedEvent

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

Użyj data.message.id, żeby znaleźć i usunąć wyświetloną wiadomość.

chatMessagePinnedEvent (data.message ma ten sam format co dane chatMessageEvent)

{
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 to pusta tablica ([]).

chatClearedEvent

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

followerCountUpdatedEvent (uwaga: followersCount jest w camelCase)

{ 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 }
}
}

globalValues przechowuje bieżący stan Twojego kanału. KickBot wypełnia go, zanim uruchomi się Twój kod, i aktualizuje go, gdy przychodzą zdarzenia. Użyj go, żeby narysować widget od razu na starcie, zanim przyjdzie jakiekolwiek zdarzenie.

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'
}
}
WartośćJak się aktualizuje
subCountWczytana z Kick. Rośnie o 1 przy każdym subEvent i o 1 przy każdym podarowanym subie, a subCountUpdatedEvent ustawia ją na nowo.
followerCountWczytana z Kick. Ustawiają ją followEvent, unfollowEvent i followerCountUpdatedEvent.
viewerCountWczytana z Kick (0, gdy jesteś offline). Ustawia ją viewerCountUpdatedEvent.
lastFollower, lastSub, lastGiftedSubOstatni taki przypadek, który KickBot widział na Twoim kanale, albo null. Aktualizuje je odpowiednie zdarzenie.
chatMessagesOstatnie wiadomości z czatu Kick przy wczytaniu widgetu, potem każda nowa wiadomość. Trzyma 100 najnowszych. chatClearedEvent ją opróżnia. Żeby ukrywać usunięte wiadomości, obsłuż chatMessageDeletedEvent we własnym kodzie.
streamerInfo.kickTwój profil Kick. Nie zmienia się, gdy widget działa.
currentStreamWczytana z Kick przy wczytaniu widgetu. streamOnline ani streamOffline jej nie aktualizują. Jeśli potrzebujesz aktualnego stanu, nasłuchuj tych zdarzeń.

Zmienne użytkownika to ustawienia, które streamerzy widzą, gdy otwierają Twój widget w Zapisanych widgetach. Dodajesz je w sekcji Zmienne użytkownika w edytorze. W kodzie odczytujesz wartość przez userVariables.<variable name>.value.

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

Pola zmiennej:

PoleCo to jest
TytułEtykieta, którą widzą streamerzy.
Nazwa zmiennejNazwa w Twoim kodzie. Tylko litery, cyfry i _. Po utworzeniu zmiennej nie można jej zmienić.
TooltipDodatkowy tekst pomocy pod tytułem.
Typ zmiennejZobacz tabelę poniżej.
Wartość domyślnaWartość, zanim streamer ją zmieni. Może być pusta.
WymaganaStreamer musi wpisać wartość, zanim zapisze.
TypCo widzi streamervalue w Twoim kodzie
TekstPole tekstoweString
LiczbaPole liczboweLiczba albo string z liczbą. Dla pewności użyj Number().
KolorWybór koloruString z kolorem hex, np. #ffffff
Lista rozwijanaMenu z Twoimi opcjamiWybrana opcja jako string. Domyślnie pierwsza opcja.
PrzełącznikPrzełącznik wł./wył.true albo false
Obraz/GIFPole na URL i przycisk wgrywaniaURL do pliku
WideoPole na URL i przycisk wgrywaniaURL do pliku
AudioPole na URL i przycisk wgrywaniaURL do pliku

Wgrane pliki przechowuje KickBot, a value to URL pliku. Menu obok zmiennej pozwala przenieść ją w górę lub w dół, edytować ją albo usunąć. Kolejność w edytorze to kolejność, którą widzą streamerzy.

Traktuj każde pole zdarzenia i każdą zmienną użytkownika jak tekst od obcej osoby. KickBot czyści tekst z czatu i ze zdarzeń, zanim dostanie go Twój kod, więc jest bezpieczny jako tekst w HTML, ale nie jako URL, CSS czy skrypt. Nie wstawiaj surowych pól zdarzeń do innerHTML. Użyj tych funkcji pomocniczych:

FunkcjaCo robi
window.kickbotWidget.createChatMessageFragment(content, font_size)Zwraca DocumentFragment z węzłami tekstowymi i obrazkami emotek z Kick. Emotki mają font_size + 3 pikseli. Domyślnie font_size to 20.
window.kickbotWidget.createTextNode(value)Zwraca węzeł tekstowy dla dowolnej wartości.
window.kickbotWidget.escapeHtmlText(value)Escapuje tekst do użycia między tagami HTML, gdy musisz zbudować string z HTML. Nie używaj go do URL-i, CSS ani skryptów.
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);
});

Do innego tekstu używaj textContent albo createTextNode.

Podgląd w edytorze działa jak OBS, z kilkoma różnicami ułatwiającymi testy:

  • Gdy zmienisz kod albo zmienną użytkownika, podgląd uruchamia Twój JavaScript ponownie. KickBot najpierw usuwa listenery widgetEvent z poprzedniego uruchomienia. Timery z setInterval i setTimeout nie są usuwane, więc kliknij przycisk odświeżania, jeśli zaczną się nawarstwiać.
  • Gdy zmienisz szerokość albo wysokość, podgląd się przeładowuje.
  • Zdarzenia testowe trafiają tylko do podglądu. Testowy Follow dodaje 1 do globalValues.followerCount, a Unfollow odejmuje 1. Aktualizacja liczby widzów wysyła przykładową liczbę. Wiadomość usunięta usuwa losową wiadomość z czatu w podglądzie.
  • Jeśli Twój kanał nie ma jeszcze ostatniego obserwującego, suba ani podarowanego suba, podgląd używa przykładowych danych dla lastFollower, lastSub i lastGiftedSub.
  • Żeby zobaczyć wynik console.log i błędy, kliknij przycisk otwierania w nowym oknie i otwórz w tym oknie narzędzia deweloperskie.

To krótki cel obserwujących. Używa listenera zdarzeń, globalValues i dwóch zmiennych użytkownika: follower_goal (Liczba) i bar_color (Kolor).

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

Pełną wersję z większą liczbą ustawień dostaniesz, gdy zaczniesz nowy widget od szablonu Simple Follower Goal.

  • Narysuj stan początkowy z globalValues, a potem zmieniaj go przy zdarzeniach. Widget, który czeka na zdarzenie, jest pusty, dopóki coś się nie wydarzy.
  • Zapisane widgety pokazują przyciski testowe tylko dla nazw zdarzeń, które występują w Twoim JavaScripcie. Wpisz w kodzie pełną nazwę zdarzenia (np. 'followEvent'), żeby streamerzy mogli przetestować Twój widget.
  • Zostaw przezroczyste tło, chyba że tło jest częścią projektu. Dzięki przezroczystemu tłu widget leży na wierzchu sceny.
  • Widgetami z kreatora możesz też zarządzać przez API KickBot. Zobacz dokumentację API widgetów.