diff --git a/src/d2m/converters/message-to-event.js b/src/d2m/converters/message-to-event.js
index 78829ba..449303a 100644
--- a/src/d2m/converters/message-to-event.js
+++ b/src/d2m/converters/message-to-event.js
@@ -542,16 +542,9 @@ async function messageToEvent(message, guild, options = {}, di) {
$type: "m.room.message",
"m.mentions": mentions,
msgtype,
- body: body
- }
-
- const isPlaintext = body === html
-
- if (!isPlaintext || options.alwaysReturnFormattedBody) {
- Object.assign(newTextMessageEvent, {
- format: "org.matrix.custom.html",
- formatted_body: html
- })
+ body: body,
+ format: "org.matrix.custom.html",
+ formatted_body: html
}
events.push(newTextMessageEvent)
@@ -695,7 +688,18 @@ async function messageToEvent(message, guild, options = {}, di) {
// Then attachments
if (message.attachments) {
const attachmentEvents = await Promise.all(message.attachments.map(attachmentToEvent.bind(null, mentions)))
- events.push(...attachmentEvents)
+
+ // Try to merge attachment events with the previous event
+ // This means that if the attachments ended up as a text link, and especially if there were many of them, the events will be joined together.
+ let prev = events.at(-1)
+ for (const atch of attachmentEvents) {
+ if (atch.msgtype === "m.text" && prev?.body && prev?.formatted_body && ["m.text", "m.notice"].includes(prev?.msgtype)) {
+ prev.body = prev.body + "\n" + atch.body
+ prev.formatted_body = prev.formatted_body + "
" + atch.formatted_body
+ } else {
+ events.push(atch)
+ }
+ }
}
// Then embeds
@@ -829,6 +833,16 @@ async function messageToEvent(message, guild, options = {}, di) {
})
}
+ // Strip formatted_body where equivalent to body
+ if (!options.alwaysReturnFormattedBody) {
+ for (const event of events) {
+ if (["m.text", "m.notice"].includes(event.msgtype) && event.body === event.formatted_body) {
+ delete event.format
+ delete event.formatted_body
+ }
+ }
+ }
+
return events
}
diff --git a/src/d2m/converters/message-to-event.test.js b/src/d2m/converters/message-to-event.test.js
index fa51eae..3c0c5d9 100644
--- a/src/d2m/converters/message-to-event.test.js
+++ b/src/d2m/converters/message-to-event.test.js
@@ -869,14 +869,62 @@ test("message2event: very large attachment is linked instead of being uploaded",
$type: "m.room.message",
"m.mentions": {},
msgtype: "m.text",
- body: "hey"
- }, {
+ body: "hey\n๐ Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)",
+ format: "org.matrix.custom.html",
+ formatted_body: 'hey
๐ Uploaded file: hey.jpg (100 MB)'
+ }])
+})
+
+test("message2event: multiple attachments are combined into the same event where possible", async t => {
+ const events = await messageToEvent({
+ content: "hey",
+ attachments: [{
+ filename: "hey.jpg",
+ url: "https://cdn.discordapp.com/attachments/123/456/789.mega",
+ content_type: "application/i-made-it-up",
+ size: 100e6
+ }, {
+ filename: "SPOILER_secret.jpg",
+ url: "https://cdn.discordapp.com/attachments/123/456/SPOILER_secret.jpg",
+ content_type: "image/jpeg",
+ size: 38291
+ }, {
+ filename: "my enemies.txt",
+ url: "https://cdn.discordapp.com/attachments/123/456/my_enemies.txt",
+ content_type: "text/plain",
+ size: 8911
+ }, {
+ filename: "hey.jpg",
+ url: "https://cdn.discordapp.com/attachments/123/456/789.mega",
+ content_type: "application/i-made-it-up",
+ size: 100e6
+ }]
+ })
+ t.deepEqual(events, [{
$type: "m.room.message",
"m.mentions": {},
msgtype: "m.text",
- body: "๐ Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)",
+ body: "hey"
+ + "\n๐ Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)"
+ + "\n๐ธ Uploaded SPOILER file: https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg (38 KB)"
+ + "\n๐ Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)",
format: "org.matrix.custom.html",
- formatted_body: '๐ Uploaded file: hey.jpg (100 MB)'
+ formatted_body: "hey"
+ + `
๐ Uploaded file: hey.jpg (100 MB)`
+ + `
๐ธ Uploaded SPOILER file: https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg (38 KB)` + + `
@unknown-user:`, - "m.mentions": {} - }, { - $type: "m.room.message", - msgtype: "m.text", - body: "ยป ๐๏ธ Uploaded file: https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4 (51 MB)", - format: "org.matrix.custom.html", - formatted_body: "
๐๏ธ Uploaded file: 2022-10-18_16-49-46.mp4 (51 MB)", - "m.mentions": {} - } - ]) + t.deepEqual(events, [{ + $type: "m.room.message", + msgtype: "m.text", + body: "[๐ Forwarded message]\nยป @unknown-user:\nยป ๐๏ธ Uploaded file: https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4 (51 MB)", + format: "org.matrix.custom.html", + formatted_body: "๐ Forwarded message
@unknown-user:", + "m.mentions": {} + }]) }) diff --git a/test/ooye-test-data.sql b/test/ooye-test-data.sql index ef3dc5f..04e6b9b 100644 --- a/test/ooye-test-data.sql +++ b/test/ooye-test-data.sql @@ -151,7 +151,8 @@ INSERT INTO file (discord_url, mxc_url) VALUES ('https://cdn.discordapp.com/attachments/112760669178241024/1197621094786531358/Ins_1960637570.mp4', 'mxc://cadence.moe/kMqLycqMURhVpwleWkmASpnU'), ('https://cdn.discordapp.com/attachments/1099031887500034088/1112476845502365786/voice-message.ogg', 'mxc://cadence.moe/MRRPDggXQMYkrUjTpxQbmcxB'), ('https://cdn.discordapp.com/attachments/122155380120748034/1174514575220158545/the.yml', 'mxc://cadence.moe/HnQIYQmmlIKwOQsbFsIGpzPP'), -('https://cdn.discordapp.com/attachments/112760669178241024/1296237494987133070/100km.gif', 'mxc://cadence.moe/qDAotmebTfEIfsAIVCEZptLh'); +('https://cdn.discordapp.com/attachments/112760669178241024/1296237494987133070/100km.gif', 'mxc://cadence.moe/qDAotmebTfEIfsAIVCEZptLh'), +('https://cdn.discordapp.com/attachments/123/456/my_enemies.txt', 'mxc://cadence.moe/y89EOTRp2lbeOkgdsEleGOge'); INSERT INTO emoji (emoji_id, name, animated, mxc_url) VALUES ('230201364309868544', 'hippo', 0, 'mxc://cadence.moe/qWmbXeRspZRLPcjseyLmeyXC'),
๐๏ธ Uploaded file: 2022-10-18_16-49-46.mp4 (51 MB)