diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 382e9709..90023ee3 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -8,6 +8,34 @@ const { sync, db, discord } = passthrough /** @type {import("../../matrix/file")} */ const file = sync.require("../../matrix/file") +function getDiscordParseCallbacks(message, useHTML) { + return { + user: node => { + const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id) + const username = message.mentions.find(ment => ment.id === node.id)?.username || node.id + if (mxid && useHTML) { + return `@${username}` + } else { + return `@${username}:` + } + }, + channel: node => { + const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(node.id) + if (roomID && useHTML) { + return "https://matrix.to/#/" + roomID + } else { + return "#" + node.id + } + }, + role: node => + "@&" + node.id, + everyone: node => + "@room", + here: node => + "@here" + } +} + /** * @param {import("discord-api-types/v10").APIMessage} message * @param {import("discord-api-types/v10").APIGuild} guild @@ -17,34 +45,18 @@ async function messageToEvent(message, guild) { // Text content appears first if (message.content) { - const body = message.content - const html = markdown.toHTML(body, { - discordCallback: { - user: node => { - const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id) - if (mxid) { - return "https://matrix.to/#/" + mxid - } else { - return "@" + node.id - } - }, - channel: node => { - const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(node.id) - if (roomID) { - return "https://matrix.to/#/" + roomID - } else { - return "#" + node.id - } - }, - role: node => - "@&" + node.id, - everyone: node => - "@room", - here: node => - "@here" - } + const html = markdown.toHTML(message.content, { + discordCallback: getDiscordParseCallbacks(message, true) }, null, null) + + const body = markdown.toHTML(message.content, { + discordCallback: getDiscordParseCallbacks(message, false), //TODO: library bug!! + discordOnly: true, + escapeHTML: false, + }, null, null) + const isPlaintext = body === html + if (isPlaintext) { events.push({ $type: "m.room.message", diff --git a/d2m/converters/message-to-event.test.js b/d2m/converters/message-to-event.test.js index 26cf1f1d..1f3a844e 100644 --- a/d2m/converters/message-to-event.test.js +++ b/d2m/converters/message-to-event.test.js @@ -2,6 +2,26 @@ const {test} = require("supertape") const {messageToEvent} = require("./message-to-event") const data = require("../../test/data") +test("message2event: simple plaintext", async t => { + const events = await messageToEvent(data.message.simple_plaintext, data.guild.general) + t.deepEqual(events, [{ + $type: "m.room.message", + msgtype: "m.text", + body: "ayy lmao" + }]) +}) + +test("message2event: simple user mention", async t => { + const events = await messageToEvent(data.message.simple_user_mention, data.guild.general) + t.deepEqual(events, [{ + $type: "m.room.message", + msgtype: "m.text", + body: "@crunch god: Tell me about Phil, renowned martial arts master and creator of the Chin Trick", + format: "org.matrix.custom.html", + formatted_body: '@crunch god Tell me about Phil, renowned martial arts master and creator of the Chin Trick' + }]) +}) + test("message2event: attachment with no content", async t => { const events = await messageToEvent(data.message.attachment_no_content, data.guild.general) t.deepEqual(events, [{ diff --git a/stdin.js b/stdin.js index cd504f2b..7e0db895 100644 --- a/stdin.js +++ b/stdin.js @@ -6,6 +6,7 @@ const util = require("util") const passthrough = require("./passthrough") const { discord, config, sync, db } = passthrough +const data = sync.require("./test/data") const createSpace = sync.require("./d2m/actions/create-space") const createRoom = sync.require("./d2m/actions/create-room") const registerUser = sync.require("./d2m/actions/register-user") diff --git a/test/data.js b/test/data.js index 49bbeafa..f4326a6e 100644 --- a/test/data.js +++ b/test/data.js @@ -138,6 +138,84 @@ module.exports = { }, message: { // Display order is text content, attachments, then stickers + simple_plaintext: { + id: "1126733830494093453", + type: 0, + content: "ayy lmao", + channel_id: "112760669178241024", + author: { + id: "111604486476181504", + username: "kyuugryphon", + avatar: "e4ce31267ca524d19be80e684d4cafa1", + discriminator: "0", + public_flags: 0, + flags: 0, + banner: null, + accent_color: null, + global_name: "KyuuGryphon", + avatar_decoration: null, + display_name: "KyuuGryphon", + banner_color: null + }, + attachments: [], + embeds: [], + mentions: [], + mention_roles: [], + pinned: false, + mention_everyone: false, + tts: false, + timestamp: "2023-07-07T04:37:58.892000+00:00", + edited_timestamp: null, + flags: 0, + components: [] + }, + simple_user_mention: { + id: "1126739682080858234", + type: 0, + content: "<@820865262526005258> Tell me about Phil, renowned martial arts master and creator of the Chin Trick", + 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: [ + { + id: "820865262526005258", + username: "crunch god", + avatar: "f7a75ca031c1d2326e0f3ca5213eea47", + discriminator: "8889", + public_flags: 0, + flags: 0, + bot: true, + banner: null, + accent_color: null, + global_name: null, + avatar_decoration: null, + display_name: null, + banner_color: null + } + ], + mention_roles: [], + pinned: false, + mention_everyone: false, + tts: false, + timestamp: "2023-07-07T05:01:14.019000+00:00", + edited_timestamp: null, + flags: 0, + components: [] + }, attachment_no_content: { id: "1124628646670389348", type: 0,