Refactor cross-room event detection

This commit is contained in:
Cadence Ember
2026-01-13 22:20:11 +13:00
parent 536ab56048
commit fcd4eb4e51
2 changed files with 43 additions and 35 deletions
+41 -33
View File
@@ -286,8 +286,8 @@ async function messageToEvent(message, guild, options = {}, di) {
// Mentions scenarios 1 and 2, part A. i.e. translate relevant message.mentions to m.mentions // Mentions scenarios 1 and 2, part A. i.e. translate relevant message.mentions to m.mentions
// (Still need to do scenarios 1 and 2 part B, and scenario 3.) // (Still need to do scenarios 1 and 2 part B, and scenario 3.)
if (message.type === DiscordTypes.MessageType.Reply && message.message_reference?.message_id) { if (message.type === DiscordTypes.MessageType.Reply && message.message_reference?.message_id) {
const row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index").select("event_id", "room_id", "reference_channel_id", "source").and("WHERE message_id = ? ORDER BY part ASC").get(message.message_reference.message_id) const row = await getHistoricalEventRow(message.message_reference?.message_id)
if (row) { if (row && "event_id" in row) {
repliedToEventRow = Object.assign(row, {channel_id: row.reference_channel_id}) repliedToEventRow = Object.assign(row, {channel_id: row.reference_channel_id})
} else if (message.referenced_message) { } else if (message.referenced_message) {
repliedToUnknownEvent = true repliedToUnknownEvent = true
@@ -300,8 +300,8 @@ async function messageToEvent(message, guild, options = {}, di) {
assert(message.embeds[0].description) assert(message.embeds[0].description)
const match = message.embeds[0].description.match(/\/channels\/[0-9]*\/[0-9]*\/([0-9]{2,})/) const match = message.embeds[0].description.match(/\/channels\/[0-9]*\/[0-9]*\/([0-9]{2,})/)
if (match) { if (match) {
const row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index").select("event_id", "room_id", "reference_channel_id", "source").and("WHERE message_id = ? ORDER BY part ASC").get(match[1]) const row = await getHistoricalEventRow(match[1])
if (row) { if (row && "event_id" in row) {
/* /*
we generate a partial referenced_message based on what PK provided. we don't need everything, since this will only be used for further message-to-event converting. we generate a partial referenced_message based on what PK provided. we don't need everything, since this will only be used for further message-to-event converting.
the following properties are necessary: the following properties are necessary:
@@ -346,6 +346,34 @@ async function messageToEvent(message, guild, options = {}, di) {
return promise return promise
} }
/**
* @param {string} messageID
* @param {string} [timestampChannelID]
*/
async function getHistoricalEventRow(messageID, timestampChannelID) {
/** @type {{room_id: string} | {event_id: string, room_id: string, reference_channel_id: string, source: number} | null} */
let row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index")
.select("event_id", "room_id", "reference_channel_id", "source").where({message_id: messageID}).and("ORDER BY part ASC").get()
if (!row && timestampChannelID) {
const ts = dUtils.snowflakeToTimestampExact(messageID)
const oldestRow = from("historical_channel_room").selectUnsafe("max(upgraded_timestamp)", "room_id")
.where({reference_channel_id: timestampChannelID}).and("and upgraded_timestamp < ?").get(ts)
if (oldestRow?.room_id) {
row = {room_id: oldestRow.room_id}
try {
const {event_id} = await di.api.getEventForTimestamp(oldestRow.room_id, ts)
row = {
event_id,
room_id: oldestRow.room_id,
reference_channel_id: oldestRow.reference_channel_id,
source: 1
}
} catch (e) {}
}
}
return row
}
/** /**
* Translate Discord message links to Matrix event links. * Translate Discord message links to Matrix event links.
* If OOYE has handled this message in the past, this is an instant database lookup. * If OOYE has handled this message in the past, this is an instant database lookup.
@@ -358,30 +386,11 @@ async function messageToEvent(message, guild, options = {}, di) {
assert(typeof match.index === "number") assert(typeof match.index === "number")
const [_, channelID, messageID] = match const [_, channelID, messageID] = match
const result = await (async () => { const result = await (async () => {
const row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index") const row = await getHistoricalEventRow(messageID, channelID)
.select("event_id", "room_id").where({message_id: messageID}).get() if (!row) return `${match[0]} [event is from another server]`
// const roomID = select("channel_room", "room_id", {channel_id: channelID}).pluck().get() const via = await getViaServersMemo(row.room_id)
if (row) { if (!("event_id" in row)) return `[unknown event in https://matrix.to/#/${row.room_id}?${via}]`
const via = await getViaServersMemo(row.room_id) return `https://matrix.to/#/${row.room_id}/${row.event_id}?${via}`
return `https://matrix.to/#/${row.room_id}/${row.event_id}?${via}`
}
const ts = dUtils.snowflakeToTimestampExact(messageID)
const oldestRow = from("historical_channel_room").selectUnsafe("max(upgraded_timestamp)", "room_id")
.where({reference_channel_id: channelID}).and("and upgraded_timestamp < ?").get(ts)
if (oldestRow?.room_id) {
const via = await getViaServersMemo(oldestRow.room_id)
try {
const {event_id} = await di.api.getEventForTimestamp(oldestRow.room_id, ts)
return `https://matrix.to/#/${oldestRow.room_id}/${event_id}?${via}`
} catch (e) {
// M_NOT_FOUND: Unable to find event from <ts> in direction Direction.FORWARDS
// not supported in Conduit and descendants
return `[unknown event, timestamp resolution failed, in room: https://matrix.to/#/${oldestRow.room_id}?${via}]`
}
}
return `${match[0]} [event is from another server]`
})() })()
content = content.slice(0, match.index + offset) + result + content.slice(match.index + match[0].length + offset) content = content.slice(0, match.index + offset) + result + content.slice(match.index + match[0].length + offset)
@@ -561,17 +570,16 @@ async function messageToEvent(message, guild, options = {}, di) {
// Forwarded content appears first // Forwarded content appears first
if (message.message_reference?.type === DiscordTypes.MessageReferenceType.Forward && message.message_snapshots?.length) { if (message.message_reference?.type === DiscordTypes.MessageReferenceType.Forward && message.message_snapshots?.length) {
// Forwarded notice // Forwarded notice
const event = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index") const row = await getHistoricalEventRow(message.message_reference.message_id, message.message_reference.channel_id)
.select("event_id", "room_id").where({message_id: message.message_reference.message_id}).get()
const room = select("channel_room", ["room_id", "name", "nick"], {channel_id: message.message_reference.channel_id}).get() const room = select("channel_room", ["room_id", "name", "nick"], {channel_id: message.message_reference.channel_id}).get()
const forwardedNotice = new mxUtils.MatrixStringBuilder() const forwardedNotice = new mxUtils.MatrixStringBuilder()
if (room) { if (room) {
const roomName = room && (room.nick || room.name) const roomName = room && (room.nick || room.name)
if (event) { if ("event_id" in row) {
const via = await getViaServersMemo(event.room_id) const via = await getViaServersMemo(row.room_id)
forwardedNotice.addLine( forwardedNotice.addLine(
`[🔀 Forwarded from #${roomName}]`, `[🔀 Forwarded from #${roomName}]`,
tag`🔀 <em>Forwarded from ${roomName} <a href="https://matrix.to/#/${room.room_id}/${event.event_id}?${via}">[jump to event]</a></em>` tag`🔀 <em>Forwarded from ${roomName} <a href="https://matrix.to/#/${room.room_id}/${row.event_id}?${via}">[jump to event]</a></em>`
) )
} else { } else {
const via = await getViaServersMemo(room.room_id) const via = await getViaServersMemo(room.room_id)
+2 -2
View File
@@ -287,10 +287,10 @@ test("message2event: message timestamp failed to fetch", async t => {
"m.mentions": {}, "m.mentions": {},
msgtype: "m.text", msgtype: "m.text",
body: "Me: I'll scroll up to find a certain message I'll send\n_scrolls up and clicks message links for god knows how long_\n_completely forgets what they were looking for and simply begins scrolling up to find some fun moments_\n_stumbles upon:_ " body: "Me: I'll scroll up to find a certain message I'll send\n_scrolls up and clicks message links for god knows how long_\n_completely forgets what they were looking for and simply begins scrolling up to find some fun moments_\n_stumbles upon:_ "
+ "[unknown event, timestamp resolution failed, in room: https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org]", + "[unknown event in https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org]",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: "Me: I'll scroll up to find a certain message I'll send<br><em>scrolls up and clicks message links for god knows how long</em><br><em>completely forgets what they were looking for and simply begins scrolling up to find some fun moments</em><br><em>stumbles upon:</em> " formatted_body: "Me: I'll scroll up to find a certain message I'll send<br><em>scrolls up and clicks message links for god knows how long</em><br><em>completely forgets what they were looking for and simply begins scrolling up to find some fun moments</em><br><em>stumbles upon:</em> "
+ '[unknown event, timestamp resolution failed, in room: <a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org</a>]' + '[unknown event in <a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org</a>]'
}]) }])
t.equal(called, 2, "getEventForTimestamp and getJoinedMembers should be called once each") t.equal(called, 2, "getEventForTimestamp and getJoinedMembers should be called once each")
}) })