From cd195f92e0e7acc3685447d79c35a42ae0963071 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Wed, 20 Sep 2023 16:12:19 +1200 Subject: [PATCH 1/3] rename a function --- d2m/actions/register-user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/d2m/actions/register-user.js b/d2m/actions/register-user.js index a23513e..64e0ceb 100644 --- a/d2m/actions/register-user.js +++ b/d2m/actions/register-user.js @@ -119,7 +119,7 @@ async function memberToStateContent(user, member, guildID) { return content } -function calculateProfileEventContentHash(content) { +function hashProfileContent(content) { return `${content.displayname}\u0000${content.avatar_url}` } @@ -136,12 +136,12 @@ function calculateProfileEventContentHash(content) { async function syncUser(user, member, guildID, roomID) { const mxid = await ensureSimJoined(user, roomID) const content = await memberToStateContent(user, member, guildID) - const profileEventContentHash = calculateProfileEventContentHash(content) + const currentHash = hashProfileContent(content) const existingHash = select("sim_member", "profile_event_content_hash", "WHERE room_id = ? AND mxid = ?").pluck().get(roomID, mxid) // only do the actual sync if the hash has changed since we last looked - if (existingHash !== profileEventContentHash) { + if (existingHash !== currentHash) { 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) + db.prepare("UPDATE sim_member SET profile_event_content_hash = ? WHERE room_id = ? AND mxid = ?").run(currentHash, roomID, mxid) } return mxid } From 40922ff479cc187e4a0ea1d458806703dc1270ff Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Wed, 20 Sep 2023 16:37:24 +1200 Subject: [PATCH 2/3] change syncSpace input parameters to fix the test --- d2m/actions/create-room.js | 2 +- d2m/actions/create-space.js | 34 +++++++++++++++++------------- d2m/event-dispatcher.js | 2 +- scripts/migrate-from-old-bridge.js | 4 ++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/d2m/actions/create-room.js b/d2m/actions/create-room.js index a207586..671940f 100644 --- a/d2m/actions/create-room.js +++ b/d2m/actions/create-room.js @@ -68,7 +68,7 @@ function convertNameAndTopic(channel, guild, customName) { * @param {DiscordTypes.APIGuild} guild */ async function channelToKState(channel, guild) { - const spaceID = await createSpace.ensureSpace(guild.id) + const spaceID = await createSpace.ensureSpace(guild) assert.ok(typeof spaceID === "string") const row = select("channel_room", ["nick", "custom_avatar"], "WHERE channel_id = ?").get(channel.id) diff --git a/d2m/actions/create-space.js b/d2m/actions/create-space.js index 96b074e..f90c1c3 100644 --- a/d2m/actions/create-space.js +++ b/d2m/actions/create-space.js @@ -74,30 +74,28 @@ async function guildToKState(guild) { } /** - * @param {string} guildID + * @param {DiscordTypes.APIGuild} guild * @param {boolean} shouldActuallySync false if just need to ensure nspace exists (which is a quick database check), * true if also want to efficiently sync space name, space avatar, and child room avatars * @returns {Promise} room ID */ -async function _syncSpace(guildID, shouldActuallySync) { - /** @ts-ignore @type {DiscordTypes.APIGuild} */ - const guild = discord.guilds.get(guildID) +async function _syncSpace(guild, shouldActuallySync) { assert.ok(guild) - if (inflightSpaceCreate.has(guildID)) { - await inflightSpaceCreate.get(guildID) // just waiting, and then doing a new db query afterwards, is the simplest way of doing it + if (inflightSpaceCreate.has(guild.id)) { + await inflightSpaceCreate.get(guild.id) // just waiting, and then doing a new db query afterwards, is the simplest way of doing it } - const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guildID) + const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guild.id) if (!spaceID) { const creation = (async () => { const guildKState = await guildToKState(guild) const spaceID = await createSpace(guild, guildKState) - inflightSpaceCreate.delete(guildID) + inflightSpaceCreate.delete(guild.id) return spaceID })() - inflightSpaceCreate.set(guildID, creation) + inflightSpaceCreate.set(guild.id, creation) return creation // Naturally, the newly created space is already up to date, so we can always skip syncing here. } @@ -136,14 +134,20 @@ async function _syncSpace(guildID, shouldActuallySync) { return spaceID } -/** Ensures the space exists. If it doesn't, creates the space with an accurate initial state. */ -function ensureSpace(guildID) { - return _syncSpace(guildID, false) +/** + * Ensures the space exists. If it doesn't, creates the space with an accurate initial state. + * @param {DiscordTypes.APIGuild} guild + */ +function ensureSpace(guild) { + return _syncSpace(guild, false) } -/** Actually syncs. Efficiently updates the space name, space avatar, and child room avatars. */ -function syncSpace(guildID) { - return _syncSpace(guildID, true) +/** + * Actually syncs. Efficiently updates the space name, space avatar, and child room avatars. + * @param {DiscordTypes.APIGuild} guild + */ +function syncSpace(guild) { + return _syncSpace(guild, true) } /** diff --git a/d2m/event-dispatcher.js b/d2m/event-dispatcher.js index 82c6adb..32b8f49 100644 --- a/d2m/event-dispatcher.js +++ b/d2m/event-dispatcher.js @@ -140,7 +140,7 @@ module.exports = { async onGuildUpdate(client, guild) { const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guild.id) if (!spaceID) return - await createSpace.syncSpace(guild.id) + await createSpace.syncSpace(guild) }, /** diff --git a/scripts/migrate-from-old-bridge.js b/scripts/migrate-from-old-bridge.js index cd32729..84daad7 100644 --- a/scripts/migrate-from-old-bridge.js +++ b/scripts/migrate-from-old-bridge.js @@ -66,7 +66,7 @@ async function migrateGuild(guild) { console.log(`START MIGRATION of ${guild.name} (${guild.id})`) // Step 1: Create a new space for the guild (createSpace) - const spaceID = await createSpace.syncSpace(guild.id) + const spaceID = await createSpace.syncSpace(guild) let oldRooms = oldDB.prepare("SELECT matrix_id, discord_guild, discord_channel FROM room_entries INNER JOIN remote_room_data ON remote_id = room_id WHERE discord_guild = ?").all(guild.id) const migrated = db.prepare("SELECT discord_channel FROM migration WHERE migrated = 1").pluck().all() @@ -132,6 +132,6 @@ async function migrateGuild(guild) { } // Step 5: Call syncSpace to make sure everything is up to date - await createSpace.syncSpace(guild.id) + await createSpace.syncSpace(guild) console.log(`Finished migrating ${guild.name} to Out Of Your Element`) } From 0b5475e9a82cc8c2700516e05f93372bb19ee7b0 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Wed, 20 Sep 2023 16:51:49 +1200 Subject: [PATCH 3/3] start drafting d->m embed bridging --- d2m/converters/message-to-event.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 2a50d62..d9b8940 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -167,6 +167,31 @@ async function messageToEvent(message, guild, options = {}, di) { escapeHTML: false, }, null, null) + for (const embed of message.embeds || []) { + // Start building up a replica ("rep") of the embed in Discord-markdown format, which we will convert into both plaintext and formatted body at once + let repParagraphs = [] + if (embed.author?.name) repParagraphs.push(`**${embed.author.name}**`) + if (embed.title && embed.url) repParagraphs.push(`[**${embed.title}**](${embed.url})`) + else if (embed.title) repParagraphs.push(`**${embed.title}**`) + else if (embed.url) repParagraphs.push(`**${embed.url}**`) + if (embed.description) repParagraphs.push(embed.description) + for (const field of embed.fields || []) { + repParagraphs.push(`**${field.name}**\n${field.value}`) + } + if (embed.footer?.text) repParagraphs.push(embed.footer.text) + const repContent = repParagraphs.join("\n\n") + + html += "
" + markdown.toHTML(repContent, { + discordCallback: getDiscordParseCallbacks(message, true) + }, null, null) + "
" + + body += "\n\n" + markdown.toHTML(repContent, { + discordCallback: getDiscordParseCallbacks(message, false), + discordOnly: true, + escapeHTML: false + }, null, null) + } + // Mentions scenario 3: scan the message content for written @mentions of matrix users. Allows for up to one space between @ and mention. const matches = [...content.matchAll(/@ ?([a-z0-9._]+)\b/gi)] if (matches.length && matches.some(m => m[1].match(/[a-z]/i))) {