Events
Auf Twitch-Events reagieren
Custom Widgets registrieren Event-Handler mit overlay.on(). Sobald auf deinem Twitch-Channel etwas passiert, ruft pixl deinen Handler mit den Event-Daten auf.
overlay.on('twitch.follow', (data) => {
showAlert(`${data.username} folgt jetzt!`);
});
overlay.on('twitch.cheer', (data) => {
showAlert(`${data.username} hat ${data.bits} Bits gecheert`);
});on() gibt die SDK-Instanz zurück, Handler lassen sich also verketten.
Event-Referenz
Jedes Event kann an drei Stellen ankommen:
- Activity Logs/Events Tab — persistiert in der DB, sichtbar + wiederholbar im Dashboard. Bewusst nicht alles: sehr häufig feuernde Zwischenstände (
*_progress) und kleinteilige/sensible Events (Chat, Moderation, Guest Star) würden das Log nur zumüllen. - Actions — geplante Automatisierungsebene (n8n-artig, mit Schreibzugriff wie Bot-Antworten). Noch nicht gebaut — deshalb aktuell überall ❌, auch wenn ein Event technisch schon existiert.
- Overlay SDK —
overlay.on(). Aktuell ein einziger ungefilterter Broadcast: jedes existierende Event kommt bei jedem Handler an, unabhängig davon, ob es auch im Events-Tab landet. Deshalb überall ✅.
| Event | Daten | Auslöser | Activity Logs/Events Tab | Actions | Overlay SDK |
|---|---|---|---|---|---|
twitch.follow | { username } | Neuer Follower | ✅ | ❌ | ✅ |
twitch.sub | { username, tier, gift?, months?, streak?, message? } | Neuer Sub oder Resub. Feuert NICHT für Gift-Empfänger (weder Einzel- noch Bomben-Gifts) — die stehen ausschließlich in twitch.sub_gift (recipient/recipients), sonst gäbe es doppelte Zeilen. gift/months/streak bleiben nur aus Altdaten-Kompatibilität im Typ, months = Gesamtmonate, streak = aktuelle Serie (fehlt, wenn versteckt), message = Resub-Nachricht | ✅ | ❌ | ✅ |
twitch.sub_gift | { username, tier, amount, community?, months?, recipient?, recipients?, totalGifted? } | Sub-Gift (Direkt-Gift an eine Person, oder Community-Gift-Bombe an zufällige Zuschauer) — einzige Quelle für den/die Empfänger, es gibt bewusst kein zusätzliches twitch.sub-Log dafür. amount = Anzahl, community: true = Community-Gift (Tier + Menge wählbar, immer 1 Monat, kein fester Empfänger — auch bei amount === 1 möglich, deshalb eigenes Feld statt aus amount geraten), sonst Direkt-Gift (Tier + Länge wählbar, months = gekaufte Länge in Monaten, recipient = Empfänger). recipients = { username, login? }[] bei Community-Gifts, trudelt nach der Notification per Chat-Notice nach und nach ein, totalGifted = alle je verschenkten Subs des Gifters, username kann Anonym sein | ✅ | ❌ | ✅ |
twitch.cheer | { username, bits } | Bits gecheert | ✅ | ❌ | ✅ |
twitch.raid | { from, viewerCount } | Eingehender Raid | ✅ | ❌ | ✅ |
twitch.channel_point | { username, reward, cost, input } | Channel-Point-Belohnung eingelöst (custom oder automatisch, z.B. Sub-Emote-Unlock) | ✅ | ❌ | ✅ |
twitch.channel_point_resolved | { username, reward, status } | Streamer erfüllt/storniert eine Einlösung. status: fulfilled/canceled | ❌ | ❌ | ✅ |
twitch.power_up | { username, title, bits, input } | Custom Power-up eingelöst | ✅ | ❌ | ✅ |
twitch.poll_started | { title, choices } | Poll wurde gestartet | ✅ | ❌ | ✅ |
twitch.poll_progress | { title, results } | Zwischenstand während die Poll läuft, results = { title, votes }[]. Feuert bei jeder Stimme | ❌ | ❌ | ✅ |
twitch.poll_ended | { title, status, results } | Poll beendet. status: completed/archived/terminated, results = { title, votes }[] | ✅ | ❌ | ✅ |
twitch.prediction_started | { title, outcomes } | Prediction wurde gestartet | ✅ | ❌ | ✅ |
twitch.prediction_progress | { title, results } | Zwischenstand während die Prediction läuft, results = { title, points }[]. Feuert bei jedem Einsatz | ❌ | ❌ | ✅ |
twitch.prediction_locked | { title, results } | Einreichung geschlossen — noch nicht aufgelöst/abgebrochen (siehe twitch.prediction_ended). results = { title, points }[] (eingesetzte Channel Points je Outcome) | ✅ | ❌ | ✅ |
twitch.prediction_ended | { title, status, winningOutcome?, results } | Prediction aufgelöst oder abgebrochen. status: resolved/canceled, results = { title, points }[] (eingesetzte Channel Points je Outcome) | ✅ | ❌ | ✅ |
twitch.hype_train_started | { level, goal, total } | Hype Train beginnt | ✅ | ❌ | ✅ |
twitch.hype_train_progress | { level, progress, goal, total } | Hype-Train-Fortschritt | ❌ | ❌ | ✅ |
twitch.hype_train_ended | { level, total } | Hype Train endet | ✅ | ❌ | ✅ |
twitch.goal_started | { type, description, current, target } | Creator-Goal beginnt | ❌ | ❌ | ✅ |
twitch.goal_progress | { current, target } | Goal-Fortschritt | ❌ | ❌ | ✅ |
twitch.goal_ended | { type, description, current, target, achieved } | Creator-Goal endet | ❌ | ❌ | ✅ |
twitch.charity_started | { name, target, currency, decimalPlaces } | Charity-Kampagne gestartet | ✅ | ❌ | ✅ |
twitch.charity_progress | { current, target, currency, decimalPlaces } | Charity-Fortschritt | ❌ | ❌ | ✅ |
twitch.charity_donated | { username, name, amount, currency, decimalPlaces } | Spende an die Charity-Kampagne | ✅ | ❌ | ✅ |
twitch.charity_stopped | { name, current, target, currency, decimalPlaces } | Charity-Kampagne beendet | ✅ | ❌ | ✅ |
twitch.ad_break | { durationSec, isAutomatic } | Werbepause läuft an | ✅ | ❌ | ✅ |
twitch.shoutout_sent | { to, viewerCount } | Du gibst einen Shoutout | ❌ | ❌ | ✅ |
twitch.title_changed | { title } | Titel wechselt mitten im Stream (Twitch schickt bei jedem channel.update immer Titel + Kategorie, egal was sich ändert — pixl vergleicht selbst gegen den Vorwert und meldet nur, was sich wirklich geändert hat) | ✅ | ❌ | ✅ |
twitch.category_changed | { category } | Kategorie/Spiel wechselt mitten im Stream (gleicher Diff wie bei twitch.title_changed) | ✅ | ❌ | ✅ |
twitch.ban | { username, moderator, reason, isPermanent, endsAt } | Viewer gebannt/getimeoutet | ❌ | ❌ | ✅ |
twitch.unban | { username, moderator } | Viewer entbannt | ❌ | ❌ | ✅ |
twitch.vip_added / twitch.vip_removed | { username } | VIP-Status vergeben/entfernt | ❌ | ❌ | ✅ |
twitch.moderator_added / twitch.moderator_removed | { username } | Mod-Status vergeben/entfernt | ❌ | ❌ | ✅ |
twitch.watch_streak | { username, streak, channelPoints } | Viewer erreicht einen neuen Watch-Streak-Meilenstein (X Streams in Folge geschaut) | ❌ | ❌ | ✅ |
twitch.modiversary | { username, months } | Mod-Jubiläum: X Monate als Moderator im Kanal | ❌ | ❌ | ✅ |
stream.online | { streamId, title, category, url, thumbnailUrl } | Stream ist live gegangen | ✅ | ❌ | ✅ |
stream.offline | { durationSec? } | Stream wurde beendet | ✅ | ❌ | ✅ |
twitch.chat_message | { username, text, color } | Chat-Nachricht | ❌ | ❌ | ✅ |
twitch.chat_cleared | { } | Chat komplett geleert | ❌ | ❌ | ✅ |
twitch.chat_user_cleared | { username } | Alle Nachrichten eines Users gelöscht | ❌ | ❌ | ✅ |
twitch.chat_message_deleted | { username, messageId } | Einzelne Nachricht gelöscht | ❌ | ❌ | ✅ |
twitch.chat_settings_updated | { emoteMode, followerMode, followerModeDuration, slowMode, slowModeWait, subscriberMode, uniqueChatMode } | Chat-Einstellungen geändert | ❌ | ❌ | ✅ |
twitch.chat_message_held | { username, text, messageId } | Nachricht von Automod zurückgehalten | ❌ | ❌ | ✅ |
twitch.chat_message_held_updated | { username, status, messageId } | Automod-Status einer zurückgehaltenen Nachricht geändert | ❌ | ❌ | ✅ |
twitch.shared_chat_started / twitch.shared_chat_updated | { sessionId, participants } | Shared-Chat-Session beginnt/ändert sich | ❌ | ❌ | ✅ |
twitch.shared_chat_ended | { sessionId } | Shared-Chat-Session endet | ❌ | ❌ | ✅ |
twitch.guest_star_session_started / twitch.guest_star_session_ended | { sessionId } | Guest-Star-Session beginnt/endet | ❌ | ❌ | ✅ |
twitch.guest_star_guest_updated | { sessionId, guest, state, slotId } | Gast-Status in einer Guest-Star-Session ändert sich | ❌ | ❌ | ✅ |
twitch.guest_star_settings_updated | { slotCount, groupLayout } | Guest-Star-Einstellungen geändert | ❌ | ❌ | ✅ |
Mehr Events geplant
Weitere Events (z.B. Spotify-Track-Wechsel) sind in Arbeit. Die Referenz wird laufend erweitert.
Beispiel: Alert mit Sound
const overlay = new Pixl({
token: '__TOKEN__',
settings: {
sound: { type: 'file', label: 'Alert-Sound', accept: 'audio/*' },
},
});
overlay.on('twitch.raid', (data) => {
document.querySelector('#alert').textContent =
`${data.from} raidet mit ${data.viewerCount} Leuten!`;
new Audio(overlay.settings.sound).play();
});Für Werte, die sich merken sollen (Counter, Ziele), nutzt du statt Events den State.
Konfiguration
Settings definieren, das Dashboard baut das Formular
State
Persistente Werte über Streams hinweg
© 2026 pixl