Chat Bridge: porta la chat del tuo forum sui tuoi altri siti web

Gestisco un piccolo forum e altri tre siti web, e continuavo a notare la stessa cosa. Le persone erano felici di chattare una volta sul forum, ma nessuno va su un forum per fare una domanda veloce. La fanno ovunque si trovino già, oppure non la fanno affatto.

Ho quindi creato un plugin che porta la chat del forum su quegli altri siti. Un tag script, e appare una bolla nell’angolo. I visitatori accedono con l’account del forum che hanno già, tramite la schermata di login del forum stesso, e chattano negli stessi canali che vedrebbero sul forum. I messaggi che inviano arrivano nella chat del forum come qualsiasi altro messaggio, perché lo sono.

Repository: GitHub - capodieci/discourse-chat-bridge: Allows to install discourse chat as a plugin in other websites · GitHub (MIT)

<script src="https://forum.example.com/chat-bridge/widget.js"
        data-site-key="your-site-key" defer></script>

Perché è un plugin e non un servizio

Ho iniziato progettando un ponte esterno che avrebbe comunicato con Discourse tramite API, ma poi ho letto il codice sorgente. Questo ha cambiato completamente la progettazione, e le ragioni potrebbero essere utili a chiunque stia considerando qualcosa di simile.

Il plugin di chat registra esattamente un ambito API granulare, create_message. Qualsiasi cosa oltre all’invio, come la lettura dei canali, il recupero dello storico, l’apertura di un messaggio diretto, richiede una chiave di ambito globale, e una chiave di ambito globale per ogni utente è un grosso mucchio di credenziali da gestire. I limiti di frequenza predefiniti sono 60 richieste al minuto per il bucket admin e 20 per il bucket utente, un limite che un client di chat esaurisce senza nemmeno provarci. E gli webhook di chat trasportano solo quattro eventi di messaggio e nient’altro, quindi reazioni, presenza e stato di lettura semplicemente non sono disponibili per essere inoltrati.

Tutti questi problemi spariscono quando il codice gira all’interno di Discourse e può fare direttamente una domanda a Guardian. Niente chiavi, niente limite massimo di frequenza, e una sola fonte di verità invece di una cache che potrebbe non essere in linea con il forum.

Cosa funziona

Canali, storico dei messaggi, invio, messaggi diretti con ricerca persone, e messaggi vocali registrati nel browser. I messaggi vocali appaiono come un normale player audio per i membri che leggono la chat del forum stesso, non come un link di download, il che ha richiesto un po’ di attenzione per essere fatto correttamente.

Ogni sito web ha il proprio colore di accento, angolo e titolo del pannello, in modo che tre siti possano sembrare tre prodotti diversi invece di tre copie dello stesso widget. I visitatori ricevono un suono di notifica che possono disattivare, un’override chiaro o scuro, e la possibilità di mettere in muto una conversazione, che viene scritta nella loro vera iscrizione a Discourse in modo da seguirli fino al forum.

Tutto viene renderizzato all’interno di uno Shadow DOM. Questo gira su pagine che non controllo, e il CSS di nessuna delle due parti dovrebbe poter rompere l’altra.

Cosa non funziona, e perché

Non ci sono chiamate vocali o video. È intenzionale e fuori scope.

La consegna non è istantanea. I messaggi arrivano in circa tre secondi mentre il pannello è aperto. Questo merita una spiegazione, perché Discourse pubblica effettivamente eventi di chat su MessageBus e sembra che dovrebbe funzionare così.

Un browser su un altro dominio non può autenticarsi all’endpoint di MessageBus. La sua policy CORS consente quattro intestazioni di richiesta e nessuna di esse trasporta un token bearer, e la rotta tramite parametro di query nell’autenticazione di Discourse è limitata agli endpoint RSS e calendario. L’unica intestazione che funziona, X-Shared-Session-Key, si risolve in un UserAuthToken e quindi autentica qualsiasi richiesta che la trasporta, non solo quelle di MessageBus. Consegnarla a una pagina incorporata trasformerebbe un buco di cross-site scripting su un sito di marketing in un completo sequestro dell’account del forum. Tre secondi sono il compromesso migliore.

C’è una rotta più sicura per il tempo reale descritta nel repository, che utilizza un canale MessageBus il cui nome indovinabile è esso stesso la capacità, limitato a una sessione di widget piuttosto che all’account dell’utente. Non l’ho costruito. Se qualcuno vuole farlo, il ragionamento è in docs/decisions.md.

La cosa da capire prima di installare

Registrare un sito web concede a quel sito l’accesso cross-origin al tuo forum trasportando le credenziali dei tuoi membri. Non è un effetto collaterale, è il meccanismo.

Se un sito che hai registrato viene compromesso, un attaccante che può eseguire JavaScript lì può agire come qualsiasi membro che lo visita. Non solo nella chat. Qualsiasi cosa quel membro potrebbe fare sul forum.

Quindi registra solo siti che controlli. Registrare il sito di un partner o di un cliente significa accettare la loro sicurezza come la tua. Il plugin lo dice sulla pagina admin accanto al campo dove digiti l’origine, invece che in un documento che nessuno apre, e SECURITY.md passa in rassegna cosa fa il plugin per limitare il raggio d’azione e cosa non fa deliberatamente.

Installazione

Aggiungilo alla tua definizione del container e ricostruisci una volta:

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone --depth 1 https://github.com/capodieci/discourse-chat-bridge.git
env:
  DISCOURSE_ENABLE_CORS: true

Poi attiva chat_bridge_enabled in Admin, Settings, e tutto il resto vive su una pagina in /chat-bridge/admin, dove aggiungi un sito web e ti consegna il tag script.

Due note che salveranno a qualcuno un pomeriggio. I messaggi vocali hanno bisogno di formati audio in authorized_extensions, che di default non ne contiene affatto, quindi la pagina admin ti dice esattamente quali mancano. E chat_allowed_groups è impostato di default sul trust level 1, quindi gli account brand new non possono chattare finché non lo guadagnano, il che il widget spiega invece di fallire silenziosamente.

Compatibilità

Testato contro Discourse 2026.9.0 e 2026.8.0, e in uso in produzione su un forum.

Questo si affida a oggetti di servizio di chat che non sono API pubbliche, quindi una release di Discourse può spostarli. Il repository include uno script pre-flight in sola lettura che asserisce che ognuno di essi esiste ancora e riporta in secondi piuttosto che alla prima richiesta. Vale la pena eseguirlo dopo un upgrade.

Cosa vorrei

Che qualcuno lo installi su un forum che non è mio e mi dica cosa si è rotto. Tutto finora è stato verificato contro un solo Discourse, su un solo server, da una sola persona, e questa è la cosa più debole.

Vorrei anche sentire da chiunque conosca una risposta migliore al problema di MessageBus rispetto a quella su cui mi sono fermato.

2 Mi Piace

ho rimosso il like subito dopo aver notato questo :smiling_face_with_tear:

2 Mi Piace