diff --git a/src/Client.ts b/src/Client.ts index b67d5b2..a27b12a 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -23,6 +23,7 @@ export class Client { ["echo-message", ""], ["extended-join", ""], ["invite-notify", ""], + ["labeled-response", ""], ["message-tags", ""], ["sasl", "PLAIN"], ["server-time", ""], @@ -208,7 +209,16 @@ export class Client { "reason": (message.params.length === 2) ? message.params[1] : "" } const newTxnid = randomUUID(); - this.apiCall.put(`/rooms/${targetChannel.roomId}/redact/${eventId}/${newTxnid}`, data).catch(function (error) { + this.apiCall.put(`/rooms/${targetChannel.roomId}/redact/${eventId}/${newTxnid}`, data).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { @@ -236,7 +246,16 @@ export class Client { "reason": reason, "user_id": targetUser.mxid } - this.apiCall.post(`/rooms/${targetChannel.roomId}/invite`, data).catch(function (error) { + this.apiCall.post(`/rooms/${targetChannel.roomId}/invite`, data).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { @@ -264,7 +283,16 @@ export class Client { "reason": reason, "user_id": targetUser.mxid } - this.apiCall.post(`/rooms/${targetChannel.roomId}/kick`, data).catch(function (error) { + this.apiCall.post(`/rooms/${targetChannel.roomId}/kick`, data).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { @@ -332,8 +360,16 @@ export class Client { } } const newTxnid = randomUUID(); - this.server.txnIdStore.set(newTxnid, this); - this.apiCall.put(`/rooms/${targetChannel.roomId}/send/m.room.message/${newTxnid}`, content).catch(function (error) { + this.apiCall.put(`/rooms/${targetChannel.roomId}/send/m.room.message/${newTxnid}`, content).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { @@ -427,8 +463,16 @@ export class Client { } } const newTxnid = randomUUID(); - this.server.txnIdStore.set(newTxnid, this); - this.apiCall.put(`/rooms/${targetChannel.roomId}/send/m.reaction/${newTxnid}`, content).catch(function (error) { + this.apiCall.put(`/rooms/${targetChannel.roomId}/send/m.reaction/${newTxnid}`, content).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { @@ -465,7 +509,16 @@ export class Client { return; } const topic = message.params[1]; - this.apiCall.put(`/rooms/${targetChannel.roomId}/state/m.room.topic`, {"topic": topic}).catch(function (error) { + this.apiCall.put(`/rooms/${targetChannel.roomId}/state/m.room.topic`, {"topic": topic}).then(r => { + const maybeEventID = r.data["event_id"]; + if (maybeEventID) { + this.server.eventIdStore.set(maybeEventID, this); + const maybeLabel = message.tags.get("label") || ""; + if (maybeLabel !== "") { + this.server.eventIDToLabel.set(maybeEventID, maybeLabel) + } + } + }).catch(function (error) { if (error.response) { console.log(error.response.data); } else if (error.request) { diff --git a/src/Server.ts b/src/Server.ts index 931de10..0d23378 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -17,7 +17,8 @@ export class Server { public ourMatrixUser: MatrixUser; private clients: Set public nickToMatrixUser: Map - public txnIdStore: Map + public eventIdStore: Map + public eventIDToLabel: Map private nextBatch: string private isSyncing: boolean private initialSync: boolean @@ -39,7 +40,8 @@ export class Server { this.matrixUsers = new Map(); this.nickToMatrixUser = new Map(); this.clients = new Set(); - this.txnIdStore = new Map(); + this.eventIdStore = new Map(); + this.eventIDToLabel = new Map(); this.nextBatch = ""; this.isSyncing = false; this.initialSync = false; @@ -272,6 +274,9 @@ export class Server { const reaction = reactionData["key"]; tags.set('+draft/reply', targetMsgid); tags.set('+draft/react', reaction); + if (this.eventIDToLabel.has(event["event_id"])) { + tags.set("label", this.eventIDToLabel.get(event["event_id"]) || "") + } this.sendToAllWithCap("message-tags", sourceUser.getMask(), "TAGMSG", [targetChannel.name], tags) } @@ -402,8 +407,10 @@ export class Server { tags.set('msgid', event["event_id"]); tags.set('account', sourceUser.accountName); tags.set('time', new Date(event["origin_server_ts"]).toISOString()) + if (this.eventIDToLabel.has(event["event_id"])) { + tags.set("label", this.eventIDToLabel.get(event["event_id"]) || "") + } const maybeReply = content["m.relates_to"]?.["m.in_reply_to"]?.["event_id"]; - const maybeTxnId: string = event["unsigned"]?.["transaction_id"] || ""; if (maybeReply) { tags.set('+draft/reply', maybeReply); } @@ -426,11 +433,10 @@ export class Server { msgArray.forEach((msg: string) => { if (msg) { this.clients.forEach((client) => { - if (this.txnIdStore.get(maybeTxnId) === client) { + if (this.eventIdStore.get(event["event_id"]) === client) { if (client.enabledCaps.has('echo-message')) { client.sendMessage(sourceUser.getMask(), ircCommand, [targetChannel.name, msg], tags) - } - + } } else { client.sendMessage(sourceUser.getMask(), ircCommand, [targetChannel.name, msg], tags) } diff --git a/test/rawlogbot.js b/test/rawlogbot.js index f3aa3c5..a683575 100644 --- a/test/rawlogbot.js +++ b/test/rawlogbot.js @@ -1,7 +1,7 @@ import { readFileSync } from "fs"; import { connect } from "tls"; -const config = JSON.parse(readFileSync('config.json')); +const config = JSON.parse(readFileSync(process.argv[2])); const client = connect({ host: 'localhost', @@ -9,7 +9,7 @@ const client = connect({ rejectUnauthorized: false }, () => { client.write("CAP LS 302\r\n"); - client.write("CAP REQ :account-tag batch draft/channel-rename echo-message extended-join invite-notify message-tags sasl server-time\r\n"); + client.write("CAP REQ :account-tag batch draft/channel-rename echo-message reflectionircd.chat/edit-message reflectionircd.chat/extended-invite extended-join invite-notify labeled-response message-tags sasl server-time\r\n"); const saslPassword = Buffer.from(`\0user\0${config.SASLPassword}`).toString('base64'); client.write(`AUTHENTICATE ${saslPassword}\r\n`) client.write("CAP END\r\n")