diff --git a/d2m/actions/delete-message.js b/d2m/actions/delete-message.js index 261c8f9d..c9b43ee1 100644 --- a/d2m/actions/delete-message.js +++ b/d2m/actions/delete-message.js @@ -2,8 +2,6 @@ const passthrough = require("../../passthrough") const { sync, db } = passthrough -/** @type {import("../converters/edit-to-changes")} */ -const editToChanges = sync.require("../converters/edit-to-changes") /** @type {import("../../matrix/api")} */ const api = sync.require("../../matrix/api") @@ -12,7 +10,7 @@ const api = sync.require("../../matrix/api") */ async function deleteMessage(data) { /** @type {string?} */ - const roomID = db.prepare("SELECT channel_id FROM channel_room WHERE channel_id = ?").pluck().get(data.channel_id) + const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(data.channel_id) if (!roomID) return /** @type {string[]} */ @@ -22,7 +20,6 @@ async function deleteMessage(data) { // Unfortuately, we can't specify a sender to do the redaction as, unless we find out that info via the audit logs await api.redactEvent(roomID, eventID) db.prepare("DELETE from event_message WHERE event_id = ?").run(eventID) - // TODO: Consider whether this code could be reused between edited messages and deleted messages. } } diff --git a/d2m/actions/edit-message.js b/d2m/actions/edit-message.js index 1c1b90e8..8e8c8388 100644 --- a/d2m/actions/edit-message.js +++ b/d2m/actions/edit-message.js @@ -35,11 +35,8 @@ async function editMessage(message, guild) { // Not redacting as the last action because the last action is likely to be shown in the room preview in clients, and we don't want it to look like somebody actually deleted a message. for (const eventID of eventsToRedact) { await api.redactEvent(roomID, eventID, senderMxid) - // TODO: Reconsider whether it's the right thing to do to delete it from our database? I mean, it's literally not there any more... you can't do anything else with it... - // and you definitely want to mark it in *some* way to prevent duplicate redactions... db.prepare("DELETE from event_message WHERE event_id = ?").run(eventID) // TODO: If I just redacted part = 0, I should update one of the other events to make it the new part = 0, right? - // TODO: Consider whether this code could be reused between edited messages and deleted messages. } // 3. Send all the things. diff --git a/d2m/actions/register-user.js b/d2m/actions/register-user.js index 14553601..19c3a6d5 100644 --- a/d2m/actions/register-user.js +++ b/d2m/actions/register-user.js @@ -115,8 +115,14 @@ function calculateProfileEventContentHash(content) { } /** + * Sync profile data for a sim user. This function follows the following process: + * 1. Join the sim to the room if needed + * 2. Make an object of what the new room member state content would be, including uploading the profile picture if it hasn't been done before + * 3. Compare against the previously known state content, which is helpfully stored in the database + * 4. If the state content has changes, send it to Matrix and update it in the database for next time * @param {import("discord-api-types/v10").APIUser} user * @param {Omit} member + * @returns {Promise} mxid of the updated sim */ async function syncUser(user, member, guildID, roomID) { const mxid = await ensureSimJoined(user, roomID) @@ -128,6 +134,7 @@ async function syncUser(user, member, guildID, roomID) { await api.sendState(roomID, "m.room.member", mxid, content, mxid) db.prepare("UPDATE sim_member SET profile_event_content_hash = ? WHERE room_id = ? AND mxid = ?").run(profileEventContentHash, roomID, mxid) } + return mxid } async function syncAllUsersInRoom(roomID) { diff --git a/d2m/actions/send-message.js b/d2m/actions/send-message.js index cf87d350..2132905e 100644 --- a/d2m/actions/send-message.js +++ b/d2m/actions/send-message.js @@ -23,8 +23,7 @@ async function sendMessage(message, guild) { let senderMxid = null if (!message.webhook_id) { assert(message.member) - senderMxid = await registerUser.ensureSimJoined(message.author, roomID) - await registerUser.syncUser(message.author, message.member, message.guild_id, roomID) + senderMxid = await registerUser.syncUser(message.author, message.member, message.guild_id, roomID) } const events = await messageToEvent.messageToEvent(message, guild, {}, {api}) diff --git a/d2m/discord-packets.js b/d2m/discord-packets.js index 6ae1c22b..c0ba1a6b 100644 --- a/d2m/discord-packets.js +++ b/d2m/discord-packets.js @@ -11,7 +11,7 @@ const utils = { * @param {import("./discord-client")} client * @param {import("cloudstorm").IGatewayMessage} message */ - onPacket(client, message) { + async onPacket(client, message) { // requiring this later so that the client is already constructed by the time event-dispatcher is loaded /** @type {typeof import("./event-dispatcher")} */ const eventDispatcher = sync.require("./event-dispatcher") @@ -68,16 +68,16 @@ const utils = { // Event dispatcher for OOYE bridge operations try { if (message.t === "MESSAGE_CREATE") { - eventDispatcher.onMessageCreate(client, message.d) + await eventDispatcher.onMessageCreate(client, message.d) } else if (message.t === "MESSAGE_UPDATE") { - eventDispatcher.onMessageUpdate(client, message.d) + await eventDispatcher.onMessageUpdate(client, message.d) } else if (message.t === "MESSAGE_DELETE") { - eventDispatcher.onMessageDelete(client, message.d) + await eventDispatcher.onMessageDelete(client, message.d) } else if (message.t === "MESSAGE_REACTION_ADD") { - eventDispatcher.onReactionAdd(client, message.d) + await eventDispatcher.onReactionAdd(client, message.d) } } catch (e) { // Let OOYE try to handle errors too diff --git a/d2m/event-dispatcher.js b/d2m/event-dispatcher.js index fde228d4..8e645913 100644 --- a/d2m/event-dispatcher.js +++ b/d2m/event-dispatcher.js @@ -27,7 +27,7 @@ module.exports = { console.error("hit event-dispatcher's error handler with this exception:") console.error(e) // TODO: also log errors into a file or into the database, maybe use a library for this? or just wing it? definitely need to be able to store the formatted event body to load back in later console.error(`while handling this ${gatewayMessage.t} gateway event:`) - console.dir(gatewayMessage.d) + console.dir(gatewayMessage.d, {depth: null}) if (Date.now() - lastReportedEvent > 5000) { lastReportedEvent = Date.now() @@ -60,7 +60,7 @@ module.exports = { * @param {import("./discord-client")} client * @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message */ - onMessageCreate(client, message) { + async onMessageCreate(client, message) { if (message.webhook_id) { const row = db.prepare("SELECT webhook_id FROM webhook WHERE webhook_id = ?").pluck().get(message.webhook_id) if (row) { @@ -73,14 +73,14 @@ module.exports = { if (!channel.guild_id) return // Nothing we can do in direct messages. const guild = client.guilds.get(channel.guild_id) if (message.guild_id !== "112760669178241024" && message.guild_id !== "497159726455455754") return // TODO: activate on other servers (requires the space creation flow to be done first) - sendMessage.sendMessage(message, guild) + await sendMessage.sendMessage(message, guild) }, /** * @param {import("./discord-client")} client * @param {import("discord-api-types/v10").GatewayMessageUpdateDispatchData} message */ - onMessageUpdate(client, data) { + async onMessageUpdate(client, data) { if (data.webhook_id) { const row = db.prepare("SELECT webhook_id FROM webhook WHERE webhook_id = ?").pluck().get(data.webhook_id) if (row) { @@ -98,7 +98,7 @@ module.exports = { if (!channel.guild_id) return // Nothing we can do in direct messages. const guild = client.guilds.get(channel.guild_id) if (message.guild_id !== "112760669178241024" && message.guild_id !== "497159726455455754") return // TODO: activate on other servers (requires the space creation flow to be done first) - editMessage.editMessage(message, guild) + await editMessage.editMessage(message, guild) } }, @@ -106,19 +106,19 @@ module.exports = { * @param {import("./discord-client")} client * @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data */ - onReactionAdd(client, data) { + async onReactionAdd(client, data) { if (data.user_id === client.user.id) return // m2d reactions are added by the discord bot user - do not reflect them back to matrix. if (data.emoji.id !== null) return // TODO: image emoji reactions console.log(data) - addReaction.addReaction(data) + await addReaction.addReaction(data) }, /** * @param {import("./discord-client")} client * @param {import("discord-api-types/v10").GatewayMessageDeleteDispatchData} data */ - onMessageDelete(client, data) { + async onMessageDelete(client, data) { console.log(data) - deleteMessage.deleteMessage(data) + await deleteMessage.deleteMessage(data) } } diff --git a/matrix/api.js b/matrix/api.js index ef3e199c..81d8a161 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -134,7 +134,7 @@ async function sendEvent(roomID, type, content, mxid, timestamp) { */ async function redactEvent(roomID, eventID, mxid) { /** @type {Ty.R.EventRedacted} */ - const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/redact/${eventID}/${makeTxnId.makeTxnId()}`, mxid)) + const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/redact/${eventID}/${makeTxnId.makeTxnId()}`, mxid), {}) return root.event_id }