Jak zobrazit emoce Twitch v chatových zprávách tmi.js

Pokud streamujete na Twitchi, možná víte, že si můžete vytvořit vlastní překrytí streamu pomocí webové technologie. Nástroje pro vysílání, jako je OBS, vám umožňují vkládat webové stránky přímo do vašeho streamu. Knihovnu tmi.js můžete použít k odesílání, reagování a zobrazování chatových zpráv v reálném čase.

Dnes jsem strávil směšné množství času zjišťováním, jak zobrazit Twitch emote v překryvných vrstvách chatu, a dokonce jsem začal stahovat všechny Twitch emote do svého místního počítače... (nedělejte to!)

Pokud tedy narazíte na stejný problém a přemýšlíte, jak vykreslit emoce ve zprávách, tento příspěvek je pro vás!

Problém se zobrazováním emocí Twitch ve zprávách tmi.js

Níže uvedený kód je to, co musíte udělat pro připojení k Twitchi z vaší webové aplikace. Používá websockets a fungovalo to pro mě hned po vybalení.

const tmi = require('tmi.js');
const client = new tmi.Client({
  options: { debug: true, messagesLogLevel: "info" },
  connection: {
    reconnect: true,
    secure: true
	},
  identity: {
    username: 'bot-name',
    password: 'oauth:my-bot-token'
  },
  channels: [ 'my-channel' ]
});
client.connect().catch(console.error);
client.on('message', (channel, tags, message, self) => {
  if(self) return;
  if(message.toLowerCase() === '!hello') {
    client.say(channel, `@${tags.username}, heya!`);
  }
});

Tmi.js poskytuje typický vzor posluchače událostí. Kdykoli někdo komunikuje s chatem vašeho kanálu, zobrazí se message posluchač událostí je volán s několika argumenty:channel , tags , message a self .

Můžete použít message řetězec a vykreslete jej, jak chcete.

Problém se objeví, když lidé ve vašem chatu používají emoce Twitch. Chatová zpráva jako LUL SSSsss SirSad obsahuje několik emocí a měl by být vykreslen následovně.

Otázky jsou:

  • Jak zjistíte, která slova v chatové zprávě jsou emotivní klíčová slova?
  • Jak tato klíčová slova nahradíte?
  • Jak získáte přístup k obrázkům emocí?

tags objekt obsahuje informace pro vykreslení emocí

Chcete-li tento problém vyřešit, musíte znát dva důležité body:

  • tags objekt obsahuje emotes vlastnost, která poskytuje ID emoce a pozice zprávy
  • všechny emotivní obrázky jsou dostupné pod https://static-cdn.jtvnw.net/emoticons/v1/[emote_id]/2.0

emotes vlastnost

Kdykoli je v chatu Twitch zveřejněna zpráva, funkce zpětného volání se spustí pomocí message a tags argument. tags obsahuje spoustu metainformací o uživateli a odeslané zprávě. Pojďme se podívat!

{
  "badge-info": null,
  "badge-info-raw": null,
  "badges": { "broadcaster": "1" },
  "badges-raw": "broadcaster/1",
  "client-nonce": "...",
  "color": null,
  "display-name": "stefanjudis",
  "emotes": {
    "425618": ["0-2"]
  },
  "emotes-raw": "425618:0-2",
  "flags": null,
  "id": "b8aafd84-a15d-4227-9d6b-6d68e1f71c2b"
  "message-type": "chat"
  "mod": false,
  "room-id": "250675174",
  "subscriber": false,
  "tmi-sent-ts": "1606591653042",
  "turbo": false,
  "user-id": "250675174"
  "user-type": null,
  "username": "stefanjudis"
}

Objekt také obsahuje informace o použitých emocích. emotes a emotes-raw vlastnost vám umožní přístup k id a pozici každé použité emoce.

Pro zprávu skládající se z emocí LUL SSSsss SirSad , tags.emotes je následující.

{
  "46": ["4-9"],         // "SSSsss" on characters 4 to 9
  "425618": ["0-2"],     // "LUL" on characters 0 to 2
  "301544924": ["11-16"] // "SirSad" on characters 11 to 16
}

Pomocí těchto informací můžete analyzovat příchozí zprávy a nahradit klíčová slova emocí obrázky.

Adresa URL obrázků veřejnosti emocí

Pravděpodobně je to někde zdokumentováno (nenašel jsem to však), ale teď, když máte id emocí, máte přístup ke každému obrázku emocí v různých velikostech pod následující adresou URL.

https://static-cdn.jtvnw.net/emoticons/v1/[emote_id]/[size]

Example URLs for "LUL":
28x28
https://static-cdn.jtvnw.net/emoticons/v1/425618/1.0
56x56
https://static-cdn.jtvnw.net/emoticons/v1/425618/2.0
112x112
https://static-cdn.jtvnw.net/emoticons/v1/425618/3.0

S těmito dvěma kusy (tags.emotes a veřejně dostupnou adresu URL emocí), můžete všechna klíčová slova ve zprávách Twitch nahradit jejich obrázky. 🎉

Moje řešení

Pokud jste zvědaví, je to ošklivý a neoptimalizovaný kód, který spouštím v místním nastavení Twitch. Transformuje řetězec zprávy chatu na řetězec HTML, který obsahuje prvky emotivního obrázku.

function getMessageHTML(message, { emotes }) {
  if (!emotes) return message;

  // store all emote keywords
  // ! you have to first scan through 
  // the message string and replace later
  const stringReplacements = [];

  // iterate of emotes to access ids and positions
  Object.entries(emotes).forEach(([id, positions]) => {
    // use only the first position to find out the emote key word
    const position = positions[0];
    const [start, end] = position.split("-");
    const stringToReplace = message.substring(
      parseInt(start, 10),
      parseInt(end, 10) + 1
    );

    stringReplacements.push({
      stringToReplace: stringToReplace,
      replacement: `<img src="https://static-cdn.jtvnw.net/emoticons/v1/${id}/3.0">`,
    });
  });

  // generate HTML and replace all emote keywords with image elements
  const messageHTML = stringReplacements.reduce(
    (acc, { stringToReplace, replacement }) => {
      // obs browser doesn't seam to know about replaceAll
      return acc.split(stringToReplace).join(replacement);
    },
    message
  );

  return messageHTML;
}

Upravit :Můj přítel Dominik poukázal na to, že výše uvedený kód obsahuje zranitelnost XSS. Lidé mohou vkládat zprávy HTML chatu a <script> tag by byl spuštěn na mém místním počítači. 🙈 Ve své aplikaci používám React a transformuji HTML na komponenty React, které jsou správně zakódovány. Pokud použijete tento úryvek výše, ujistěte se, že se ve vaší aplikaci nevykreslují zprávy HTML.

Pokud chcete, vidíme se na Twitchi. A doufejme, že google zařadí tento článek dobře, aby nikdo jiný nemusel stahovat tisíce (miliony?) emocí lokálně, jako jsem se to snažil udělat já.