How to make a Twitch profanity filter Chrome extension

Nintendo Engineer
Dec 28, 2020 – 7 min read

Ich mache hier und da eine Menge Twitch-bezogene Projekte, um zu sehen, was die Möglichkeiten sind. Eines meiner letzten Projekte war die Erstellung einer Twitch-Emote-Erweiterung für Chrome, in der ich gezeigt habe, wie man kostenlos zusätzliche Emote-„Slots“ erhält. Das hat mich dazu gebracht, mich mit Browsererweiterungen zu beschäftigen, also dachte ich mir, ich zeige mal, wie man eine von Grund auf neu erstellt, indem ich einen Schimpfwortfilter für den Twitch-Chat entwickle.

Am Ende wollen wir eine Erweiterung haben, die, wenn sie installiert wird, nach einer Reihe von markierten Wörtern im Chat sucht und sie durch freundlichere Versionen ersetzt. Das könnte zum Beispiel für Kinder nützlich sein, die sich Streams ansehen.

Wenn Sie nur den Code für diese Erweiterung haben wollen, finden Sie einen Link zum Endergebnis am Ende dieses Artikels.

Also, fangen wir gleich an. Legen Sie irgendwo einen Ordner an, den Sie mögen, und nennen Sie ihn profanity-filter. Ich habe meinen an einem Ort erstellt, an dem ich mich mit GitHub synchronisiere.

Jeder beliebige Name ist möglich, aber dieser scheint passend

Nun erstellen Sie in diesem Ordner zwei neue Dateien: manifest.json und content.js. Sie werden sehen, wie wir sie verwenden werden, wenn wir die Erweiterung erstellen.

So geht’s

Öffne manifest.json, die Datei, in der Google die Metadaten zu Ihrer Erweiterung sucht, und fügen Sie Folgendes ein:

{ "manifest_version": 2, "name": "Twitch Profanity Filter Extension", "version": "0.1", "content_scripts": , "js": } ]}

Wie Sie sehen, teilen wir Google mit, dass diese Erweiterung auf jeder Seite von Twitch funktionieren soll, und wir sagen auch, dass die Logik, die auf diesen Seiten ausgeführt werden soll, in der Datei content.js liegt. Beachten Sie, dass ich die Version 0.1 angegeben habe, da dies mein erster Versuch ist.

Einfügen der Logik

Nun öffnen Sie content.js in einem Texteditor Ihrer Wahl. Ich empfehle Visual Studio Code, das ist mein bevorzugter Texteditor für alles, was mit Programmierung zu tun hat, und er ist kostenlos.

Nun werden wir dies in ein paar Schritten einrichten. Was wollen wir erreichen, und wie wollen wir das bewerkstelligen? Wir wissen, dass wir bestimmte Wörter in andere umwandeln wollen, was bedeutet, dass wir die Chatnachrichten lesen, sie auf markierte Wörter überprüfen und diese Wörter dann in freundlichere umwandeln. Wenn die Seite geladen wird, soll unsere Logik also Folgendes leisten:

  • Die Chatbox finden
  • Jedes Mal, wenn eine neue Chatnachricht erscheint, die Nachricht oder den Nachrichtencontainer abrufen
  • Markierte Wörter in ihre freundlichen Gegenstücke umwandeln

Legen wir also los. Der erste Teil besteht darin, das Skript zu aktivieren, wenn die Seite, oder genauer gesagt das Fenster, geladen wurde. In Javascript können Sie sich in das Ladeereignis einklinken, und genau das werden wir jetzt tun. Aktualisieren Sie Ihre content.js so, dass sie Folgendes enthält:

Damit stellen Sie sicher, dass alles, was wir in diese Funktion einfügen, aufgerufen wird, wenn die Seite geladen ist.

Finde die Chatbox

Wie finden wir also die Chatbox? Nun, in der Chrome-Version der Twitch-Website ist die Chatbox in einem <div>-Element enthalten, das eine Klasse namens chat-scrollable-area__message-container hat. Wir werden dieses Element bzw. diesen Knoten über Javascript aufrufen. Aktualisieren Sie die Datei so, dass sie wie folgt aussieht:

Der Grund, warum wir .item(0) dahinter hinzufügen, ist, dass getElementsByClassName() ein Array von Elementen zurückgibt. Da wir wissen, dass nur ein Element diese Klasse hat, nehmen wir es aus dem Array, indem wir angeben, dass wir das erste Element haben wollen (die meisten Programmiersprachen fangen bei 0 an zu zählen).

Jede neue Nachricht im Chat abrufen

Dies ist etwas schwieriger zu verstehen, wenn man nicht an die Programmierung oder an Beobachtermuster gewöhnt ist. Die Art und Weise, wie wir jede neue Nachricht erhalten werden, ist die Verwendung eines MutationObservers auf dem Chatbox-Knoten, den wir gerade aufgenommen haben. Aktualisieren Sie die Datei so, dass sie mit dem Folgenden übereinstimmt, und dann gehen wir durch, was passiert:

Zunächst definieren wir in Zeile 4 eine Callback-Funktion, die eine Liste von Mutationen und den Beobachter aufnimmt, den wir in Zeile 8 erstellen werden. Die Logik in dieser Funktion wird immer dann aufgerufen, wenn sich an dem zu beobachtenden Knoten etwas ändert oder mutiert.

In Zeile 8 erstellen wir den Beobachter und übergeben ihm unsere Callback-Funktion. In Zeile 9 teilen wir dem Beobachter mit, dass er mit der Beobachtung unseres Zielknotens beginnen soll, und wir übergeben eine Konfiguration, die besagt, dass wir nur an Mutationen in der childList interessiert sind. Nachrichten erscheinen als untergeordnete Knoten in dem von uns betrachteten Chatbox-Knoten, so dass unsere Callback-Funktion jedes Mal ausgelöst wird, wenn eine neue Chat-Nachricht erscheint. Das ist genau das, was wir wollen!

Aber jetzt müssen wir noch die eigentlichen Nachrichtenelemente abrufen und dafür fügen wir eine weitere Codezeile in unserem Callback ein:

Der Name mag etwas seltsam erscheinen, aber alle Textteile einer Nachricht (wir scannen keine Emotes, nur die eigentlichen Texte) werden in <span> HTML-Elementen platziert, die die Klasse text-fragment haben. Da diese Funktion bei jeder neuen Nachricht ausgelöst wird, wissen wir auch, dass die gewünschte Nachricht das letzte Element im Chatbox-Knoten sein muss. Deshalb greifen wir auf das lastElementChild zu.

Markierte Wörter in ihre freundlichen Gegenstücke umwandeln

Lassen Sie uns nun zum spannenden Teil kommen. Wenn wir gekennzeichnete Wörter ändern wollen, brauchen wir zunächst etwas, das uns sagt, was gekennzeichnete Wörter und ihre Gegenstücke sind. Wir werden dies mit einem einfachen Wörterbuch tun. Aktualisieren Sie die Datei so, dass sie wie folgt aussieht:

Sie können nach Belieben weitere Wörter hinzufügen, denken Sie nur an das Komma am Ende

Jetzt werden wir den eigentlichen Text in allen Text-Fragment-Elementen lesen, eine Schleife über alle verbotenen Wörter ziehen und sie gegebenenfalls ersetzen. Beginnen wir mit der Schleife, also aktualisieren Sie Ihre Callback-Funktion mit dem Folgenden:

Was hier passiert, ist, dass wir eine Schleife durch all diese Elemente ziehen, die Text enthalten. In Zeile 18 nehmen wir uns jeweils ein bestimmtes Element vor, und in Zeile 19 erhalten wir den eigentlichen Text in Kleinbuchstaben, da unsere markierten Wörter ebenfalls alle in Kleinbuchstaben geschrieben sind. Das macht es für Vergleichszwecke einfacher, aber in einer fortgeschritteneren Version würden wir die Groß- und Kleinschreibung sauber einhalten. Jetzt, da wir unseren Text haben, wollen wir eine Schleife über die markierten Wörter laufen lassen und prüfen, ob sie vorhanden sind. Wenn ja, löschen wir sie. Aktualisieren Sie die Funktion:

Das Wörterbuch, das wir erstellt haben, arbeitet mit Schlüssel-Wert-Paaren, wobei die Schlüssel die gekennzeichneten Wörter und die Werte die freundlichen Wörter sind, so dass wir in Zeile 21 einfach ein Array aller Schlüssel erhalten, das das Array der gekennzeichneten Wörter ist, über die wir eine Schleife ziehen wollen. In der Schleife nehmen wir das markierte Wort, das wir gerade betrachten, und wenn unser Text eines oder mehrere davon enthält, nehmen wir das freundliche Wort und aktualisieren unseren Text, indem wir die markierten Wörter ersetzen. Das ist fast alles, jetzt müssen wir nur noch unseren neuen und verbesserten Text nehmen und ihn wieder in das Element einfügen, aus dem wir ihn entnommen haben:

In Zeile 31 haben wir nun den Text wieder in das Element eingefügt und das war’s! Testen wir dies nun in Chrome.

Der Test

Öffnen Sie Chrome und gehen Sie zu chrome://extensions. Sie sollten Ihre Erweiterungen sehen und oben rechts sehen Sie den Entwicklermodus. Schalten Sie ihn ein, falls er noch nicht aktiviert ist. Danach sehen Sie oben rechts die Option Load unpacked. Damit laden wir unsere lokale Erweiterung, ohne den Weg über den Chrome Web Store gehen zu müssen. Klicken Sie darauf und wählen Sie den Ordner aus, in dem sich die Dateien befinden:

Damit sollte sie sofort in unserer Erweiterungsliste erscheinen:

Gut! Jetzt gehen wir in einen Kanal, in dem wir chatten können. Ich gehe zum Kanal meines Freundes Bjarke, einem lustigen dänischen Streamer, und probiere es aus:

So, es funktioniert! Unser ganz eigener Schimpfwortfilter. War doch gar nicht so schwer, oder? Jetzt müssen Sie ihn nur noch im Chrome Web Store veröffentlichen, wenn Sie das möchten. Ich werde diese Wortliste erweitern und freigeben. Wenn Sie also nicht mehr als das brauchen, müssen Sie es nicht freigeben, da es eine Gebühr erfordert, um in das Programm zu gelangen. Ich werde nicht darauf eingehen, wie die Freigabe funktioniert, aber wenn es dich interessiert, habe ich eine Twitch-Emote-Erweiterung gemacht, um deine eigenen unbegrenzten Emote-Slots zu bekommen, und dieser Artikel erklärt, wie man Erweiterungen am Ende freigibt.

Wenn du den gesamten Code für diese Erweiterung sehen willst, schau dir hier das GitHub-Repos an. Merry coding!