Come fare un’estensione Chrome del filtro bestemmie di Twitch

Ingegnere di Nintendo
28 dicembre, 2020 – 7 min read

Faccio molti progetti legati a Twitch qua e là, cercando di vedere quali sono le possibilità. Uno dei miei ultimi progetti riguardava la creazione di un’estensione Twitch Emote per Chrome, dove ho mostrato come ottenere “slot” extra per le emote gratuitamente. Questo mi ha fatto appassionare alle estensioni del browser, così ho pensato di mostrare come crearne una da zero costruendo un filtro per le bestemmie per la chat di Twitch.

Alla fine di questo, vogliamo avere un’estensione che, quando installata, controlla una serie di parole contrassegnate nella chat e le sostituisce con versioni più amichevoli. Questo potrebbe essere utile per i bambini che guardano i flussi, per esempio.

Se volete solo il codice per questa estensione, c’è un link al risultato finale in fondo a questo articolo.

Va bene, quindi mettiamoci a capofitto. Create una cartella da qualche parte e chiamatela profanity-filter. Io ho creato la mia in un posto dove mi sincronizzo con GitHub.

Va bene qualsiasi nome, ma questo mi sembra adatto

Ora all’interno di questa cartella, create due nuovi file: manifest.json e content.js. Vedrai come li useremo per costruire l’estensione.

Ecco fatto

Apri manifest.json, che è il file che Google guarda per i metadati riguardanti la vostra estensione, e incollate quanto segue:

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

Come potete vedere, stiamo dicendo a Google che questa estensione dovrebbe funzionare su qualsiasi pagina di Twitch e stiamo anche dicendo che la logica che dovrebbe essere eseguita su queste pagine risiede nel file chiamato content.js. Notate che ho messo la versione 0.1, dato che questo è il mio tentativo iniziale.

Mettere la logica in

Ora aprite content.js in un editor di testo di vostra scelta. Raccomando vivamente Visual Studio Code, è il mio editor di testo preferito per tutto ciò che riguarda la codifica ed è gratuito.

Ora, il modo in cui impostiamo questo è in pochi passi. Cosa vogliamo ottenere e come lo faremo? Sappiamo che vogliamo cambiare certe parole con altre, il che significa leggere i messaggi di chat, scannerizzarli alla ricerca di parole segnalate e poi aggiornare quelle parole con altre più amichevoli. Quindi, quando la pagina viene caricata, vogliamo che la nostra logica sia in grado di fare quanto segue:

  • Trovare la chatbox
  • Ogni volta che appare un nuovo messaggio di chat, prendere il messaggio o il contenitore dei messaggi
  • Cambiare le parole segnalate con le loro controparti amichevoli

Perciò, diamoci da fare. La prima parte è effettivamente l’attivazione dello script quando la pagina, o più specificamente la finestra, è stata caricata. In javascript, potete agganciarvi a quell’evento di caricamento e noi faremo proprio questo. Aggiornate il vostro content.js in modo che contenga quanto segue:

Questo farà in modo che qualsiasi cosa mettiamo dentro quella funzione, venga chiamata quando la pagina è caricata.

Trovare la chatbox

Come facciamo a trovare la chatbox? Bene, nella versione Chrome del sito di Twitch, la chatbox è contenuta in un elemento <div> che ha una classe chiamata chat-scrollable-area__message-container. Andremo a prendere quell’elemento, o nodo, attraverso javascript. Aggiorna il file in modo che assomigli a questo:

La ragione per cui aggiungiamo .item(0) dietro, è perché getElementsByClassName() ritorna un array di elementi. Poiché sappiamo che solo un elemento ha questa classe, lo prendiamo dall’array specificando che vogliamo la prima cosa (la maggior parte dei linguaggi di programmazione inizia a contare da 0).

Ottieni ogni nuovo messaggio in chat

Questo è un po’ più difficile da capire se non sei abituato a programmare o non sei abituato ai modelli di osservatori. Il modo in cui otterremo ogni nuovo messaggio è usando un MutationObserver sul nodo chatbox che abbiamo appena preso. Aggiornate il file in modo che corrisponda a quanto segue e poi vedremo cosa succede:

Primo, alla linea 4, definiamo una funzione di callback che prende una lista di mutazioni e l’osservatore che creeremo alla linea 8. La logica di questa funzione è quella che viene chiamata ogni volta che qualcosa cambia, o muta, nel nodo che stiamo osservando.

Nella linea 8 creiamo l’osservatore e gli passiamo la nostra funzione di callback. Poi, alla linea 9, diciamo all’osservatore di iniziare ad osservare il nostro nodo di destinazione e passiamo una configurazione che dice che siamo interessati solo alle mutazioni nella childList. I messaggi appaiono come nodi figli nel nodo chatbox che stiamo osservando, quindi la nostra funzione di callback verrà attivata ogni volta che appare un nuovo messaggio di chat. Questo è esattamente ciò che vogliamo!

Ma ora abbiamo ancora bisogno di ottenere gli elementi effettivi del messaggio e per questo aggiungiamo un’altra linea di codice nella nostra callback:

Il nome potrebbe sembrare un po’ strano, ma tutte le parti di testo di un messaggio (non stiamo analizzando le emotes, solo i testi effettivi) sono collocate in <span> elementi HTML che hanno la classe text-fragment. Inoltre, poiché questa funzione viene attivata ad ogni nuovo messaggio, sappiamo che il messaggio che vogliamo deve essere l’ultimo elemento nel nodo chatbox, ecco perché stiamo prendendo l’ultimoElementChild.

Cambia le parole contrassegnate con le loro controparti amichevoli

Veniamo alla parte interessante. Se vogliamo cambiare le parole contrassegnate, abbiamo prima bisogno di qualcosa che ci dica quali sono le parole contrassegnate e le loro controparti. Lo faremo usando un semplice dizionario. Aggiornate il file in modo che assomigli a questo:

Si possono aggiungere altre parole come si vuole, basta ricordare la virgola alla fine

Ora leggeremo il testo attuale in tutti gli elementi del frammento di testo, faremo un loop su tutte le parole vietate e le sostituiremo se necessario. Facciamo partire quel ciclo, quindi aggiornate la vostra funzione di callback con quanto segue:

Quello che sta succedendo qui è che stiamo eseguendo un ciclo attraverso tutti questi elementi che contengono testo. Alla linea 18 prendiamo un elemento specifico alla volta e alla linea 19 otteniamo il testo effettivo da esso in minuscolo, perché anche le nostre parole contrassegnate sono tutte in minuscolo. Rende più facile il confronto, ma in una versione più avanzata ci occuperemmo di mantenere ordinatamente il casing. Ora che abbiamo il nostro testo, vogliamo fare un loop sulle nostre parole contrassegnate e controllare se sono presenti. Se è così, le cancelliamo. Aggiorna la funzione:

Il dizionario che abbiamo creato funziona con coppie chiave-valore, dove le chiavi sono le parole contrassegnate e i valori sono le parole amichevoli, quindi alla linea 21 stiamo semplicemente ottenendo un array di tutte le chiavi, che è l’array di parole contrassegnate che vogliamo controllare. Nel ciclo prendiamo la parola contrassegnata che stiamo attualmente guardando e se il nostro testo include una o più di esse, prendiamo la parola amichevole e aggiorniamo il nostro testo sostituendo le parole contrassegnate. Questo è quasi tutto, ora dobbiamo solo prendere il nostro nuovo e migliorato testo e rimetterlo nell’elemento da cui l’abbiamo preso:

Nella linea 31 abbiamo ora rimesso il testo nell’elemento e questo è tutto! Proviamo questo in Chrome.

Il test

Apri Chrome e vai a chrome://extensions. Dovresti vedere le tue estensioni e in alto a destra vedrai la modalità sviluppatore. Attivatela se non lo è ancora. In seguito, in alto a destra, vedrai l’opzione Load unpacked. La useremo per caricare la nostra estensione locale senza dover ancora passare attraverso il Chrome Web Store. Clicca su di essa e seleziona la cartella dove si trovano i file:

Questo dovrebbe farla apparire immediatamente nella nostra lista delle estensioni:

Bene! Ora andiamo su qualsiasi canale dove possiamo chattare. Andrò sul canale del mio amico Bjarke, un esilarante streamer danese, e lo proverò:

Ecco, funziona! Il nostro filtro per le bestemmie personale. Non era così difficile, vero? Non resta che rilasciarlo sul Chrome Web Store, se volete. Espanderò questa lista di parole e rilascerò questo, quindi se non hai bisogno di più di questo, non devi rilasciarlo, visto che richiede una tassa per entrare nel programma. Non mi addentrerò in come funziona il rilascio, ma se siete interessati, ho fatto una Twitch Emote Extension per ottenere i vostri slot di emote senza limiti e questo articolo spiega come rilasciare le estensioni alla fine.

Se volete vedere tutto il codice per questa estensione, controllate il repo GitHub qui. Buona codifica!