Compare commits

..

No commits in common. "c8b0f23db32f7a4b916a1bdad876ac706076cdb8" and "3d3671e05a13d4a3a21006f35afe0ca50db1fcca" have entirely different histories.

9 changed files with 84 additions and 156 deletions

37
package-lock.json generated
View file

@ -10,7 +10,7 @@
"license": "AGPL-3.0-or-later",
"dependencies": {
"@chriscdn/promise-semaphore": "^3.0.1",
"@cloudrac3r/discord-markdown": "^2.6.10",
"@cloudrac3r/discord-markdown": "^2.6.7",
"@cloudrac3r/giframe": "^0.4.3",
"@cloudrac3r/html-template-tag": "^5.0.1",
"@cloudrac3r/in-your-element": "^1.1.1",
@ -242,9 +242,9 @@
}
},
"node_modules/@cloudrac3r/discord-markdown": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.6.10.tgz",
"integrity": "sha512-E+F9UYDUHP2kHDCciX63SBzgsUnHpu2Pp/h98x9Zo+vKuzXjCQ5PcFNdUlH6M18bvHDZPoIsKVmjnON8UYaAPQ==",
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.6.8.tgz",
"integrity": "sha512-ZrSimHqmLqXR+W3U1n6ge6poAjmQaMzXyWrTkT36znrgKhfuQAYxLBtKTf7m+cmr3VlaDVM2P+iPdSeTeaM0qg==",
"license": "MIT",
"dependencies": {
"simple-markdown": "^0.7.3"
@ -1227,15 +1227,26 @@
"undici-types": "~6.21.0"
}
},
"node_modules/@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
},
"node_modules/@types/react": {
"version": "19.2.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz",
"integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==",
"license": "MIT",
"version": "18.2.55",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz",
"integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==",
"dependencies": {
"csstype": "^3.2.2"
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
},
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@ -1657,10 +1668,9 @@
}
},
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"license": "MIT"
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/data-uri-to-buffer": {
"version": "2.0.2",
@ -2815,7 +2825,6 @@
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/simple-markdown/-/simple-markdown-0.7.3.tgz",
"integrity": "sha512-uGXIc13NGpqfPeFJIt/7SHHxd6HekEJYtsdoCM06mEBPL9fQH/pSD7LRM6PZ7CKchpSvxKL4tvwMamqAaNDAyg==",
"license": "MIT",
"dependencies": {
"@types/react": ">=16.0.0"
}

View file

@ -19,7 +19,7 @@
},
"dependencies": {
"@chriscdn/promise-semaphore": "^3.0.1",
"@cloudrac3r/discord-markdown": "^2.6.10",
"@cloudrac3r/discord-markdown": "^2.6.7",
"@cloudrac3r/giframe": "^0.4.3",
"@cloudrac3r/html-template-tag": "^5.0.1",
"@cloudrac3r/in-your-element": "^1.1.1",
@ -64,7 +64,6 @@
"scripts": {
"start": "node --enable-source-maps start.js",
"setup": "node --enable-source-maps scripts/setup.js",
"build": "mkdir -p dist/out-of-your-element && cp -R src dist/out-of-your-element && cp -R docs dist/out-of-your-element && npx tsdown",
"addbot": "node addbot.js",
"test": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap --no-worker test/test.js | tap-dot",
"test-slow": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap --no-worker test/test.js -- --slow | tap-dot",

View file

@ -20,39 +20,31 @@ const emitter = new EventEmitter()
* (or before the it has finished being bridged to an event).
* In this case, wait until the original message has finished bridging, then retrigger the passed function.
* @template {(...args: any[]) => Promise<any>} T
* @param {string} inputID
* @param {string} messageID
* @param {T} fn
* @param {Parameters<T>} rest
* @returns {boolean} false if the event was found and the function will be ignored, true if the event was not found and the function will be retriggered
*/
function eventNotFoundThenRetrigger(inputID, fn, ...rest) {
if (!paused.has(inputID)) {
if (inputID.match(/^[0-9]+$/)) {
const eventID = select("event_message", "event_id", {message_id: inputID}).pluck().get()
if (eventID) {
debugRetrigger(`[retrigger] OK mid <-> eid = ${inputID} <-> ${eventID}`)
return false // event was found so don't retrigger
}
} else if (inputID.match(/^\$/)) {
const messageID = select("event_message", "message_id", {event_id: inputID}).pluck().get()
if (messageID) {
debugRetrigger(`[retrigger] OK eid <-> mid = ${inputID} <-> ${messageID}`)
return false // message was found so don't retrigger
}
function eventNotFoundThenRetrigger(messageID, fn, ...rest) {
if (!paused.has(messageID)) {
const eventID = select("event_message", "event_id", {message_id: messageID}).pluck().get()
if (eventID) {
debugRetrigger(`[retrigger] OK mid <-> eid = ${messageID} <-> ${eventID}`)
return false // event was found so don't retrigger
}
}
debugRetrigger(`[retrigger] WAIT id = ${inputID}`)
emitter.once(inputID, () => {
debugRetrigger(`[retrigger] TRIGGER id = ${inputID}`)
debugRetrigger(`[retrigger] WAIT mid = ${messageID}`)
emitter.once(messageID, () => {
debugRetrigger(`[retrigger] TRIGGER mid = ${messageID}`)
fn(...rest)
})
// if the event never arrives, don't trigger the callback, just clean up
setTimeout(() => {
if (emitter.listeners(inputID).length) {
debugRetrigger(`[retrigger] EXPIRE id = ${inputID}`)
if (emitter.listeners(messageID).length) {
debugRetrigger(`[retrigger] EXPIRE mid = ${messageID}`)
}
emitter.removeAllListeners(inputID)
emitter.removeAllListeners(messageID)
}, 60 * 1000) // 1 minute
return true // event was not found, then retrigger
}
@ -66,11 +58,11 @@ function eventNotFoundThenRetrigger(inputID, fn, ...rest) {
*/
async function pauseChanges(messageID, promise) {
try {
debugRetrigger(`[retrigger] PAUSE id = ${messageID}`)
debugRetrigger(`[retrigger] PAUSE mid = ${messageID}`)
paused.add(messageID)
return await promise
} finally {
debugRetrigger(`[retrigger] RESUME id = ${messageID}`)
debugRetrigger(`[retrigger] RESUME mid = ${messageID}`)
paused.delete(messageID)
messageFinishedBridging(messageID)
}
@ -82,7 +74,7 @@ async function pauseChanges(messageID, promise) {
*/
function messageFinishedBridging(messageID) {
if (emitter.listeners(messageID).length) {
debugRetrigger(`[retrigger] EMIT id = ${messageID}`)
debugRetrigger(`[retrigger] EMIT mid = ${messageID}`)
}
emitter.emit(messageID)
}

View file

@ -312,21 +312,6 @@ test("message2event embeds: youtube video", async t => {
}])
})
test("message2event embeds: embed not bridged if its link was spoilered", async t => {
const events = await messageToEvent({
...data.message_with_embeds.youtube_video,
content: "||https://youtu.be/kDMHHw8JqLE?si=NaqNjVTtXugHeG_E\n\n\nJutomi I'm gonna make these sounds in your walls tonight||"
}, data.guild.general)
t.deepEqual(events, [{
$type: "m.room.message",
msgtype: "m.text",
body: "[spoiler]",
format: "org.matrix.custom.html",
formatted_body: `<span data-mx-spoiler=""><a href="https://youtu.be/kDMHHw8JqLE?si=NaqNjVTtXugHeG_E">https://youtu.be/kDMHHw8JqLE?si=NaqNjVTtXugHeG_E</a><br><br><br>Jutomi I'm gonna make these sounds in your walls tonight</span>`,
"m.mentions": {}
}])
})
test("message2event embeds: tenor gif should show a video link without a provider", async t => {
const events = await messageToEvent(data.message_with_embeds.tenor_gif, data.guild.general, {}, {})
t.deepEqual(events, [{

View file

@ -26,9 +26,8 @@ const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
* @param {DiscordTypes.APIMessage} message
* @param {DiscordTypes.APIGuild} guild
* @param {boolean} useHTML
* @param {string[]} spoilers
*/
function getDiscordParseCallbacks(message, guild, useHTML, spoilers = []) {
function getDiscordParseCallbacks(message, guild, useHTML) {
return {
/** @param {{id: string, type: "discordUser"}} node */
user: node => {
@ -91,10 +90,6 @@ function getDiscordParseCallbacks(message, guild, useHTML, spoilers = []) {
here: () => {
if (message.mention_everyone) return "@room"
return "@here"
},
spoiler: node => {
spoilers.push(node.raw)
return useHTML
}
}
}
@ -286,8 +281,8 @@ async function messageToEvent(message, guild, options = {}, di) {
// 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.)
if (message.type === DiscordTypes.MessageType.Reply && message.message_reference?.message_id) {
const row = await getHistoricalEventRow(message.message_reference?.message_id)
if (row && "event_id" in row) {
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)
if (row) {
repliedToEventRow = Object.assign(row, {channel_id: row.reference_channel_id})
} else if (message.referenced_message) {
repliedToUnknownEvent = true
@ -300,8 +295,8 @@ async function messageToEvent(message, guild, options = {}, di) {
assert(message.embeds[0].description)
const match = message.embeds[0].description.match(/\/channels\/[0-9]*\/[0-9]*\/([0-9]{2,})/)
if (match) {
const row = await getHistoricalEventRow(match[1])
if (row && "event_id" in row) {
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])
if (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.
the following properties are necessary:
@ -346,34 +341,6 @@ async function messageToEvent(message, guild, options = {}, di) {
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.
* If OOYE has handled this message in the past, this is an instant database lookup.
@ -386,11 +353,30 @@ async function messageToEvent(message, guild, options = {}, di) {
assert(typeof match.index === "number")
const [_, channelID, messageID] = match
const result = await (async () => {
const row = await getHistoricalEventRow(messageID, channelID)
if (!row) return `${match[0]} [event is from another server]`
const via = await getViaServersMemo(row.room_id)
if (!("event_id" in row)) return `[unknown event in https://matrix.to/#/${row.room_id}?${via}]`
return `https://matrix.to/#/${row.room_id}/${row.event_id}?${via}`
const row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index")
.select("event_id", "room_id").where({message_id: messageID}).get()
// const roomID = select("channel_room", "room_id", {channel_id: channelID}).pluck().get()
if (row) {
const via = await getViaServersMemo(row.room_id)
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)
@ -406,7 +392,6 @@ async function messageToEvent(message, guild, options = {}, di) {
return content.replace(/https:\/\/(cdn|media)\.discordapp\.(?:com|net)\/attachments\/([0-9]+)\/([0-9]+)\/([-A-Za-z0-9_.,]+)/g, url => dUtils.getPublicUrlForCdn(url))
}
const spoilers = []
/**
* Translate links and emojis and mentions and stuff. Give back the text and HTML so they can be combined into bigger events.
* @param {string} content Partial or complete Discord message content
@ -446,7 +431,7 @@ async function messageToEvent(message, guild, options = {}, di) {
}
let html = await markdown.toHtmlWithPostParser(content, transformParsedVia, {
discordCallback: getDiscordParseCallbacks(message, guild, true, spoilers),
discordCallback: getDiscordParseCallbacks(message, guild, true),
...customOptions
}, customParser, customHtmlOutput)
@ -570,16 +555,17 @@ async function messageToEvent(message, guild, options = {}, di) {
// Forwarded content appears first
if (message.message_reference?.type === DiscordTypes.MessageReferenceType.Forward && message.message_snapshots?.length) {
// Forwarded notice
const row = await getHistoricalEventRow(message.message_reference.message_id, message.message_reference.channel_id)
const event = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index")
.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 forwardedNotice = new mxUtils.MatrixStringBuilder()
if (room) {
const roomName = room && (room.nick || room.name)
if ("event_id" in row) {
const via = await getViaServersMemo(row.room_id)
if (event) {
const via = await getViaServersMemo(event.room_id)
forwardedNotice.addLine(
`[🔀 Forwarded from #${roomName}]`,
tag`🔀 <em>Forwarded from ${roomName} <a href="https://matrix.to/#/${room.room_id}/${row.event_id}?${via}">[jump to event]</a></em>`
tag`🔀 <em>Forwarded from ${roomName} <a href="https://matrix.to/#/${room.room_id}/${event.event_id}?${via}">[jump to event]</a></em>`
)
} else {
const via = await getViaServersMemo(room.room_id)
@ -706,13 +692,6 @@ async function messageToEvent(message, guild, options = {}, di) {
continue // If discord creates an embed preview for a discord channel link, don't copy that embed
}
if (embed.url && spoilers.some(sp => sp.match(/\bhttps?:\/\/[a-z]/))) {
// If the original message had spoilered URLs, don't generate any embeds for links.
// This logic is the same as the Discord desktop client. It doesn't match specific embeds to specific spoilered text, it's all or nothing.
// It's not easy to do much better because posting a link like youtu.be generates an embed.url with youtube.com/watch, so you can't match up the text without making at least that a special case.
continue
}
// Start building up a replica ("rep") of the embed in Discord-markdown format, which we will convert into both plaintext and formatted body at once
const rep = new mxUtils.MatrixStringBuilder()

View file

@ -287,10 +287,10 @@ test("message2event: message timestamp failed to fetch", async t => {
"m.mentions": {},
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:_ "
+ "[unknown event in https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org]",
+ "[unknown event, timestamp resolution failed, in room: https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org]",
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> "
+ '[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>]'
+ '[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>]'
}])
t.equal(called, 2, "getEventForTimestamp and getJoinedMembers should be called once each")
})
@ -862,20 +862,6 @@ test("message2event: advanced written @mentions for matrix users", async t => {
t.equal(called, 1, "should only look up the member list once")
})
test("message2event: spoilers are removed from plaintext body", async t => {
const events = await messageToEvent({
content: "||**beatrice**||"
})
t.deepEqual(events, [{
$type: "m.room.message",
"m.mentions": {},
msgtype: "m.text",
body: "[spoiler]",
format: "org.matrix.custom.html",
formatted_body: `<span data-mx-spoiler=""><strong>beatrice</strong></span>`
}])
})
test("message2event: very large attachment is linked instead of being uploaded", async t => {
const events = await messageToEvent({
content: "hey",

View file

@ -4,27 +4,20 @@ const assert = require("assert").strict
const Ty = require("../../types")
const passthrough = require("../../passthrough")
const {discord, as, sync, db, select, from} = passthrough
const {discord, sync, db, select} = passthrough
/** @type {import("../../matrix/utils")} */
const utils = sync.require("../../matrix/utils")
/** @type {import("../converters/emoji")} */
const emoji = sync.require("../converters/emoji")
/** @type {import("../../d2m/actions/retrigger")} */
const retrigger = sync.require("../../d2m/actions/retrigger")
/**
* @param {Ty.Event.Outer<Ty.Event.M_Reaction>} event
*/
async function addReaction(event) {
// Wait until the corresponding channel and message have already been bridged
if (retrigger.eventNotFoundThenRetrigger(event.content["m.relates_to"].event_id, as.emit.bind(as, "type:m.reaction", event))) return
// These will exist because it passed retrigger
const row = from("event_message").join("message_room", "message_id").join("historical_channel_room", "historical_room_index")
.select("message_id", "reference_channel_id").where({event_id: event.content["m.relates_to"].event_id}).and("ORDER BY reaction_part ASC").get()
assert(row)
const messageID = row.message_id
const channelID = row.reference_channel_id
const channelID = select("historical_channel_room", "reference_channel_id", {room_id: event.room_id}).pluck().get()
if (!channelID) return // We just assume the bridge has already been created
const messageID = select("event_message", "message_id", {event_id: event.content["m.relates_to"].event_id}, "ORDER BY reaction_part").pluck().get()
if (!messageID) return // Nothing can be done if the parent message was never bridged.
const key = event.content["m.relates_to"].key
const discordPreferredEncoding = await emoji.encodeEmoji(key, event.content.shortcode)
@ -42,10 +35,6 @@ async function addReaction(event) {
// happens if a matrix user tries to add on to a super reaction
return
}
if (e.message?.includes("Unknown Message")) {
// happens under a race condition where a message is deleted after it passes the database check above
return
}
throw e
}

View file

@ -4,11 +4,9 @@ const DiscordTypes = require("discord-api-types/v10")
const Ty = require("../../types")
const passthrough = require("../../passthrough")
const {discord, as, sync, db, select, from} = passthrough
const {discord, sync, db, select, from} = passthrough
/** @type {import("../../matrix/utils")} */
const utils = sync.require("../../matrix/utils")
/** @type {import("../../d2m/actions/retrigger")} */
const retrigger = sync.require("../../d2m/actions/retrigger")
/**
* @param {Ty.Event.Outer_M_Room_Redaction} event
@ -54,18 +52,13 @@ async function removeReaction(event) {
* @param {Ty.Event.Outer_M_Room_Redaction} event
*/
async function handle(event) {
// If this is for removing a reaction, try it
await removeReaction(event)
// Or, it might be for removing a message or suppressing embeds. But to do that, the message needs to be bridged first.
if (retrigger.eventNotFoundThenRetrigger(event.redacts, as.emit.bind(as, "type:m.room.redaction", event))) return
const row = select("event_message", ["event_type", "event_subtype", "part"], {event_id: event.redacts}).get()
if (row && row.event_type === "m.room.message" && row.event_subtype === "m.notice" && row.part === 1) {
await suppressEmbeds(event)
} else {
await deleteMessage(event)
}
await removeReaction(event)
}
module.exports.handle = handle

View file

@ -28,8 +28,6 @@ const api = sync.require("../matrix/api")
const createRoom = sync.require("../d2m/actions/create-room")
/** @type {import("../matrix/room-upgrade")} */
const roomUpgrade = require("../matrix/room-upgrade")
/** @type {import("../d2m/actions/retrigger")} */
const retrigger = sync.require("../d2m/actions/retrigger")
const {reg} = require("../matrix/read-registration")
let lastReportedEvent = 0
@ -203,7 +201,6 @@ async event => {
// @ts-ignore
await matrixCommandHandler.execute(event)
}
retrigger.messageFinishedBridging(event.event_id)
await api.ackEvent(event)
}))
@ -214,7 +211,6 @@ sync.addTemporaryListener(as, "type:m.sticker", guard("m.sticker",
async event => {
if (utils.eventSenderIsFromDiscord(event.sender)) return
const messageResponses = await sendEvent.sendEvent(event)
retrigger.messageFinishedBridging(event.event_id)
await api.ackEvent(event)
}))