From 437f04682c0490b3fe94e679195f6466f2045abe Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Tue, 11 Jul 2023 17:27:40 +1200 Subject: [PATCH] support written @mentions (scenario 3) --- d2m/converters/message-to-event.js | 21 +++++++++++- d2m/converters/message-to-event.test.js | 43 +++++++++++++++++++++++++ test/data.js | 31 ++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 0e94a70..daa0a3c 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -8,6 +8,9 @@ const passthrough = require("../../passthrough") const { sync, db, discord } = passthrough /** @type {import("../../matrix/file")} */ const file = sync.require("../../matrix/file") +const reg = require("../../matrix/read-registration") + +const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex)) function getDiscordParseCallbacks(message, useHTML) { return { @@ -69,7 +72,7 @@ async function messageToEvent(message, guild, api) { function addMention(mxid) { if (!mentions.user_ids) mentions.user_ids = [] - mentions.user_ids.push(mxid) + if (!mentions.user_ids.includes(mxid)) mentions.user_ids.push(mxid) } // Mentions scenarios 1 and 2, part A. i.e. translate relevant message.mentions to m.mentions @@ -106,12 +109,28 @@ async function messageToEvent(message, guild, api) { discordCallback: getDiscordParseCallbacks(message, true) }, null, null) + // TODO: add a string return type to my discord-markdown library let body = markdown.toHTML(content, { discordCallback: getDiscordParseCallbacks(message, false), discordOnly: true, escapeHTML: false, }, null, null) + // Mentions scenario 3: scan the message content for written @mentions of matrix users + const matches = [...content.matchAll(/@([a-z0-9._]+)\b/gi)] + if (matches.length && matches.some(m => m[1].match(/[a-z]/i))) { + const writtenMentionsText = matches.map(m => m[1].toLowerCase()) + const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(message.channel_id) + const {joined} = await api.getJoinedMembers(roomID) + for (const [mxid, member] of Object.entries(joined)) { + if (!userRegex.some(rx => mxid.match(rx))) { + const localpart = mxid.match(/@([^:]*)/) + assert(localpart) + if (writtenMentionsText.includes(localpart[1].toLowerCase()) || writtenMentionsText.includes(member.display_name.toLowerCase())) addMention(mxid) + } + } + } + // Fallback body/formatted_body for replies if (repliedToEventId) { let repliedToDisplayName diff --git a/d2m/converters/message-to-event.test.js b/d2m/converters/message-to-event.test.js index 5fa16f8..58093ca 100644 --- a/d2m/converters/message-to-event.test.js +++ b/d2m/converters/message-to-event.test.js @@ -215,4 +215,47 @@ test("message2event: simple reply to matrix user", async t => { }]) }) +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, { + async getJoinedMembers(roomID) { + t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe") + return new Promise(resolve => { + setTimeout(() => { + resolve({ + joined: { + "@cadence:cadence.moe": { + display_name: "cadence [they]", + avatar_url: "whatever" + }, + "@huckleton:cadence.moe": { + display_name: "huck", + avatar_url: "whatever" + }, + "@_ooye_botrac4r:cadence.moe": { + display_name: "botrac4r", + avatar_url: "whatever" + }, + "@_ooye_bot:cadence.moe": { + display_name: "Out Of Your Element", + avatar_url: "whatever" + } + } + }) + }) + }) + } + }) + t.deepEqual(events, [{ + $type: "m.room.message", + "m.mentions": { + user_ids: [ + "@cadence:cadence.moe", + "@huckleton:cadence.moe" + ] + }, + msgtype: "m.text", + body: "@Cadence, tell me about @Phil, the creator of the Chin Trick, who has become ever more powerful under the mentorship of @botrac4r and @huck" + }]) +}) + // TODO: read "edits of replies" in the spec diff --git a/test/data.js b/test/data.js index 7c8fadc..a5ca95e 100644 --- a/test/data.js +++ b/test/data.js @@ -304,6 +304,37 @@ module.exports = { flags: 0, components: [] }, + simple_written_at_mention_for_matrix: { + id: "1126739682080858234", + type: 0, + content: "@Cadence, tell me about @Phil, the creator of the Chin Trick, who has become ever more powerful under the mentorship of @botrac4r and @huck", + channel_id: "112760669178241024", + author: { + id: "114147806469554185", + username: "extremity", + avatar: "6628aaf6b27219c36e2d3b5cfd6d0ee6", + discriminator: "0", + public_flags: 768, + flags: 768, + banner: null, + accent_color: null, + global_name: "Extremity", + avatar_decoration: null, + display_name: "Extremity", + banner_color: null + }, + attachments: [], + embeds: [], + mentions: [], + mention_roles: [], + pinned: false, + mention_everyone: false, + tts: false, + timestamp: "2023-07-07T05:01:14.019000+00:00", + edited_timestamp: null, + flags: 0, + components: [] + }, simple_reply: { id: "1126604870762369124", type: 19,