diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 45c4032..1e77d9d 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -58,7 +58,7 @@ function getDiscordParseCallbacks(message, guild, useHTML) { emoji: node => { if (useHTML) { const mxc = select("emoji", "mxc_url", {emoji_id: node.id}).pluck().get() - assert(mxc) // All emojis should have been added ahead of time in the messageToEvent function. + assert(mxc, `Emoji consistency assertion failed for ${node.name}:${node.id}`) // All emojis should have been added ahead of time in the messageToEvent function. return `:${node.name}:` } else { return `:${node.name}:` @@ -430,10 +430,12 @@ async function messageToEvent(message, guild, options = {}, di) { repliedToUserHtml = repliedToDisplayName } let repliedToContent = message.referenced_message?.content - if (repliedToContent?.startsWith("> <:L1:")) { + if (repliedToContent?.match(/^(-# )?> (-# )?<:L1:/)) { // If the Discord user is replying to a Matrix user's reply, the fallback is going to contain the emojis and stuff from the bridged rep of the Matrix user's reply quote. // Need to remove that previous reply rep from this fallback body. The fallbody body should only contain the Matrix user's actual message. - repliedToContent = repliedToContent.split("\n").slice(2).join("\n") + // ┌──────A─────┐ A reply rep starting with >quote or -#smalltext >quote. Match until the end of the line. + // ┆ ┆┌─B─┐ There may be up to 2 reply rep lines in a row if it was created in the old format. Match all lines. + repliedToContent = repliedToContent.replace(/^((-# )?> .*\n){1,2}/, "") } if (repliedToContent == "") repliedToContent = "[Media]" else if (!repliedToContent) repliedToContent = "[Replied-to message content wasn't provided by Discord]" diff --git a/d2m/converters/message-to-event.test.js b/d2m/converters/message-to-event.test.js index edcb44c..fbfe06d 100644 --- a/d2m/converters/message-to-event.test.js +++ b/d2m/converters/message-to-event.test.js @@ -559,6 +559,84 @@ test("message2event: simple reply in thread to a matrix user's reply", async t = }]) }) +test("message2event: infinidoge's reply to ami's matrix smalltext reply to infinidoge", async t => { + const events = await messageToEvent(data.message.infinidoge_reply_to_ami_matrix_smalltext_reply_to_infinidoge, data.guild.general, {}, { + api: { + getEvent: mockGetEvent(t, "!BnKuBPCvyfOkhcUjEu:cadence.moe", "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", { + type: "m.room.message", + sender: "@ami:the-apothecary.club", + content: { + msgtype: "m.text", + body: `> <@_ooye_infinidoge:cadence.moe> Neat that they thought of that\n\nlet me guess they got a lot of bug reports like "empty chest with no loot?"`, + format: "org.matrix.custom.html", + formatted_body: `
In reply to @_ooye_infinidoge:cadence.moe
Neat that they thought of that
let me guess they got a lot of bug reports like "empty chest with no loot?"`, + "m.relates_to": { + "m.in_reply_to": { + event_id: "$baby" + } + } + }, + event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", + room_id: "!BnKuBPCvyfOkhcUjEu:cadence.moe" + }) + } + }) + t.deepEqual(events, [{ + $type: "m.room.message", + "m.relates_to": { + "m.in_reply_to": { + event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4" + } + }, + "m.mentions": { + user_ids: ["@ami:the-apothecary.club"] + }, + msgtype: "m.text", + body: `> Ami (she/her): let me guess they got a lot of bug reports like "empty chest with no loot?"\n\nMost likely`, + format: "org.matrix.custom.html", + formatted_body: `
In reply to Ami (she/her)
let me guess they got a lot of bug reports like "empty chest with no loot?"
Most likely`, + }]) +}) + +test("message2event: infinidoge's reply to ami's matrix smalltext singleline reply to infinidoge", async t => { + const events = await messageToEvent(data.message.infinidoge_reply_to_ami_matrix_smalltext_singleline_reply_to_infinidoge, data.guild.general, {}, { + api: { + getEvent: mockGetEvent(t, "!BnKuBPCvyfOkhcUjEu:cadence.moe", "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", { + type: "m.room.message", + sender: "@ami:the-apothecary.club", + content: { + msgtype: "m.text", + body: `> <@_ooye_infinidoge:cadence.moe> Neat that they thought of that\n\nlet me guess they got a lot of bug reports like "empty chest with no loot?"`, + format: "org.matrix.custom.html", + formatted_body: `
In reply to @_ooye_infinidoge:cadence.moe
Neat that they thought of that
let me guess they got a lot of bug reports like "empty chest with no loot?"`, + "m.relates_to": { + "m.in_reply_to": { + event_id: "$baby" + } + } + }, + event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", + room_id: "!BnKuBPCvyfOkhcUjEu:cadence.moe" + }) + } + }) + t.deepEqual(events, [{ + $type: "m.room.message", + "m.relates_to": { + "m.in_reply_to": { + event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4" + } + }, + "m.mentions": { + user_ids: ["@ami:the-apothecary.club"] + }, + msgtype: "m.text", + body: `> Ami (she/her): let me guess they got a lot of bug reports like "empty chest with no loot?"\n\nMost likely`, + format: "org.matrix.custom.html", + formatted_body: `
In reply to Ami (she/her)
let me guess they got a lot of bug reports like "empty chest with no loot?"
Most likely`, + }]) +}) + 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/test/data.js b/test/data.js index 77b2ada..771c183 100644 --- a/test/data.js +++ b/test/data.js @@ -1562,6 +1562,182 @@ module.exports = { attachments: [], guild_id: "1100319549670301727" }, + infinidoge_reply_to_ami_matrix_smalltext_reply_to_infinidoge: { + type: 19, + tts: false, + timestamp: "2024-08-15T20:45:20.697000+00:00", + referenced_message: { + webhook_id: "1179987856631017473", + type: 0, + tts: false, + timestamp: "2024-08-15T20:43:42.705000+00:00", + pinned: false, + mentions: [ + { + username: "infinidoge1337", + public_flags: 768, + id: "197126718400626689", + global_name: "Infinidoge", + discriminator: "0", + clan: null, + avatar_decoration_data: null, + avatar: "89c59de97fdb5f90999d86fed01f23fe" + } + ], + mention_roles: [], + mention_everyone: false, + id: "1273743950028607530", + flags: 0, + embeds: [], + edited_timestamp: null, + content: "> -# <:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/813954820460642336/1100319550446252084/1273733346005880925 <@197126718400626689>:\n" + + "> -# Neat that they thought of that\n" + + 'let me guess they got a lot of bug reports like "empty chest with no loot?"', + components: [], + channel_id: "1100319550446252084", + author: { + username: "Ami (she/her)", + id: "1179987856631017473", + global_name: null, + discriminator: "0000", + bot: true, + avatar: "8b2ca50a10b39f4f908f536cd82d7953" + }, + attachments: [], + application_id: "684280192553844747" + }, + pinned: false, + nonce: "1273744360743108608", + message_reference: { + type: 0, + message_id: "1273743950028607530", + guild_id: "813954820460642336", + channel_id: "1100319550446252084" + }, + mentions: [], + mention_roles: [], + mention_everyone: false, + member: { + roles: [ "832496260219928577" ], + premium_since: null, + pending: false, + nick: null, + mute: false, + joined_at: "2021-05-05T21:22:36.181000+00:00", + flags: 0, + deaf: false, + communication_disabled_until: null, + banner: null, + avatar: null + }, + id: "1273744361036841061", + flags: 0, + embeds: [], + edited_timestamp: null, + content: "Most likely", + components: [], + channel_id: "1100319550446252084", + author: { + username: "infinidoge1337", + public_flags: 768, + id: "197126718400626689", + global_name: "Infinidoge", + discriminator: "0", + clan: null, + avatar_decoration_data: null, + avatar: "89c59de97fdb5f90999d86fed01f23fe" + }, + attachments: [], + guild_id: "813954820460642336" + }, + infinidoge_reply_to_ami_matrix_smalltext_singleline_reply_to_infinidoge: { + type: 19, + tts: false, + timestamp: "2024-08-15T20:45:20.697000+00:00", + referenced_message: { + webhook_id: "1179987856631017473", + type: 0, + tts: false, + timestamp: "2024-08-15T20:43:42.705000+00:00", + pinned: false, + mentions: [ + { + username: "infinidoge1337", + public_flags: 768, + id: "197126718400626689", + global_name: "Infinidoge", + discriminator: "0", + clan: null, + avatar_decoration_data: null, + avatar: "89c59de97fdb5f90999d86fed01f23fe" + } + ], + mention_roles: [], + mention_everyone: false, + id: "1273743950028607530", + flags: 0, + embeds: [], + edited_timestamp: null, + content: "> -# <:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/813954820460642336/1100319550446252084/1273733346005880925 <@197126718400626689>:" + + " Neat that they thought of that\n" + + 'let me guess they got a lot of bug reports like "empty chest with no loot?"', + components: [], + channel_id: "1100319550446252084", + author: { + username: "Ami (she/her)", + id: "1179987856631017473", + global_name: null, + discriminator: "0000", + bot: true, + avatar: "8b2ca50a10b39f4f908f536cd82d7953" + }, + attachments: [], + application_id: "684280192553844747" + }, + pinned: false, + nonce: "1273744360743108608", + message_reference: { + type: 0, + message_id: "1273743950028607530", + guild_id: "813954820460642336", + channel_id: "1100319550446252084" + }, + mentions: [], + mention_roles: [], + mention_everyone: false, + member: { + roles: [ "832496260219928577" ], + premium_since: null, + pending: false, + nick: null, + mute: false, + joined_at: "2021-05-05T21:22:36.181000+00:00", + flags: 0, + deaf: false, + communication_disabled_until: null, + banner: null, + avatar: null + }, + id: "1273744361036841061", + flags: 0, + embeds: [], + edited_timestamp: null, + content: "Most likely", + components: [], + channel_id: "1100319550446252084", + author: { + username: "infinidoge1337", + public_flags: 768, + id: "197126718400626689", + global_name: "Infinidoge", + discriminator: "0", + clan: null, + avatar_decoration_data: null, + avatar: "89c59de97fdb5f90999d86fed01f23fe" + }, + attachments: [], + guild_id: "813954820460642336" + }, sticker: { id: "1106366167788044450", type: 0, diff --git a/test/ooye-test-data.sql b/test/ooye-test-data.sql index 32777a2..328c4b3 100644 --- a/test/ooye-test-data.sql +++ b/test/ooye-test-data.sql @@ -55,7 +55,8 @@ INSERT INTO message_channel (message_id, channel_id) VALUES ('1202543413652881428', '1160894080998461480'), ('1207486471489986620', '1160894080998461480'), ('1210387798297682020', '112760669178241024'), -('1273204543739396116', '687028734322147344'); +('1273204543739396116', '687028734322147344'), +('1273743950028607530', '1100319550446252084'); INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, reaction_part, source) VALUES ('$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg', 'm.room.message', 'm.text', '1126786462646550579', 0, 0, 1), @@ -91,7 +92,8 @@ INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part ('$NB6nPgO2tfXyIwwDSF0Ga0BUrsgX1S-0Xl-jAvI8ucU', 'm.room.message', 'm.text', '1202543413652881428', 0, 0, 0), ('$OEEK-Wam2FTh6J-6kVnnJ6KnLA_lLRnLTHatKKL62-Y', 'm.room.message', 'm.image', '1207486471489986620', 0, 0, 0), ('$mPSzglkCu-6cZHbYro0RW2u5mHvbH9aXDjO5FCzosc0', 'm.room.message', 'm.text', '1210387798297682020', 0, 0, 1), -('$qmyjr-ISJtnOM5WTWLI0fT7uSlqRLgpyin2d2NCglCU', 'm.room.message', 'm.text', '1273204543739396116', 0, 0, 0); +('$qmyjr-ISJtnOM5WTWLI0fT7uSlqRLgpyin2d2NCglCU', 'm.room.message', 'm.text', '1273204543739396116', 0, 0, 0), +('$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4', 'm.room.message', 'm.text', '1273743950028607530', 0, 0, 0); INSERT INTO file (discord_url, mxc_url) VALUES ('https://cdn.discordapp.com/attachments/497161332244742154/1124628646431297546/image.png', 'mxc://cadence.moe/qXoZktDqNtEGuOCZEADAMvhM'), @@ -134,7 +136,8 @@ INSERT INTO member_cache (room_id, mxid, displayname, avatar_url) VALUES ('!cBxtVRxDlZvSVhJXVK:cadence.moe', '@Milan:tchncs.de', 'Milan', NULL), ('!TqlyQmifxGUggEmdBN:cadence.moe', '@ampflower:matrix.org', 'Ampflower 🌺', 'mxc://cadence.moe/PRfhXYBTOalvgQYtmCLeUXko'), ('!TqlyQmifxGUggEmdBN:cadence.moe', '@aflower:syndicated.gay', 'Rose', 'mxc://syndicated.gay/ZkBUPXCiXTjdJvONpLJmcbKP'), -('!TqlyQmifxGUggEmdBN:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', NULL); +('!TqlyQmifxGUggEmdBN:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', NULL), +('!BnKuBPCvyfOkhcUjEu:cadence.moe', '@ami:the-apothecary.club', 'Ami (she/her)', NULL); INSERT INTO lottie (sticker_id, mxc_url) VALUES ('860171525772279849', 'mxc://cadence.moe/ZtvvVbwMIdUZeovWVyGVFCeR');