show member details on discord from cache
This commit is contained in:
parent
0ea2b4efc9
commit
3ebfa8e3a7
4 changed files with 68 additions and 25 deletions
|
@ -47,6 +47,13 @@ CREATE TABLE IF NOT EXISTS "event_message" (
|
||||||
"source" INTEGER NOT NULL,
|
"source" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("event_id","message_id")
|
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;
|
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/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');
|
('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;
|
COMMIT;
|
||||||
|
|
|
@ -9,6 +9,8 @@ const passthrough = require("../../passthrough")
|
||||||
const { sync, db, discord } = passthrough
|
const { sync, db, discord } = passthrough
|
||||||
/** @type {import("../../matrix/file")} */
|
/** @type {import("../../matrix/file")} */
|
||||||
const file = sync.require("../../matrix/file")
|
const file = sync.require("../../matrix/file")
|
||||||
|
/** @type {import("../converters/utils")} */
|
||||||
|
const utils = sync.require("../converters/utils")
|
||||||
|
|
||||||
const BLOCK_ELEMENTS = [
|
const BLOCK_ELEMENTS = [
|
||||||
"ADDRESS", "ARTICLE", "ASIDE", "AUDIO", "BLOCKQUOTE", "BODY", "CANVAS",
|
"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 {Ty.Event.Outer<Ty.Event.M_Room_Message>} event
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
* @param {import("discord-api-types/v10").APIGuild} guild
|
||||||
|
@ -81,11 +99,13 @@ async function eventToMessage(event, guild, di) {
|
||||||
let displayName = event.sender
|
let displayName = event.sender
|
||||||
let avatarURL = undefined
|
let avatarURL = undefined
|
||||||
let replyLine = ""
|
let replyLine = ""
|
||||||
|
// Extract a basic display name from the sender
|
||||||
const match = event.sender.match(/^@(.*?):/)
|
const match = event.sender.match(/^@(.*?):/)
|
||||||
if (match) {
|
if (match) displayName = match[1]
|
||||||
displayName = match[1]
|
// Try to extract an accurate display name and avatar URL from the member event
|
||||||
// TODO: get the media repo domain and the avatar url from the matrix 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
|
// Convert content depending on what the message is
|
||||||
let content = event.content.body // ultimate fallback
|
let content = event.content.body // ultimate fallback
|
||||||
|
|
|
@ -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",
|
content: "testing plaintext",
|
||||||
avatar_url: undefined
|
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>",
|
content: "testing \\*\\*special\\*\\* \\~\\~things\\~\\~ which \\_should\\_ \\*not\\* \\`trigger\\` @any <effects>",
|
||||||
avatar_url: undefined
|
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~~",
|
content: "this **is** a **_test_** of ~~formatting~~",
|
||||||
avatar_url: undefined
|
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",
|
content: "this \\*\\*is\\*\\* an **_extreme_** \\\\\\*test\\\\\\* of",
|
||||||
avatar_url: undefined
|
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",
|
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
|
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",
|
content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\n line five",
|
||||||
avatar_url: undefined
|
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",
|
content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\nline five",
|
||||||
avatar_url: undefined
|
avatar_url: undefined
|
||||||
}]
|
}]
|
||||||
|
@ -234,7 +234,7 @@ test("event2message: lists are bridged correctly", async t => {
|
||||||
"room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe"
|
"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",
|
content: "* line one\n* line two\n* line three\n * nested one\n * nested two\n* line four",
|
||||||
avatar_url: undefined
|
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),
|
content: (("a".repeat(130) + " ").repeat(15)).slice(0, -1),
|
||||||
avatar_url: undefined
|
avatar_url: undefined
|
||||||
}, {
|
}, {
|
||||||
username: "cadence",
|
username: "cadence [they]",
|
||||||
content: (("a".repeat(130) + " ").repeat(4)).slice(0, -1),
|
content: (("a".repeat(130) + " ").repeat(4)).slice(0, -1),
|
||||||
avatar_url: undefined
|
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",
|
content: "preceding\n\n```\ncode block\n```\n\nfollowing `code` is inline",
|
||||||
avatar_url: undefined
|
avatar_url: undefined
|
||||||
}]
|
}]
|
||||||
|
@ -315,7 +315,7 @@ test("event2message: code block contents are formatted correctly and not escaped
|
||||||
"room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe"
|
"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,`",
|
content: "```\ninput = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n_input_ = input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n```\n\n`input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,`",
|
||||||
avatar_url: undefined
|
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🤨",
|
content: "> Chancellor of Germany Angela Merkel, on March 17, 2017: they did not shake hands\n🤨",
|
||||||
avatar_url: undefined
|
avatar_url: undefined
|
||||||
}]
|
}]
|
||||||
|
@ -367,8 +367,8 @@ test("event2message: m.emote markdown syntax is escaped", async t => {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
[{
|
[{
|
||||||
username: "cadence",
|
username: "cadence [they]",
|
||||||
content: "\\* cadence shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of",
|
content: "\\* cadence \\[they\\] shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of",
|
||||||
avatar_url: undefined
|
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",
|
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!!!**",
|
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",
|
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"
|
||||||
}]
|
}]
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,4 +19,15 @@ function eventSenderIsFromDiscord(sender) {
|
||||||
return false
|
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.eventSenderIsFromDiscord = eventSenderIsFromDiscord
|
||||||
|
module.exports.getPublicUrlForMxc = getPublicUrlForMxc
|
||||||
|
|
Loading…
Reference in a new issue