show member details on discord from cache

This commit is contained in:
Cadence Ember 2023-08-26 22:22:54 +12:00
parent 0ea2b4efc9
commit 3ebfa8e3a7
4 changed files with 68 additions and 25 deletions

View File

@ -47,6 +47,13 @@ CREATE TABLE IF NOT EXISTS "event_message" (
"source" INTEGER NOT NULL,
PRIMARY KEY("event_id","message_id")
);
CREATE TABLE IF NOT EXISTS "member_cache" (
"room_id" TEXT NOT NULL,
"mxid" TEXT NOT NULL,
"displayname" TEXT,
"avatar_url" TEXT,
PRIMARY KEY("room_id", "mxid")
);
COMMIT;
@ -101,4 +108,9 @@ INSERT INTO file (discord_url, mxc_url) VALUES
('https://cdn.discordapp.com/icons/112760669178241024/a_f83622e09ead74f0c5c527fe241f8f8c.png?size=1024', 'mxc://cadence.moe/zKXGZhmImMHuGQZWJEFKJbsF'),
('https://cdn.discordapp.com/avatars/113340068197859328/b48302623a12bc7c59a71328f72ccb39.png?size=1024', 'mxc://cadence.moe/UpAeIqeclhKfeiZNdIWNcXXL');
INSERT INTO member_cache (room_id, mxid, displayname, avatar_url) VALUES
('!kLRqKKUQXcibIMtOpl:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', NULL),
('!BpMdOUkWWhFxmTrENV:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', NULL),
('!fGgIymcYWOqjbSRUdV:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU');
COMMIT;

View File

@ -9,6 +9,8 @@ const passthrough = require("../../passthrough")
const { sync, db, discord } = passthrough
/** @type {import("../../matrix/file")} */
const file = sync.require("../../matrix/file")
/** @type {import("../converters/utils")} */
const utils = sync.require("../converters/utils")
const BLOCK_ELEMENTS = [
"ADDRESS", "ARTICLE", "ASIDE", "AUDIO", "BLOCKQUOTE", "BODY", "CANVAS",
@ -69,6 +71,22 @@ turndownService.addRule("fencedCodeBlock", {
}
})
/**
* @param {string} roomID
* @param {string} mxid
* @returns {Promise<{displayname?: string?, avatar_url?: string?}>}
*/
async function getMemberFromCacheOrHomeserver(roomID, mxid, api) {
const row = db.prepare("SELECT displayname, avatar_url FROM member_cache WHERE room_id = ? AND mxid = ?").get(roomID, mxid)
if (row) return row
return api.getStateEvent(roomID, "m.room.member", mxid).then(event => {
db.prepare("INSERT INTO member_cache (room_id, mxid, displayname, avatar_url) VALUES (?, ?, ?, ?)").run(roomID, mxid, event?.displayname || null, event?.avatar_url || null)
return event
}).catch(() => {
return {displayname: null, avatar_url: null}
})
}
/**
* @param {Ty.Event.Outer<Ty.Event.M_Room_Message>} event
* @param {import("discord-api-types/v10").APIGuild} guild
@ -81,11 +99,13 @@ async function eventToMessage(event, guild, di) {
let displayName = event.sender
let avatarURL = undefined
let replyLine = ""
// Extract a basic display name from the sender
const match = event.sender.match(/^@(.*?):/)
if (match) {
displayName = match[1]
// TODO: get the media repo domain and the avatar url from the matrix member event
}
if (match) displayName = match[1]
// Try to extract an accurate display name and avatar URL from the member event
const member = await getMemberFromCacheOrHomeserver(event.room_id, event.sender, di?.api)
if (member.displayname) displayName = member.displayname
if (member.avatar_url) avatarURL = utils.getPublicUrlForMxc(member.avatar_url)
// Convert content depending on what the message is
let content = event.content.body // ultimate fallback

View File

@ -51,7 +51,7 @@ test("event2message: body is used when there is no formatted_body", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "testing plaintext",
avatar_url: undefined
}]
@ -75,7 +75,7 @@ test("event2message: any markdown in body is escaped", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "testing \\*\\*special\\*\\* \\~\\~things\\~\\~ which \\_should\\_ \\*not\\* \\`trigger\\` @any <effects>",
avatar_url: undefined
}]
@ -101,7 +101,7 @@ test("event2message: basic html is converted to markdown", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "this **is** a **_test_** of ~~formatting~~",
avatar_url: undefined
}]
@ -127,7 +127,7 @@ test("event2message: markdown syntax is escaped", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "this \\*\\*is\\*\\* an **_extreme_** \\\\\\*test\\\\\\* of",
avatar_url: undefined
}]
@ -153,7 +153,7 @@ test("event2message: html lines are bridged correctly", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "paragraph one\nline _two_\nline three\n\nparagraph two\nline _two_\nline three\n\nparagraph three\n\nparagraph four\nline two\nline three\nline four\n\nparagraph five",
avatar_url: undefined
}]
@ -179,7 +179,7 @@ test("event2message: html lines are bridged correctly", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\n line five",
avatar_url: undefined
}]
@ -206,7 +206,7 @@ test("event2message: whitespace is collapsed", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\nline five",
avatar_url: undefined
}]
@ -234,7 +234,7 @@ test("event2message: lists are bridged correctly", async t => {
"room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe"
}),
[{
username: "cadence",
username: "cadence [they]",
content: "* line one\n* line two\n* line three\n * nested one\n * nested two\n* line four",
avatar_url: undefined
}]
@ -258,11 +258,11 @@ test("event2message: long messages are split", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: (("a".repeat(130) + " ").repeat(15)).slice(0, -1),
avatar_url: undefined
}, {
username: "cadence",
username: "cadence [they]",
content: (("a".repeat(130) + " ").repeat(4)).slice(0, -1),
avatar_url: undefined
}]
@ -288,7 +288,7 @@ test("event2message: code blocks work", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "preceding\n\n```\ncode block\n```\n\nfollowing `code` is inline",
avatar_url: undefined
}]
@ -315,7 +315,7 @@ test("event2message: code block contents are formatted correctly and not escaped
"room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe"
}),
[{
username: "cadence",
username: "cadence [they]",
content: "```\ninput = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n_input_ = input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n```\n\n`input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,`",
avatar_url: undefined
}]
@ -341,7 +341,7 @@ test("event2message: quotes have an appropriate amount of whitespace", async t =
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "> Chancellor of Germany Angela Merkel, on March 17, 2017: they did not shake hands\n🤨",
avatar_url: undefined
}]
@ -367,8 +367,8 @@ test("event2message: m.emote markdown syntax is escaped", async t => {
}
}),
[{
username: "cadence",
content: "\\* cadence shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of",
username: "cadence [they]",
content: "\\* cadence \\[they\\] shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of",
avatar_url: undefined
}]
)
@ -410,9 +410,9 @@ test("event2message: rich reply to a sim user", async t => {
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 <@111604486476181504>: Slow news day.\nTesting this reply, ignore",
avatar_url: undefined
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU"
}]
)
})
@ -455,9 +455,9 @@ test("event2message: rich reply to a matrix user's long message with formatting"
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 Ⓜ️**cadence**: i should have a little...\n**no you can't!!!**",
avatar_url: undefined
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU"
}]
)
})
@ -500,9 +500,9 @@ test("event2message: with layered rich replies, the preview should only be the r
}
}),
[{
username: "cadence",
username: "cadence [they]",
content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 Ⓜ️**cadence**: two\nthree",
avatar_url: undefined
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU"
}]
)
})

View File

@ -19,4 +19,15 @@ function eventSenderIsFromDiscord(sender) {
return false
}
/**
* @param {string} mxc
* @returns {string?}
*/
function getPublicUrlForMxc(mxc) {
const avatarURLParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/)
if (avatarURLParts) return `https://matrix.cadence.moe/_matrix/media/r0/download/${avatarURLParts[1]}/${avatarURLParts[2]}`
else return null
}
module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord
module.exports.getPublicUrlForMxc = getPublicUrlForMxc