diff --git a/src/d2m/converters/message-to-event.embeds.test.js b/src/d2m/converters/message-to-event.embeds.test.js index 08558b4..9c18386 100644 --- a/src/d2m/converters/message-to-event.embeds.test.js +++ b/src/d2m/converters/message-to-event.embeds.test.js @@ -33,7 +33,9 @@ test("message2event embeds: reply with just an embed", async t => { $type: "m.room.message", msgtype: "m.notice", "m.mentions": {}, - body: "| ## ⏺️ dynastic (@dynastic) https://twitter.com/i/user/719631291747078145" + body: "> In reply to an unbridged message:" + + "\n> PokemonGod: https://twitter.com/dynastic/status/1707484191963648161" + + "\n\n| ## ⏺️ dynastic (@dynastic) https://twitter.com/i/user/719631291747078145" + "\n| \n| does anyone know where to find that one video of the really mysterious yam-like object being held up to a bunch of random objects, like clocks, and they have unexplained impossible reactions to it?" + "\n| \n| ### Retweets" + "\n| 119" @@ -41,7 +43,8 @@ test("message2event embeds: reply with just an embed", async t => { + "\n| 5581" + "\n| — Twitter", format: "org.matrix.custom.html", - formatted_body: '
⏺️ dynastic (@dynastic)' + formatted_body: '
In reply to an unbridged message from PokemonGod:' + + '
https://twitter.com/dynastic/status/1707484191963648161' }]) diff --git a/src/d2m/converters/message-to-event.js b/src/d2m/converters/message-to-event.js index b6268dc..ae7ea1e 100644 --- a/src/d2m/converters/message-to-event.js +++ b/src/d2m/converters/message-to-event.js @@ -262,7 +262,9 @@ async function messageToEvent(message, guild, options = {}, di) { - So make sure we don't do anything in this case. */ const mentions = {} + /** @type {{event_id: string, room_id: string, source: number}?} */ let repliedToEventRow = null + let repliedToUnknownEvent = false let repliedToEventSenderMxid = null if (message.mention_everyone) mentions.room = true @@ -278,6 +280,8 @@ async function messageToEvent(message, guild, options = {}, di) { const row = from("event_message").join("message_channel", "message_id").join("channel_room", "channel_id").select("event_id", "room_id", "source").and("WHERE message_id = ? AND part = 0").get(message.message_reference.message_id) if (row) { repliedToEventRow = row + } else if (message.referenced_message) { + repliedToUnknownEvent = true } } else if (dUtils.isWebhookMessage(message) && message.embeds[0]?.author?.name?.endsWith("↩️")) { // It could be a PluralKit emulated reply, let's see if it has a message link @@ -451,7 +455,7 @@ async function messageToEvent(message, guild, options = {}, di) { // Fallback body/formatted_body for replies // This branch is optional - do NOT change anything apart from the reply fallback, since it may not be run - if (repliedToEventRow && options.includeReplyFallback !== false) { + if ((repliedToEventRow || repliedToUnknownEvent) && options.includeReplyFallback !== false) { let repliedToDisplayName let repliedToUserHtml if (repliedToEventRow?.source === 0 && repliedToEventSenderMxid) { @@ -481,12 +485,33 @@ async function messageToEvent(message, guild, options = {}, di) { discordOnly: true, escapeHTML: false, }) - html = `does anyone know where to find that one video of the really mysterious yam-like object being held up to a bunch of random objects, like clocks, and they have unexplained impossible reactions to it?' + '
Retweets
119Likes
— Twitter
5581` - + html - body = (`${repliedToDisplayName}: ` // scenario 1 part B for mentions - + repliedToBody).split("\n").map(line => "> " + line).join("\n") - + "\n\n" + body + if (repliedToEventRow) { + // Generate a reply pointing to the Matrix event we found + html = ` In reply to ${repliedToUserHtml}` - + `
${repliedToHtml}` + + html + body = (`${repliedToDisplayName}: ` // scenario 1 part B for mentions + + repliedToBody).split("\n").map(line => "> " + line).join("\n") + + "\n\n" + body + } else { // repliedToUnknownEvent + // This reply can't point to the Matrix event because it isn't bridged, we need to indicate this. + assert(message.referenced_message) + const dateDifference = new Date(message.timestamp).getTime() - new Date(message.referenced_message.timestamp).getTime() + const oneHour = 60 * 60 * 1000 + if (dateDifference < oneHour) { + var dateDisplay = "n" + } else if (dateDifference < 25 * oneHour) { + var dateDisplay = ` ${Math.floor(dateDifference / oneHour)}-hour-old` + } else { + var dateDisplay = ` ${Math.round(dateDifference / (24 * oneHour))}-day-old` + } + html = ` In reply to ${repliedToUserHtml}` + + `
${repliedToHtml}In reply to a${dateDisplay} unbridged message from ${repliedToDisplayName}:` + + `` + + html + body = (`In reply to a${dateDisplay} unbridged message:\n${repliedToDisplayName}: ` + + repliedToBody).split("\n").map(line => "> " + line).join("\n") + + "\n\n" + body + } } const newTextMessageEvent = { diff --git a/src/d2m/converters/message-to-event.test.js b/src/d2m/converters/message-to-event.test.js index 78848b8..3e7bcd4 100644 --- a/src/d2m/converters/message-to-event.test.js +++ b/src/d2m/converters/message-to-event.test.js @@ -724,6 +724,20 @@ test("message2event: infinidoge's reply to ami's matrix smalltext singleline rep }]) }) +test("message2event: reply to a Discord message that wasn't bridged", async t => { + const events = await messageToEvent(data.message.reply_to_unknown_message, data.guild.general) + t.deepEqual(events, [{ + $type: "m.room.message", + msgtype: "m.text", + body: `> In reply to a 1-day-old unbridged message:` + + `\n> Occimyy: BILLY BOB THE GREAT` + + `\n\nenigmatic`, + format: "org.matrix.custom.html", + formatted_body: `
${repliedToHtml}In reply to a 1-day-old unbridged message from Occimyy:enigmatic`, + "m.mentions": {} + }]) +}) + test("message2event: simple written @mention for matrix user", async t => { const events = await messageToEvent(data.message.simple_written_at_mention_for_matrix, data.guild.general, {}, { api: { diff --git a/src/d2m/discord-packets.js b/src/d2m/discord-packets.js index b9aba41..a0f2be9 100644 --- a/src/d2m/discord-packets.js +++ b/src/d2m/discord-packets.js @@ -171,6 +171,7 @@ const utils = { await eventDispatcher.onThreadCreate(client, message.d) } else if (message.t === "THREAD_UPDATE") { + // @ts-ignore await eventDispatcher.onChannelOrThreadUpdate(client, message.d, true) } else if (message.t === "MESSAGE_CREATE") { diff --git a/test/data.js b/test/data.js index b815b08..1c44af5 100644 --- a/test/data.js +++ b/test/data.js @@ -1146,6 +1146,93 @@ module.exports = { components: [] } }, + reply_to_unknown_message: { + type: 19, + content: "enigmatic", + mentions: [ + { + id: "1060361805152669766", + username: "occimyy", + avatar: "009d2bf557bca7d4f5a1d5b75a4e2eea", + discriminator: "0", + public_flags: 0, + flags: 0, + banner: null, + accent_color: null, + global_name: "Lily", + avatar_decoration_data: null, + banner_color: null, + clan: null, + primary_guild: null + } + ], + mention_roles: [], + attachments: [], + embeds: [], + timestamp: "2025-02-22T23:34:14.036000+00:00", + edited_timestamp: null, + flags: 0, + components: [], + id: "1343002945670746173", + channel_id: "392141322863116319", + author: { + id: "114147806469554185", + username: "extremity", + avatar: "0c73816563bf912ccebf1a0f1546cfe4", + discriminator: "0", + public_flags: 768, + flags: 768, + banner: null, + accent_color: null, + global_name: null, + avatar_decoration_data: null, + banner_color: null, + clan: null, + primary_guild: null + }, + pinned: false, + mention_everyone: false, + tts: false, + message_reference: { + type: 0, + channel_id: "392141322863116319", + message_id: "1342606571380674560", + guild_id: "112760669178241024" + }, + position: 0, + referenced_message: { + type: 0, + content: "BILLY BOB THE GREAT", + mentions: [], + mention_roles: [], + attachments: [], + embeds: [], + timestamp: "2025-02-21T21:19:11.041000+00:00", + edited_timestamp: null, + flags: 0, + components: [], + id: "1342606571380674560", + channel_id: "392141322863116319", + author: { + id: "1060361805152669766", + username: "occimyy", + avatar: "009d2bf557bca7d4f5a1d5b75a4e2eea", + discriminator: "0", + public_flags: 0, + flags: 0, + banner: null, + accent_color: null, + global_name: "Occimyy", + avatar_decoration_data: null, + banner_color: null, + clan: null, + primary_guild: null + }, + pinned: false, + mention_everyone: false, + tts: false + } + }, attachment_no_content: { id: "1124628646670389348", type: 0,
BILLY BOB THE GREAT