Finish adding via parameters to all room links

This commit is contained in:
Cadence Ember 2024-02-13 16:52:21 +13:00
parent 13d1f86d31
commit fd11e3fd10
5 changed files with 117 additions and 32 deletions

View file

@ -113,10 +113,10 @@ test("message2event embeds: blockquote in embed", async t => {
msgtype: "m.notice", msgtype: "m.notice",
body: "| ## ⏺️ minimus https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid\n| \n| reply draft\n| > The following is a message composed via consensus of the Stinker Council.\n| > \n| > For those who are not currently aware of our existence, we represent the organization known as Wonderland. Our previous mission centered around the assortment and study of puzzling objects, entities and other assorted phenomena. This mission was the focus of our organization for more than 28 years.\n| > \n| > Due to circumstances outside of our control, this directive has now changed. Our new mission will be the extermination of the stinker race.\n| > \n| > There will be no further communication.\n| \n| [Go to Message](https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid)", body: "| ## ⏺️ minimus https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid\n| \n| reply draft\n| > The following is a message composed via consensus of the Stinker Council.\n| > \n| > For those who are not currently aware of our existence, we represent the organization known as Wonderland. Our previous mission centered around the assortment and study of puzzling objects, entities and other assorted phenomena. This mission was the focus of our organization for more than 28 years.\n| > \n| > Due to circumstances outside of our control, this directive has now changed. Our new mission will be the extermination of the stinker race.\n| > \n| > There will be no further communication.\n| \n| [Go to Message](https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid)",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: "<blockquote><p><strong><a href=\"https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid\">⏺️ minimus</a></strong></p><p>reply draft<br><blockquote>The following is a message composed via consensus of the Stinker Council.<br><br>For those who are not currently aware of our existence, we represent the organization known as Wonderland. Our previous mission centered around the assortment and study of puzzling objects, entities and other assorted phenomena. This mission was the focus of our organization for more than 28 years.<br><br>Due to circumstances outside of our control, this directive has now changed. Our new mission will be the extermination of the stinker race.<br><br>There will be no further communication.</blockquote></p><p><a href=\"https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&via=example.invalid \">Go to Message</a></p></blockquote>", formatted_body: "<blockquote><p><strong><a href=\"https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&amp;via=example.invalid\">⏺️ minimus</a></strong></p><p>reply draft<br><blockquote>The following is a message composed via consensus of the Stinker Council.<br><br>For those who are not currently aware of our existence, we represent the organization known as Wonderland. Our previous mission centered around the assortment and study of puzzling objects, entities and other assorted phenomena. This mission was the focus of our organization for more than 28 years.<br><br>Due to circumstances outside of our control, this directive has now changed. Our new mission will be the extermination of the stinker race.<br><br>There will be no further communication.</blockquote></p><p><a href=\"https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo?via=cadence.moe&amp;via=example.invalid\">Go to Message</a></p></blockquote>",
"m.mentions": {} "m.mentions": {}
}]) }])
t.equal(called, 2) t.equal(called, 2, "should call getStateEvent and getJoinedMembers once each")
}) })
test("message2event embeds: crazy html is all escaped", async t => { test("message2event embeds: crazy html is all escaped", async t => {

View file

@ -39,13 +39,12 @@ function getDiscordParseCallbacks(message, guild, useHTML) {
return `@${username}:` return `@${username}:`
} }
}, },
// FIXME: type /** @param {{id: string, type: "discordChannel", row: {room_id: string, name: string, nick: string?}?, via: string}} node */
/** @param {{id: string, type: "discordChannel", row: any, via: URLSearchParams}} node */
channel: node => { channel: node => {
if (!node.row) { if (!node.row) {
return `#[channel-from-an-unknown-server]` // fallback for when this channel is not bridged return `#[channel-from-an-unknown-server]` // fallback for when this channel is not bridged
} else if (useHTML) { } else if (useHTML) {
return `<a href="https://matrix.to/#/${node.row.room_id}?${node.via.toString()}">#${node.row.nick || node.row.name}</a>` return `<a href="https://matrix.to/#/${node.row.room_id}?${node.via}">#${node.row.nick || node.row.name}</a>`
} else { } else {
return `#${node.row.nick || node.row.name}` return `#${node.row.nick || node.row.name}`
} }
@ -283,6 +282,20 @@ async function messageToEvent(message, guild, options = {}, di) {
addMention(repliedToEventSenderMxid) addMention(repliedToEventSenderMxid)
} }
/** @type {Map<string, Promise<string>>} */
const viaMemo = new Map()
/**
* @param {string} roomID
* @returns {Promise<string>} string encoded URLSearchParams
*/
function getViaServersMemo(roomID) {
// @ts-ignore
if (viaMemo.has(roomID)) return viaMemo.get(roomID)
const promise = mxUtils.getViaServersQuery(roomID, di.api).then(p => p.toString())
viaMemo.set(roomID, promise)
return promise
}
/** /**
* 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.
@ -299,12 +312,13 @@ async function messageToEvent(message, guild, options = {}, di) {
const roomID = select("channel_room", "room_id", {channel_id: channelID}).pluck().get() const roomID = select("channel_room", "room_id", {channel_id: channelID}).pluck().get()
if (roomID) { if (roomID) {
const eventID = select("event_message", "event_id", {message_id: messageID}).pluck().get() const eventID = select("event_message", "event_id", {message_id: messageID}).pluck().get()
const via = await getViaServersMemo(roomID)
if (eventID && roomID) { if (eventID && roomID) {
result = `https://matrix.to/#/${roomID}/${eventID}` result = `https://matrix.to/#/${roomID}/${eventID}?${via}`
} else { } else {
const ts = dUtils.snowflakeToTimestampExact(messageID) const ts = dUtils.snowflakeToTimestampExact(messageID)
const {event_id} = await di.api.getEventForTimestamp(roomID, ts) const {event_id} = await di.api.getEventForTimestamp(roomID, ts)
result = `https://matrix.to/#/${roomID}/${event_id}` result = `https://matrix.to/#/${roomID}/${event_id}?${via}`
} }
} else { } else {
result = `${match[0]} [event is from another server]` result = `${match[0]} [event is from another server]`
@ -341,7 +355,7 @@ async function messageToEvent(message, guild, options = {}, di) {
if (node.type === "discordChannel") { if (node.type === "discordChannel") {
node.row = select("channel_room", ["room_id", "name", "nick"], {channel_id: node.id}).get() node.row = select("channel_room", ["room_id", "name", "nick"], {channel_id: node.id}).get()
if (node.row?.room_id) { if (node.row?.room_id) {
node.via = await mxUtils.getViaServersQuery(node.row.room_id, di.api) node.via = await getViaServersMemo(node.row.room_id)
} }
} }
if (Array.isArray(node.content)) { if (Array.isArray(node.content)) {

View file

@ -96,7 +96,7 @@ test("message2event: simple room mention", async t => {
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org">#main</a>' formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org">#main</a>'
}]) }])
t.equal(called, 2) t.equal(called, 2, "should call getStateEvent and getJoinedMembers once each")
}) })
test("message2event: unknown room mention", async t => { test("message2event: unknown room mention", async t => {
@ -134,15 +134,41 @@ test("message2event: manually constructed unknown roles should use fallback", as
}) })
test("message2event: simple message link", async t => { test("message2event: simple message link", async t => {
const events = await messageToEvent(data.message.simple_message_link, data.guild.general, {}) let called = 0
const events = await messageToEvent(data.message.simple_message_link, data.guild.general, {}, {
api: {
async getStateEvent(roomID, type, key) {
called++
t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {
users: {
"@_ooye_bot:cadence.moe": 100
}
}
},
async getJoinedMembers(roomID) {
called++
t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
return {
joined: {
"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
"@user:super.invalid": {display_name: null, avatar_url: null}
}
}
}
}
})
t.deepEqual(events, [{ t.deepEqual(events, [{
$type: "m.room.message", $type: "m.room.message",
"m.mentions": {}, "m.mentions": {},
msgtype: "m.text", msgtype: "m.text",
body: "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg", body: "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&via=super.invalid",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg</a>' formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&amp;via=super.invalid">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&amp;via=super.invalid</a>'
}]) }])
t.equal(called, 2, "should call getStateEvent and getJoinedMembers once each")
}) })
test("message2event: message link that OOYE doesn't know about", async t => { test("message2event: message link that OOYE doesn't know about", async t => {
@ -156,6 +182,27 @@ test("message2event: message link that OOYE doesn't know about", async t => {
event_id: "$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U", event_id: "$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U",
origin_server_ts: 1613287812754 origin_server_ts: 1613287812754
} }
},
async getStateEvent(roomID, type, key) { // for ?via calculation
called++
t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {
users: {
"@_ooye_bot:cadence.moe": 100
}
}
},
async getJoinedMembers(roomID) { // for ?via calculation
called++
t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
return {
joined: {
"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
"@user:matrix.org": {display_name: null, avatar_url: null}
}
}
} }
} }
}) })
@ -164,12 +211,12 @@ test("message2event: message link that OOYE doesn't know about", 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:_ "
+ "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U", + "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?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> "
+ '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U</a>' + '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?via=cadence.moe&amp;via=matrix.org">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?via=cadence.moe&amp;via=matrix.org</a>'
}]) }])
t.equal(called, 1, "getEventForTimestamp should be called once") t.equal(called, 3, "getEventForTimestamp, getStateEvent, and getJoinedMembers should be called once each")
}) })
test("message2event: message link from another server", async t => { test("message2event: message link from another server", async t => {

View file

@ -6,6 +6,8 @@ const passthrough = require("../../passthrough")
const {discord, sync, db, select} = passthrough const {discord, sync, db, select} = passthrough
/** @type {import("../../matrix/read-registration")} */ /** @type {import("../../matrix/read-registration")} */
const reg = sync.require("../../matrix/read-registration.js") const reg = sync.require("../../matrix/read-registration.js")
/** @type {import("../../m2d/converters/utils")} */
const mxUtils = sync.require("../../m2d/converters/utils")
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex)) const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
@ -29,8 +31,9 @@ async function threadToAnnouncement(parentRoomID, threadRoomID, creatorMxid, thr
const msgtype = creatorMxid ? "m.emote" : "m.text" const msgtype = creatorMxid ? "m.emote" : "m.text"
const template = creatorMxid ? "started a thread:" : "Thread started:" const template = creatorMxid ? "started a thread:" : "Thread started:"
let body = `${template} ${thread.name} https://matrix.to/#/${threadRoomID}` const via = await mxUtils.getViaServersQuery(threadRoomID, di.api)
let html = `${template} <a href="https://matrix.to/#/${threadRoomID}">${thread.name}</a>` let body = `${template} ${thread.name} https://matrix.to/#/${threadRoomID}?${via.toString()}`
let html = `${template} <a href="https://matrix.to/#/${threadRoomID}?${via.toString()}">${thread.name}</a>`
return { return {
msgtype, msgtype,

View file

@ -29,16 +29,34 @@ function mockGetEvent(t, roomID_in, eventID_in, outer) {
} }
} }
const viaApi = {
async getStateEvent(roomID, type, key) {
return {
users: {
"@_ooye_bot:cadence.moe": 100
}
}
},
async getJoinedMembers(roomID) {
return {
joined: {
"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
"@user:matrix.org": {display_name: null, avatar_url: null}
}
}
}
}
test("thread2announcement: no known creator, no branched from event", async t => { test("thread2announcement: no known creator, no branched from event", async t => {
const content = await threadToAnnouncement("!parent", "!thread", null, { const content = await threadToAnnouncement("!parent", "!thread", null, {
name: "test thread", name: "test thread",
id: "-1" id: "-1"
}) }, {api: viaApi})
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread", body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: `Thread started: <a href="https://matrix.to/#/!thread">test thread</a>`, formatted_body: `Thread started: <a href="https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org">test thread</a>`,
"m.mentions": {} "m.mentions": {}
}) })
}) })
@ -47,12 +65,12 @@ test("thread2announcement: known creator, no branched from event", async t => {
const content = await threadToAnnouncement("!parent", "!thread", "@_ooye_crunch_god:cadence.moe", { const content = await threadToAnnouncement("!parent", "!thread", "@_ooye_crunch_god:cadence.moe", {
name: "test thread", name: "test thread",
id: "-1" id: "-1"
}) }, {api: viaApi})
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.emote", msgtype: "m.emote",
body: "started a thread: test thread https://matrix.to/#/!thread", body: "started a thread: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: `started a thread: <a href="https://matrix.to/#/!thread">test thread</a>`, formatted_body: `started a thread: <a href="https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org">test thread</a>`,
"m.mentions": {} "m.mentions": {}
}) })
}) })
@ -70,14 +88,15 @@ test("thread2announcement: no known creator, branched from discord event", async
msgtype: 'm.text', msgtype: 'm.text',
body: 'testing testing testing' body: 'testing testing testing'
} }
}) }),
...viaApi
} }
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread", body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: `Thread started: <a href="https://matrix.to/#/!thread">test thread</a>`, formatted_body: `Thread started: <a href="https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org">test thread</a>`,
"m.mentions": {}, "m.mentions": {},
"m.relates_to": { "m.relates_to": {
"m.in_reply_to": { "m.in_reply_to": {
@ -100,14 +119,15 @@ test("thread2announcement: known creator, branched from discord event", async t
msgtype: 'm.text', msgtype: 'm.text',
body: 'testing testing testing' body: 'testing testing testing'
} }
}) }),
...viaApi
} }
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.emote", msgtype: "m.emote",
body: "started a thread: test thread https://matrix.to/#/!thread", body: "started a thread: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: `started a thread: <a href="https://matrix.to/#/!thread">test thread</a>`, formatted_body: `started a thread: <a href="https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org">test thread</a>`,
"m.mentions": {}, "m.mentions": {},
"m.relates_to": { "m.relates_to": {
"m.in_reply_to": { "m.in_reply_to": {
@ -130,14 +150,15 @@ test("thread2announcement: no known creator, branched from matrix event", async
body: "so can you reply to my webhook uwu" body: "so can you reply to my webhook uwu"
}, },
sender: "@cadence:cadence.moe" sender: "@cadence:cadence.moe"
}) }),
...viaApi
} }
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread", body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: `Thread started: <a href="https://matrix.to/#/!thread">test thread</a>`, formatted_body: `Thread started: <a href="https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org">test thread</a>`,
"m.mentions": { "m.mentions": {
user_ids: ["@cadence:cadence.moe"] user_ids: ["@cadence:cadence.moe"]
}, },