import { client, xml } from "@xmpp/client" import uuid from "uuid" const GROUP_MESSAGE_ID = "I smell JOJO!" // Ur. Ugly. const XMPP_STATUS_ROOM_CREATED = "201" // 201 Created export default class XMPPConnection extends EventTarget { joinChannel() { const channelIdent = `${this.channel}@conference.xmpp.lets-draw.live/${this.username}` const presence = xml( "presence", { to: channelIdent }, xml("x", { xmlns: "http://jabber.org/protocol/muc" }), ) this.sendOrQueue(presence) } sendOrQueue(message) { if (this.online) { this.xmpp.send(message) } else { this.queue.push(message) } } sendChannelMessage(message) { const channelIdent = `${this.channel}@conference.xmpp.lets-draw.live` const wrappedMessage = xml( "message", { type: "groupchat", to: channelIdent, id: GROUP_MESSAGE_ID, }, xml("body", {}, message), ) this.sendOrQueue(wrappedMessage) } acceptDefaultRoomConfiguration() { const channelIdent = `${this.channel}@conference.xmpp.lets-draw.live` const presence = xml( "iq", { id: GROUP_MESSAGE_ID, to: channelIdent, type: "set" }, xml( "query", { xmlns: "http://jabber.org/protocol/muc#owner" }, xml("x", { xmlns: "jabber:x:data", type: "submit" }), ), ) this.sendOrQueue(presence) } constructor(channel) { super() this.username = uuid.v4().toString() this.channel = channel this.online = false this.queue = [] const xmpp = client({ service: "wss://xmpp.lets-draw.live:5281/xmpp-websocket", domain: "xmpp.lets-draw.live", username: "beartest", password: "beartest", }) this.xmpp = xmpp xmpp.on("offline", () => { this.online = false }) xmpp.on("stanza", (stanza) => { const stanzaId = stanza.getAttr("id") if (stanzaId && stanzaId === GROUP_MESSAGE_ID) { // Messages sent to the room as echoed back // Ignore our own messages to prevent loops return } if (stanza.is("message")) { this.dispatchEvent( new CustomEvent("stanza", { detail: stanza, }), ) } else if (stanza.is("presence")) { const x = stanza.getChild("x") if (x === undefined) { // Uncertain if this element is guaranteed inside a <presence/> return } const created = x.getChildByAttr("code", XMPP_STATUS_ROOM_CREATED) !== undefined if (created) { // Create an "instant room" this.acceptDefaultRoomConfiguration() } } }) xmpp.on("online", async (address) => { /*eslint no-unused-vars: ["error", { "args": "none" }]*/ // Makes itself available await xmpp.send(xml("presence")) this.online = true for (const message of this.queue) { await this.xmpp.send(message) } }) xmpp.start().catch(console.error) this.joinChannel() } sneakilySendTheOtherTeamOur(secrets) { this.sendChannelMessage(secrets) } }