Chat
Chat-Nachrichten mit 7TV-, BTTV- und FFZ-Emotes und 7TV-Paints
twitch.chat_message bringt jede Nachricht aus dem Chat mit Badges und allen Emotes: die von Twitch selbst und die von 7TV, BTTV und FFZ, die der Kanal oder alle nutzen. Heißen zwei gleich, gewinnt 7TV vor BTTV vor FFZ, und das Emote des Kanals vor dem globalen.
Der Schlüssel braucht Events lesen (events:read).
Nachricht als HTML
Das SDK hängt an jede Nachricht html an: der Text ist escaped, Emotes sind Bilder mit der Klasse pixl-emote. Zero-width Emotes (z.B. Hüte) liegen zusammen mit dem Emote davor in <span class="pixl-emote-stack">.
<div id="chat"></div>
<script src="https://pixl.lennox.zip/sdk/pixl.js"></script>
<script>
const pixl = new Pixl({ key: 'pixl_DEIN_SCHLÜSSEL' });
document.head.append(Object.assign(document.createElement('style'), { textContent: pixl.chat.css }));
pixl.on('twitch.chat_message', async (msg) => {
const line = document.createElement('div');
const name = document.createElement('b');
name.textContent = msg.username;
// 7TV-Paint, sonst die Twitch-Farbe
name.style.cssText = await pixl.chat.paintStyle(msg.paint, msg.color || '#fff');
const badges = document.createElement('span');
badges.innerHTML = pixl.chat.badgesHtml(msg.badges);
const text = document.createElement('span');
text.innerHTML = ' ' + msg.html;
line.append(badges, name, text);
document.getElementById('chat').append(line);
});
</script>msg.html und badgesHtml() sind sicher für innerHTML, msg.username dagegen nicht: den immer über textContent setzen.
Felder
| Feld | Inhalt |
|---|---|
text | Nachricht als reiner Text |
html | Nachricht mit Emotes als HTML (baut das SDK) |
emotes | Alle Emotes der Nachricht, Name → { provider, id, name, animated?, zeroWidth? }. provider ist twitch, 7tv, bttv oder ffz |
badges | Badges vor dem Namen: erst die von Twitch (Mod, Sub, VIP, ...), dann das 7TV-Badge. Je { provider, set?, id, title, url, info? } |
paint | ID des 7TV-Paints des Chatters oder null |
username, login, userId | Anzeigename, Login und Twitch-ID des Chatters |
messageId | ID der Nachricht, passt zu twitch.chat_message_deleted |
color | Twitch-Farbe des Namens |
Ohne SDK teilst du text an Leerzeichen und schaust jedes Wort in emotes nach. Die Bild-URL baut pixl.chat.emoteUrl(emote, size) mit size 1, 2 oder 4.
7TV-Paints
pixl.chat.paintStyle(paintId, fallback) gibt einen Inline-Style für den Namen zurück. Die Definitionen lädt das SDK beim ersten Mal von GET /7tv/paints und merkt sie sich. Brauchst du die Rohdaten, gibt es pixl.chat.paint(id).
Emote-Änderungen live
Fügt der Kanal bei 7TV ein Emote hinzu, entfernt oder benennt es um, kommt das sofort an. Neue Nachrichten haben das Emote dann schon, die Events brauchst du nur, wenn dein Widget Emotes selbst anzeigt.
pixl.on('seventv.emote_added', ({ emote, actor }) => {
console.log(`${actor} hat ${emote.name} hinzugefügt`, pixl.chat.emoteUrl(emote, 4));
});
pixl.on('seventv.emote_removed', ({ emote }) => console.log(`${emote.name} ist weg`));
pixl.on('seventv.emote_renamed', ({ emote, oldName }) => console.log(`${oldName} heißt jetzt ${emote.name}`));
pixl.on('seventv.emote_set_changed', ({ name }) => console.log(`Neues Set: ${name}`));Alle Emotes des Kanals auf einmal liefert await pixl.chat.emotes() (GET /emotes). Änderungen bei BTTV und FFZ kommen nicht live, pixl lädt sie alle 10 Minuten neu.
TTS
Texte vorlesen lassen und im Overlay abspielen
StreamElements
Subs und Bits seit Stream-Start als StreamElements Custom Widget
© 2026 pixl