Compare commits

...

4 commits

Author SHA1 Message Date
10fbb9e696 improved consistency 2026-02-27 23:11:50 +00:00
edfbdc567f Used getThreadRoomFromThreadEvent in practice 2026-02-27 23:07:43 +00:00
c9509bb938 figured out how tests work, yaaayyyy
As a part of that:
* rewrote the tests to support my changed behaviors
* added a missing case
* Made my „threads get attached to” wording more consistent with the test cases („threads branch from”), as I always felt that there was something off about my phrasing, but I couldn't quite tell what was it. OOYE's „branch” term seems much more fitting there
* slightly cooked the testing data (changed the „Hey.” thread from „floating” to being a branch of a message, to accommodate...)
* 3 NEW TESTS: of the function created in my previous commit (I'm not sure if this *REALLY* needed testing, given how braindead-simple that function is, but everything else in utils.js is covered, so I figured it's only fair to test this, too)

EXTRA CHANGE: fixed that function's name (we're getting the thread from a (Matrix) Event, not a (Discord) Message) and description (I totally didn't copy-paste the JSDoc from above........)
2026-02-27 20:42:16 +00:00
42c32ba749 explained my technical decisions; made a function that'll help me later 2026-02-27 13:06:52 +00:00
6 changed files with 117 additions and 44 deletions

View file

@ -49,7 +49,7 @@ test("thread2announcement: no known creator, no branched from event", async t =>
}, {api: viaApi}) }, {api: viaApi})
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org", body: "New thread started: „test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
"m.mentions": {} "m.mentions": {}
}) })
}) })
@ -61,7 +61,7 @@ test("thread2announcement: known creator, no branched from event", async t => {
}, {api: viaApi}) }, {api: viaApi})
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.emote", msgtype: "m.emote",
body: "started a thread: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org", body: "started a thread test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org",
"m.mentions": {} "m.mentions": {}
}) })
}) })
@ -85,12 +85,15 @@ test("thread2announcement: no known creator, branched from discord event", async
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org", body: "New thread started: „test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org\n[Note: You should continue the conversation in that room, rather than in this thread. Any messages sent in Matrix threads will be bridged to Discord as replies, not in-thread messages, which is probably not what you want.]",
"m.mentions": {}, "m.mentions": {},
"m.relates_to": { "m.relates_to": {
"event_id": "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg",
"is_falling_back": false,
"m.in_reply_to": { "m.in_reply_to": {
event_id: "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg" "event_id": "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg",
} },
"rel_type": "m.thread",
} }
}) })
}) })
@ -114,12 +117,15 @@ test("thread2announcement: known creator, branched from discord event", async t
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.emote", msgtype: "m.emote",
body: "started a thread: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org", body: "started a thread test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org\n[Note: You should continue the conversation in that room, rather than in this thread. Any messages sent in Matrix threads will be bridged to Discord as replies, not in-thread messages, which is probably not what you want.]",
"m.mentions": {}, "m.mentions": {},
"m.relates_to": { "m.relates_to": {
"event_id": "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg",
"is_falling_back": false,
"m.in_reply_to": { "m.in_reply_to": {
event_id: "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg" "event_id": "$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg",
} },
"rel_type": "m.thread",
} }
}) })
}) })
@ -143,14 +149,51 @@ test("thread2announcement: no known creator, branched from matrix event", async
}) })
t.deepEqual(content, { t.deepEqual(content, {
msgtype: "m.text", msgtype: "m.text",
body: "Thread started: test thread https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org", body: "New thread started: „test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org\n[Note: You should continue the conversation in that room, rather than in this thread. Any messages sent in Matrix threads will be bridged to Discord as replies, not in-thread messages, which is probably not what you want.]",
"m.mentions": { "m.mentions": {
user_ids: ["@cadence:cadence.moe"] user_ids: ["@cadence:cadence.moe"]
}, },
"m.relates_to": { "m.relates_to": {
"event_id": "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4",
"is_falling_back": false,
"m.in_reply_to": { "m.in_reply_to": {
event_id: "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4" "event_id": "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4",
} },
"rel_type": "m.thread",
}
})
})
test("thread2announcement: known creator, branched from matrix event", async t => {
const content = await threadToAnnouncement("!kLRqKKUQXcibIMtOpl:cadence.moe", "!thread", "@_ooye_crunch_god:cadence.moe", {
name: "test thread",
id: "1128118177155526666"
}, {
api: {
getEvent: mockGetEvent(t, "!kLRqKKUQXcibIMtOpl:cadence.moe", "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4", {
type: "m.room.message",
content: {
msgtype: "m.text",
body: "so can you reply to my webhook uwu"
},
sender: "@cadence:cadence.moe"
}),
...viaApi
}
})
t.deepEqual(content, {
msgtype: "m.emote",
body: "started a thread „test thread” in room: https://matrix.to/#/!thread?via=cadence.moe&via=matrix.org\n[Note: You should continue the conversation in that room, rather than in this thread. Any messages sent in Matrix threads will be bridged to Discord as replies, not in-thread messages, which is probably not what you want.]",
"m.mentions": {
user_ids: ["@cadence:cadence.moe"]
},
"m.relates_to": {
"event_id": "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4",
"is_falling_back": false,
"m.in_reply_to": {
"event_id": "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4",
},
"rel_type": "m.thread",
} }
}) })
}) })

View file

@ -222,18 +222,19 @@ async event => {
) )
} }
if (event.content["m.relates_to"]?.rel_type === "m.thread" && executedCommand !== "thread"){ if (event.content["m.relates_to"]?.rel_type === "m.thread" && executedCommand !== "thread"){
const bridgedTo = utils.getThreadRoomFromThreadEvent(event.event_id)
api.sendEvent(event.room_id, "m.room.message", { api.sendEvent(event.room_id, "m.room.message", {
"body": "⚠️ **This message may not have been bridged to Discord in the way you thought it was gonna be!**\n\nIt seems like you sent this message inside a Matrix thread. Matrix threads don't work like Discord threads - they are effectively just „fancy replies”, not independent rooms/channels (any „thread-like appearance” is handled purely client-side - and even then, most Matrix clients don't handle it particularly well, with Element being the only one known to actually render threads as threads), and as such, they are bridged as replies to Discord. *In other words: __Discord users will not be aware that you sent this message inside a thread - the reply will go directly onto the main channel.__ If the thread you sent this message in is old, such a random reply may be distracting to Discord users!*\n\nFor the sake of Discord parity (and for better support in numerous Matrix clients - as stated above, most Matrix clients don't handle threads particularly well, and they just render in-thread messages as fancy replies), it is recommended to send threaded messages inside a separate Matrix room that gets bridged to Discord. If you sent this message in a pre-existing Matrix thread, please look around to see if anyone has created such a room for it. If this is the first message (ie. the thread was just created) or nobody has made a thread-room for this thread yet, it is recommended you create one with `/thread` and continue the conversation there. You can run that command directly in this thread to attach the created Discord thread to the same message as this Matrix one, or run it outside any threads to see other options for attachment.\n\n*You can read more about the rationale behind this design choice [here](https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/threads-as-rooms.md).*", body: "⚠️ **This message may not have been bridged to Discord in the way you thought it was gonna be!**\n\nIt seems like you sent this message inside a Matrix thread. Matrix threads don't work like Discord threads - they are effectively just „fancy replies”, not independent rooms/channels (any „thread-like appearance” is handled purely client-side - and even then, most Matrix clients don't handle it particularly well, with Element being the only one known to actually render threads as threads), and as such, they are bridged as replies to Discord. *In other words: __Discord users will not be aware that you sent this message inside a thread - the reply will go directly onto the main channel.__ If the thread you sent this message in is old, such a random reply **may be distracting** to Discord users!*\n\nFor the sake of Discord parity (and for better support in numerous Matrix clients - as stated above, most Matrix clients don't handle threads particularly well, and they just render in-thread messages as fancy replies), it is recommended to send threaded messages inside a separate Matrix room that gets bridged to Discord. "+ (bridgedTo ? "Luckily for you, this thread already has one! You can access it on https://matrix.to/#/"+bridgedTo+"?"+(await utils.getViaServersQuery(bridgedTo, api)).toString() : "Please run `/thread [Optional: Thread Name]` to create such a room for this thread, or get a link to it if someone else has already done so. If you run `/thread` (without any arguments) outside any threads and not as a reply, you'll get more info about this command")+".\n\n*You can read more about the rationale behind this design choice [here](https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/threads-as-rooms.md).*",
"format": "org.matrix.custom.html", format: "org.matrix.custom.html",
"formatted_body": "⚠️ <strong>This message may not have been bridged to Discord in the way you thought it was gonna be!</strong><br><br>It seems like you sent this message inside a Matrix thread. Matrix threads don't work like Discord threads - they are effectively just „fancy replies”, not independent rooms/channels (any „thread-like appearance” is handled purely client-side - and even then, most Matrix clients don't handle it particularly well, with Element being the only one known to actually render threads as threads), and as such, they are bridged as replies to Discord. <em>In other words: <u>Discord users will not be aware that you sent this message inside a thread - the reply will go directly onto the main channel.</u> If the thread you sent this message in is old, such a random reply may be distracting to Discord users!</em><br><br>For the sake of Discord parity (and for better support in numerous Matrix clients - as stated above, most Matrix clients don't handle threads particularly well, and they just render in-thread messages as fancy replies), it is recommended to send threaded messages inside a separate Matrix room that gets bridged to Discord. If you sent this message in a pre-existing Matrix thread, please look around to see if anyone has created such a room for it. If this is the first message (ie. the thread was just created) or nobody has made a thread-room for this thread yet, it is recommended you create one with <code>/thread</code> and continue the conversation there. You can run that command directly in this thread to attach the created Discord thread to the same message as this Matrix one, or run it outside any threads to see other options for attachment.<br><br><em>You can read more about the rationale behind this design choice <a href=\"https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/threads-as-rooms.md\">here</a>.</em>", formatted_body: "⚠️ <strong>This message may not have been bridged to Discord in the way you thought it was gonna be!</strong><br><br>It seems like you sent this message inside a Matrix thread. Matrix threads don't work like Discord threads - they are effectively just „fancy replies”, not independent rooms/channels (any „thread-like appearance” is handled purely client-side - and even then, most Matrix clients don't handle it particularly well, with Element being the only one known to actually render threads as threads), and as such, they are bridged as replies to Discord. <em>In other words: <u>Discord users will not be aware that you sent this message inside a thread - the reply will go directly onto the main channel.</u> If the thread you sent this message in is old, such a random reply <strong>may be distracting</strong> to Discord users!</em><br><br>For the sake of Discord parity (and for better support in numerous Matrix clients - as stated above, most Matrix clients don't handle threads particularly well, and they just render in-thread messages as fancy replies), it is recommended to send threaded messages inside a separate Matrix room that gets bridged to Discord. "+ (bridgedTo ? "Luckily for you, this thread already has one! You can access it on <a href=\"https://matrix.to/#/"+bridgedTo+"?"+(await utils.getViaServersQuery(bridgedTo, api)).toString()+"\">https://matrix.to/#/"+bridgedTo+"?"+(await utils.getViaServersQuery(bridgedTo, api)).toString()+"</a>" : "Please run <code>/thread [Optional: Thread Name]</code> to create such a room for this thread, or get a link to it if someone else has already done so. If you run <code>/thread</code> (without any arguments) outside any threads and not as a reply, you'll get more info about this command")+".<br><br><em>You can read more about the rationale behind this design choice <a href=\"https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/threads-as-rooms.md\">here</a>.</em>",
"m.mentions": { "user_ids": [event.sender]}, "m.mentions": { "user_ids": [event.sender]},
"m.relates_to": { "m.relates_to": {
"event_id": event.content["m.relates_to"].event_id, event_id: event.content["m.relates_to"].event_id,
"is_falling_back": false, is_falling_back: false,
"m.in_reply_to": { "event_id": event.event_id }, "m.in_reply_to": { event_id: event.event_id },
"rel_type": "m.thread" rel_type: "m.thread"
}, },
"msgtype": "m.text" msgtype: "m.text"
}) })
} }

View file

@ -288,47 +288,45 @@ const commands = [{
const relation = event.content["m.relates_to"] const relation = event.content["m.relates_to"]
let isFallingBack = false; let isFallingBack = false;
let attachedToEvent = relation?.["m.in_reply_to"]?.event_id // By default, attempt to attach the thread to the message to which /thread was replying. let branchedFromMxEvent = relation?.["m.in_reply_to"]?.event_id // By default, attempt to branch the thread from the message to which /thread was replying.
if (relation?.rel_type === "m.thread") attachedToEvent = relation?.event_id // If /thread was sent inside a Matrix thread, attempt to attach the Discord thread to the message around which that Matrix thread was based on. if (relation?.rel_type === "m.thread") branchedFromMxEvent = relation?.event_id // If /thread was sent inside a Matrix thread, attempt to branch the Discord thread from the message, which that Matrix thread already is branching from.
if (!attachedToEvent){ if (!branchedFromMxEvent){
attachedToEvent = event.event_id // If /thread wasn't replying to anything (ie. attachedToEvent was undefined at initial assignment), or if the event was somehow malformed (in such a way that that - one way or another - attachedToEvent ended up being undefined, even if according to the spec it shouldn't), attach the thread to the /thread command-message that created it. branchedFromMxEvent = event.event_id // If /thread wasn't replying to anything (ie. branchedFromMxEvent was undefined at initial assignment), or if the event was somehow malformed (in such a way that that - one way or another - branchedFromMxEvent ended up being undefined, even if according to the spec it shouldn't), branch the thread from the /thread command-message that created it.
isFallingBack = true; isFallingBack = true;
} }
const attachedToMessage = select("event_message", "message_id", {event_id: attachedToEvent}).pluck().get() const branchedFromDiscordMessage = select("event_message", "message_id", {event_id: branchedFromMxEvent}).pluck().get()
if (words.length < 2){ if (words.length < 2){
words[1] = (await api.getEvent(event.room_id, attachedToEvent)).content.body words[1] = (await api.getEvent(event.room_id, branchedFromMxEvent)).content.body
words[1] = words[1].length < 100 ? words[1] : words[1].slice(0, 96) + "..." words[1] = words[1].length < 100 ? words[1] : words[1].slice(0, 96) + "..."
if (isFallingBack) return api.sendEvent(event.room_id, "m.room.message", { if (isFallingBack) return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
msgtype: "m.text", msgtype: "m.text",
"body": "**`/thread` usage:**\nRun this command as `/thread [Thread Name]` to create a thread on Discord (and optionally Matrix, if one doesn't exist already). The message under which said thread will be attached, is chosen based on the following rules:\n* If ran stand-alone (not as a reply, nor in a Matrix thread), the created thread gets attached to the command-message itself. The `Thread Name` argument must be provided in this case, otherwise you get this help message.\n* If sent as a reply (outside a Matrix thread), the thread will be attached to the message to which you replied.\n* If ran inside an existing Matrix thread (regardless of whether it's a reply or not), the Discord thread will be attached to the same message as the Matrix thread already is.", body: "**`/thread` usage:**\nRun this command as `/thread [Thread Name]` to create a thread on Discord (and optionally Matrix, if one doesn't exist already). The message from which said thread will branch, is chosen based on the following rules:\n* If ran stand-alone (not as a reply, nor in a Matrix thread), the created thread will branch from the command-message itself. The `Thread Name` argument must be provided in this case, otherwise you get this help message.\n* If sent as a reply (outside a Matrix thread), the thread will branch from the message to which you replied.\n* If ran inside an existing Matrix thread (regardless of whether it's a reply or not), the created Discord thread will be branching from the same message as the Matrix thread already is.",
"format": "org.matrix.custom.html", format: "org.matrix.custom.html",
"formatted_body": "<strong><code>/thread</code> usage:</strong><br>Run this command as <code>/thread [Thread Name]</code> to create a thread on Discord (and optionally Matrix, if one doesn't exist already). The message under which said thread will be attached, is chosen based on the following rules:<br><ul><li>If ran stand-alone (not as a reply, nor in a Matrix thread), the created thread gets attached to the command-message itself. The <code>Thread Name</code> argument must be provided in this case, otherwise you get this help message.</li><li>If sent as a reply (outside a Matrix thread), the thread will be attached to the message to which you replied.</li><li>If ran inside an existing Matrix thread (regardless of whether it's a reply or not), the Discord thread will be attached to the same message as the Matrix thread already is.</li></ul>" formatted_body: "<strong><code>/thread</code> usage:</strong><br>Run this command as <code>/thread [Thread Name]</code> to create a thread on Discord (and optionally Matrix, if one doesn't exist already). The message from which said thread will branch, is chosen based on the following rules:<br><ul><li>If ran stand-alone (not as a reply, nor in a Matrix thread), the created thread will branch from the command-message itself. The <code>Thread Name</code> argument must be provided in this case, otherwise you get this help message.</li><li>If sent as a reply (outside a Matrix thread), the thread will branch from the message to which you replied.</li><li>If ran inside an existing Matrix thread (regardless of whether it's a reply or not), the created Discord thread will be branching from the same message as the Matrix thread already is.</li></ul>"
}) })
} }
try { try {
if (attachedToMessage) await discord.snow.channel.createThreadWithMessage(channelID, attachedToMessage, {name: words.slice(1).join(" ")}) if (branchedFromDiscordMessage) await discord.snow.channel.createThreadWithMessage(channelID, branchedFromDiscordMessage, {name: words.slice(1).join(" ")})
else throw {code: "NO_ATTACH_TARGET", was_supposed_to_be: attachedToEvent}; else throw {code: "NO_BRANCH_SOURCE", was_supposed_to_be: branchedFromMxEvent};
} }
catch (e_raw){ catch (e){
const e = unmarshallDiscordError(e_raw) switch (unmarshallDiscordError(e).code) {
switch (e.code) { case "NO_BRANCH_SOURCE": return api.sendEvent(event.room_id, "m.room.message", {
case "NO_ATTACH_TARGET": return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
msgtype: "m.text", msgtype: "m.text",
"body": "⚠️ Couldn't find a Discord representation of the message under which you're trying to attach this thread (event ID `"+e_raw.was_supposed_to_be+"` on Matrix), so it wasn't created. Either you ran this command on an unbridged message (one sent by this bot or one that failed to bridge due to a previous error), or this is an error on our side and should be reported.", body: "⚠️ Couldn't find a Discord representation of the message from which you're trying to branch this thread (event ID `"+e.was_supposed_to_be+"` on Matrix), so it wasn't created. Either you ran this command on an unbridged message (one sent by this bot or one that failed to bridge due to a previous error), or this is an error on our side and should be reported.",
"format": "org.matrix.custom.html", format: "org.matrix.custom.html",
"formatted_body": "⚠️ Couldn't find a Discord representation of the message under which you're trying to attach this thread (event ID <code>"+e_raw.was_supposed_to_be+"</code> on Matrix), so it wasn't created. Either you ran this command on an unbridged message (one sent by this bot or one that failed to bridge due to a previous error), or this is an error on our side and should be reported." formatted_body: "⚠️ Couldn't find a Discord representation of the message from which you're trying to branch this thread (event ID <code>"+e.was_supposed_to_be+"</code> on Matrix), so it wasn't created. Either you ran this command on an unbridged message (one sent by this bot or one that failed to bridge due to a previous error), or this is an error on our side and should be reported."
}) })
case (160004): // see: https://docs.discord.com/developers/topics/opcodes-and-status-codes case (160004): // see: https://docs.discord.com/developers/topics/opcodes-and-status-codes
const thread = mxUtils.getThreadRoomFromThreadEvent(event.event_id)
return api.sendEvent(event.room_id, "m.room.message", { return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
msgtype: "m.text", msgtype: "m.text",
"body": "There already exist a thread for the message you ran this command on (please run `/thread` (with no arguments and outside any threads) for details on attachment rules, if you're unsure what „ran this command on” refers to); cannot create a new one. Scroll up and see where the link could be.", body: "There already exist a Discord thread for the message you ran this command on" + (thread ? " - you may join its bridged room here: https://matrix.to/#/"+thread+"?"+(await mxUtils.getViaServersQuery(thread, api)).toString() : ", so a new one cannot be crated. However, it seems like that thread isn't bridged to any Matrix rooms. Please ask the space/server admins to rectify this issue (or have someone send a message in that thread on Discord side to bridge it automatically, if that's enabled for this space/server).")
"format": "org.matrix.custom.html",
"formatted_body": "There already exist a thread for the message you ran this command on (please run <code>/thread</code> (with no arguments and outside any threads) for details on attachment rules, if you're unsure what „ran this command on” refers to); cannot create a new one. Scroll up and see where the link could be.",
}) })
case (50024): return api.sendEvent(event.room_id, "m.room.message", { case (50024): return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
@ -346,7 +344,7 @@ const commands = [{
msgtype: "m.text", msgtype: "m.text",
body: "Unknown error occurred during thread creation. See error message below (or on the main channel, if the command was ran inside a thread) for details." body: "Unknown error occurred during thread creation. See error message below (or on the main channel, if the command was ran inside a thread) for details."
}) })
throw e_raw; throw e
} }
} }
} }

View file

@ -4,7 +4,7 @@ const assert = require("assert").strict
const Ty = require("../types") const Ty = require("../types")
const {tag} = require("@cloudrac3r/html-template-tag") const {tag} = require("@cloudrac3r/html-template-tag")
const passthrough = require("../passthrough") const passthrough = require("../passthrough")
const {db} = passthrough const {db, select} = passthrough
const {reg} = require("./read-registration") const {reg} = require("./read-registration")
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex)) const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
@ -398,6 +398,15 @@ async function setUserPowerCascade(spaceID, mxid, power, api) {
} }
} }
/**
* @param {string} eventID
*/
function getThreadRoomFromThreadEvent(eventID){
const threadID = select("event_message", "message_id", {event_id: eventID}).pluck().get() //Discord thread ID === its message ID
if (!threadID) return threadID;
return select("channel_room", "room_id", {channel_id: threadID}).pluck().get()
}
module.exports.bot = bot module.exports.bot = bot
module.exports.BLOCK_ELEMENTS = BLOCK_ELEMENTS module.exports.BLOCK_ELEMENTS = BLOCK_ELEMENTS
module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord
@ -413,3 +422,4 @@ module.exports.removeCreatorsFromPowerLevels = removeCreatorsFromPowerLevels
module.exports.getEffectivePower = getEffectivePower module.exports.getEffectivePower = getEffectivePower
module.exports.setUserPower = setUserPower module.exports.setUserPower = setUserPower
module.exports.setUserPowerCascade = setUserPowerCascade module.exports.setUserPowerCascade = setUserPowerCascade
module.exports.getThreadRoomFromThreadEvent = getThreadRoomFromThreadEvent

View file

@ -2,7 +2,7 @@
const {select} = require("../passthrough") const {select} = require("../passthrough")
const {test} = require("supertape") const {test} = require("supertape")
const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion, removeCreatorsFromPowerLevels, setUserPower} = require("./utils") const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion, removeCreatorsFromPowerLevels, setUserPower, getThreadRoomFromThreadEvent} = require("./utils")
const util = require("util") const util = require("util")
/** @param {string[]} mxids */ /** @param {string[]} mxids */
@ -417,4 +417,23 @@ test("set user power: privileged users must demote themselves", async t => {
t.equal(called, 3) t.equal(called, 3)
}) })
test("getThreadRoomFromThreadEvent: real message, but without a thread", t => {
const room = getThreadRoomFromThreadEvent("$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4")
const msg = "Expected null/undefined, got: "+room
if(room) t.fail(msg);
else t.pass(msg)
})
test("getThreadRoomFromThreadEvent: real message with a thread", t => {
const room = getThreadRoomFromThreadEvent("$fdD9o7NxMA4VPexlAiIx2CB9JbsiGhJeyJgnZG7U5xg")
t.equal(room, "!FuDZhlOAtqswlyxzeR:cadence.moe")
})
test("getThreadRoomFromThreadEvent: fake message", t => {
const room = getThreadRoomFromThreadEvent("$ThisEvent-IdDoesNotExistInTheDatabase4Sure")
const msg = "Expected null/undefined, got: "+room
if(room) t.fail(msg);
else t.pass(msg)
})
module.exports.mockGetEffectivePower = mockGetEffectivePower module.exports.mockGetEffectivePower = mockGetEffectivePower

View file

@ -82,12 +82,14 @@ WITH a (message_id, channel_id) AS (VALUES
('1381212840957972480', '112760669178241024'), ('1381212840957972480', '112760669178241024'),
('1401760355339862066', '112760669178241024'), ('1401760355339862066', '112760669178241024'),
('1439351590262800565', '1438284564815548418'), ('1439351590262800565', '1438284564815548418'),
('1404133238414376971', '112760669178241024')) ('1404133238414376971', '112760669178241024'),
('1162005314908999790', '1100319550446252084'))
SELECT message_id, max(historical_room_index) as historical_room_index FROM a INNER JOIN historical_channel_room ON historical_channel_room.reference_channel_id = a.channel_id GROUP BY message_id; SELECT message_id, max(historical_room_index) as historical_room_index FROM a INNER JOIN historical_channel_room ON historical_channel_room.reference_channel_id = a.channel_id GROUP BY message_id;
INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, reaction_part, source) VALUES INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, reaction_part, source) VALUES
('$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg', 'm.room.message', 'm.text', '1126786462646550579', 0, 0, 1), ('$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg', 'm.room.message', 'm.text', '1126786462646550579', 0, 0, 1),
('$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4', 'm.room.message', 'm.text', '1128118177155526666', 0, 0, 0), ('$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4', 'm.room.message', 'm.text', '1128118177155526666', 0, 0, 0),
('$fdD9o7NxMA4VPexlAiIx2CB9JbsiGhJeyJgnZG7U5xg', 'm.room.message', 'm.text', '1162005314908999790', 0, 0, 1),
('$zXSlyI78DQqQwwfPUSzZ1b-nXzbUrCDljJgnGDdoI10', 'm.room.message', 'm.text', '1141619794500649020', 0, 0, 1), ('$zXSlyI78DQqQwwfPUSzZ1b-nXzbUrCDljJgnGDdoI10', 'm.room.message', 'm.text', '1141619794500649020', 0, 0, 1),
('$fdD9OZ55xg3EAsfvLZza5tMhtjUO91Wg3Otuo96TplY', 'm.room.message', 'm.text', '1141206225632112650', 0, 0, 1), ('$fdD9OZ55xg3EAsfvLZza5tMhtjUO91Wg3Otuo96TplY', 'm.room.message', 'm.text', '1141206225632112650', 0, 0, 1),
('$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA', 'm.room.message', 'm.text', '1141501302736695316', 0, 1, 1), ('$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA', 'm.room.message', 'm.text', '1141501302736695316', 0, 1, 1),