Display limited replies to unbridged messages

This commit is contained in:
Cadence Ember 2025-02-24 01:41:32 +13:00
parent fb38db5d23
commit 6df8d9a079
5 changed files with 139 additions and 9 deletions

View file

@ -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: '<blockquote><p><strong><a href="https://twitter.com/i/user/719631291747078145">⏺️ dynastic (@dynastic)</a></strong>'
formatted_body: '<blockquote>In reply to an unbridged message from PokemonGod:<br><a href=\"https://twitter.com/dynastic/status/1707484191963648161\">https://twitter.com/dynastic/status/1707484191963648161</a></blockquote>'
+ '<blockquote><p><strong><a href="https://twitter.com/i/user/719631291747078145">⏺️ dynastic (@dynastic)</a></strong>'
+ '</p><p>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?'
+ '</p><p><strong>Retweets</strong><br>119</p><p><strong>Likes</strong><br>5581</p>— Twitter</blockquote>'
}])

View file

@ -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 = `<mx-reply><blockquote><a href="https://matrix.to/#/${repliedToEventRow.room_id}/${repliedToEventRow.event_id}">In reply to</a> ${repliedToUserHtml}`
+ `<br>${repliedToHtml}</blockquote></mx-reply>`
+ 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 = `<mx-reply><blockquote><a href="https://matrix.to/#/${repliedToEventRow.room_id}/${repliedToEventRow.event_id}">In reply to</a> ${repliedToUserHtml}`
+ `<br>${repliedToHtml}</blockquote></mx-reply>`
+ 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 = `<blockquote>In reply to a${dateDisplay} unbridged message from ${repliedToDisplayName}:`
+ `<br>${repliedToHtml}</blockquote>`
+ html
body = (`In reply to a${dateDisplay} unbridged message:\n${repliedToDisplayName}: `
+ repliedToBody).split("\n").map(line => "> " + line).join("\n")
+ "\n\n" + body
}
}
const newTextMessageEvent = {

View file

@ -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: `<blockquote>In reply to a 1-day-old unbridged message from Occimyy:<br>BILLY BOB THE GREAT</blockquote>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: {

View file

@ -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") {

View file

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