Merge attachments with message when possible

This commit is contained in:
Cadence Ember
2026-01-21 13:25:30 +13:00
parent ddc7387fa0
commit 345b7d6135
3 changed files with 87 additions and 33 deletions

View File

@@ -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 + "<br>" + 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
}

View File

@@ -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<br>📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (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: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)'
formatted_body: "hey"
+ `<br>📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)`
+ `<br><blockquote>📸 Uploaded SPOILER file: <a href="https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg">https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg</a> (38 KB)</blockquote>`
+ `<br>📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)`
}, {
$type: "m.room.message",
"m.mentions": {},
msgtype: "m.file",
body: "my enemies.txt",
filename: "my enemies.txt",
external_url: "https://bridge.example.org/download/discordcdn/123/456/my_enemies.txt",
url: "mxc://cadence.moe/y89EOTRp2lbeOkgdsEleGOge",
info: {
mimetype: "text/plain",
size: 8911
}
}])
})
@@ -1494,21 +1542,12 @@ test("message2event: forwarded message with unreferenced mention", async t => {
}
]
})
t.deepEqual(events, [
{
$type: "m.room.message",
msgtype: "m.text",
body: "[🔀 Forwarded message]\n» @unknown-user:",
format: "org.matrix.custom.html",
formatted_body: `🔀 <em>Forwarded message</em><br><blockquote>@unknown-user:</blockquote>`,
"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: "<blockquote>🎞️ Uploaded file: <a href=\"https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4\">2022-10-18_16-49-46.mp4</a> (51 MB)</blockquote>",
"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: "🔀 <em>Forwarded message</em><br><blockquote>@unknown-user:<br>🎞️ Uploaded file: <a href=\"https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4\">2022-10-18_16-49-46.mp4</a> (51 MB)</blockquote>",
"m.mentions": {}
}])
})

View File

@@ -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'),