Sari la conținut

Referință pentru Constructorul de widgeturi

Pagina aceasta arată ce poate folosi codul tău într-un widget din Constructorul de widgeturi KickBot: evenimentele widgetEvent, obiectul globalValues, obiectul userVariables și funcțiile ajutătoare din window.kickbotWidget. Fiecare widget este HTML, CSS și JavaScript simplu, care rulează ca sursă browser în OBS. KickBot se conectează la Kick în locul tău și trimite evenimentele în codul tău.

Când OBS deschide URL-ul widgetului, KickBot:

  1. Încarcă pagina widgetului cu fundal transparent.
  2. Adaugă CSS-ul tău într-un element <style> și pune HTML-ul tău în pagină.
  3. Încarcă datele canalului tău de pe Kick (numărul de urmăritori, numărul de spectatori, starea streamului și mesajele recente din chat) în globalValues.
  4. Rulează JavaScript-ul tău. Rulează o singură dată, după pasul 3, așa că globalValues este gata când pornește codul tău.
  5. Trimite evenimentele live în codul tău ca evenimente widgetEvent pe document.

JavaScript-ul tău poate citi două obiecte fără să importe nimic: globalValues și userVariables. Funcțiile ajutătoare sunt în window.kickbotWidget.

Limite:

ElementLimită
Lățime și înălțimeSe setează în Setări de bază. Un widget gol nou are 800 × 600. Fereastra Widget nou acceptă cel mult 7680 × 4320.
HTML, CSS și JavaScriptCel mult 2.000.000 de caractere pe fișier
Numele widgetuluiCel mult 500 de caractere
Fișiere pentru variabilele pentru utilizatorCel mult 25 MB pe fișier
Widgeturi în constructor pe planul gratuit10 (fără limită pe Premium)

Adaugă un singur listener pentru widgetEvent pe document. Fiecare eveniment are event.detail, cu trei câmpuri:

CâmpTipValoare
event_namestringEvenimentul, de exemplu followEvent
sourcestringMereu kick
dataobjectDatele evenimentului (vezi mai jos)
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');
}
});
Numele evenimentuluiCând se declanșeazăButon de test
subEventUn spectator se aboneazăSub
subGiftEventUn spectator oferă sub-uri cadouSub cadou
kicksEventUn spectator trimite KICKsKICKs
followEventUn spectator îți dă followFollow
unfollowEventUn spectator îți dă unfollowUnfollow
chatMessageEventCineva trimite un mesaj în chatMesaj
chatMessageDeletedEventUn moderator șterge un mesajMesaj șters
chatMessagePinnedEventUn mesaj este fixatMesaj fixat
chatMessageUnpinnedEventMesajul fixat este scosFixare mesaj anulată
chatClearedEventUn moderator golește chatulChat golit
followerCountUpdatedEventKick trimite un număr nou de urmăritoriNumăr de urmăritori actualizat
subCountUpdatedEventNumărul de sub-uri de pe Kick s-a schimbatNumăr de sub-uri actualizat
viewerCountUpdatedEventKick trimite un număr nou de spectatoriNumăr de spectatori actualizat
raidEventAlt canal îți dă raid (host)Raid
streamOnlineStreamul tău începeStream pornit
streamOfflineStreamul tău se terminăStream oprit

Nu există un eveniment pentru donații. Pentru alertele de donații, folosește widgetul de alerte de donații.

Acestea sunt datele din event.detail.data. Se potrivesc cu evenimentele de test din editor. Evenimentele reale pot avea mai multe câmpuri. Numele, numerele și ID-urile de aici sunt exemple.

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 (aceeași formă; followers_count este numărul nou)

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

Emote-urile Kick apar în content ca [emote:ID:NAME]. Folosește createChatMessageFragment (vezi Afișează în siguranță textul din chat) ca să le transformi în imagini.

chatMessageDeletedEvent

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

Folosește data.message.id ca să găsești și să scoți mesajul pe care l-ai afișat.

chatMessagePinnedEvent (data.message are aceeași formă ca datele unui 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 este un array gol ([]).

chatClearedEvent

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

followerCountUpdatedEvent (atenție, aici e camelCase: 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 }
}
}

globalValues ține starea curentă a canalului tău. KickBot îl completează înainte să ruleze codul tău și îl ține la zi pe măsură ce vin evenimentele. Folosește-l ca să desenezi widgetul de la început, înainte să vină vreun eveniment.

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'
}
}
ValoareCum se actualizează
subCountSe încarcă de pe Kick. Crește cu 1 la fiecare subEvent și cu 1 la fiecare sub cadou și se setează din nou la subCountUpdatedEvent.
followerCountSe încarcă de pe Kick. Se setează la followEvent, unfollowEvent și followerCountUpdatedEvent.
viewerCountSe încarcă de pe Kick (0 când ești offline). Se setează la viewerCountUpdatedEvent.
lastFollower, lastSub, lastGiftedSubUltimul pe care l-a văzut KickBot pe canalul tău sau null. Se actualizează la evenimentul potrivit.
chatMessagesMesajele recente de pe Kick când se încarcă widgetul, apoi fiecare mesaj nou. Păstrează cele mai noi 100. chatClearedEvent îl golește. Ca să ascunzi mesajele șterse, tratează chatMessageDeletedEvent în propriul cod.
streamerInfo.kickProfilul tău de Kick. Nu se schimbă cât rulează widgetul.
currentStreamSe încarcă de pe Kick când se încarcă widgetul. Nu se actualizează la streamOnline sau streamOffline. Ascultă acele evenimente dacă ai nevoie de starea live.

Variabilele pentru utilizator sunt setările pe care le văd streamerii când îți deschid widgetul în Widgeturi salvate. Le adaugi la Variabile pentru utilizator în editor. În cod, citești valoarea cu userVariables.<variable name>.value.

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

Câmpurile unei variabile:

CâmpCe este
TitluEticheta pe care o văd streamerii.
Numele variabileiNumele din codul tău. Doar litere, cifre și _. Nu-l mai poți schimba după ce creezi variabila.
TooltipUn text de ajutor în plus, sub titlu.
Tipul variabileiVezi tabelul de mai jos.
Valoare implicităValoarea de dinainte ca streamerul să o schimbe. Poate fi goală.
ObligatoriuStreamerii trebuie să completeze o valoare înainte să poată salva.
TipCe vede streamerulvalue în codul tău
TextO casetă de textUn string
NumărO casetă pentru numărUn număr sau un string numeric. Folosește Number() ca să fii sigur.
CuloareUn selector de culoareUn string cu o culoare hex, de exemplu #ffffff
Listă derulantăUn meniu cu opțiunile taleOpțiunea aleasă, ca string. Implicit este prima opțiune.
ComutatorUn comutator pornit/oprittrue sau false
Imagine/GIFO casetă pentru URL și un buton de încărcareUn URL către fișier
VideoO casetă pentru URL și un buton de încărcareUn URL către fișier
AudioO casetă pentru URL și un buton de încărcareUn URL către fișier

Fișierele încărcate sunt stocate de KickBot, iar value este URL-ul fișierului. Cu meniul de lângă o variabilă o muți mai sus sau mai jos, o editezi sau o ștergi. Ordinea din editor este ordinea pe care o văd streamerii.

Tratează fiecare câmp de eveniment și fiecare variabilă pentru utilizator ca pe un text venit de la un străin. KickBot curăță textul din chat și din evenimente înainte să ajungă în codul tău, așa că e sigur ca text HTML, dar nu ca URL, CSS sau script. Nu pune câmpurile brute ale evenimentelor în innerHTML. Folosește aceste funcții ajutătoare:

Funcție ajutătoareCe face
window.kickbotWidget.createChatMessageFragment(content, font_size)Întoarce un DocumentFragment cu noduri de text și imagini pentru emote-urile Kick. Emote-urile au font_size + 3 pixeli. Implicit, font_size este 20.
window.kickbotWidget.createTextNode(value)Întoarce un nod de text pentru orice valoare.
window.kickbotWidget.escapeHtmlText(value)Face escape la text ca să-l folosești între taguri HTML, când trebuie neapărat să construiești un string HTML. Nu-l folosi pentru URL-uri, CSS sau script.
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);
});

Pentru alt text, folosește textContent sau createTextNode.

Previzualizarea din editor funcționează ca OBS, cu câteva diferențe pentru testare:

  • Când schimbi codul sau o variabilă pentru utilizator, previzualizarea rulează din nou JavaScript-ul tău. Înainte, KickBot scoate listenerii widgetEvent de la rularea anterioară. Timerele din setInterval și setTimeout nu sunt scoase, așa că apasă pe butonul de reîncărcare dacă se adună.
  • Când schimbi lățimea sau înălțimea, previzualizarea se reîncarcă.
  • Evenimentele de test ajung doar în previzualizare. Un Follow de test adaugă 1 la globalValues.followerCount, iar Unfollow scade 1. Număr de spectatori actualizat trimite un număr de exemplu. Mesaj șters scoate un mesaj la întâmplare din chatul din previzualizare.
  • Dacă pe canalul tău nu există încă un ultim urmăritor, sub sau sub cadou, previzualizarea folosește date de exemplu pentru lastFollower, lastSub și lastGiftedSub.
  • Ca să vezi rezultatul din console.log și erorile, apasă pe butonul de pop-out și deschide instrumentele pentru dezvoltatori în acea fereastră.

Acesta este un obiectiv de urmăritori scurt. Folosește un listener de evenimente, globalValues și două variabile pentru utilizator: follower_goal (Număr) și bar_color (Culoare).

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

Pentru o versiune completă, cu mai multe setări, pornește un widget nou de la șablonul Simple Follower Goal.

  • Desenează starea de început din globalValues, apoi schimb-o la evenimente. Un widget care așteaptă un eveniment pare gol până se întâmplă ceva.
  • Widgeturi salvate arată butoane de test doar pentru numele de evenimente care apar în JavaScript-ul tău. Scrie numele complet al evenimentului (de exemplu 'followEvent') în cod, ca streamerii să-ți poată testa widgetul.
  • Lasă fundalul transparent, dacă fundalul nu face parte din design, ca widgetul să stea peste scenă.
  • Poți gestiona widgeturile din constructor și cu API-ul KickBot. Vezi referința API pentru widgeturi.