diff --git a/src/discord/interactions/matrix-info.js b/src/discord/interactions/matrix-info.js index 0b9a525..c85cec2 100644 --- a/src/discord/interactions/matrix-info.js +++ b/src/discord/interactions/matrix-info.js @@ -62,29 +62,7 @@ async function _interact({guild_id, data}, {api}) { .sort((a, b) => webGuild._getPosition(a, discord.channels) - webGuild._getPosition(b, discord.channels)) .filter(channel => from("channel_room").join("member_cache", "room_id").select("mxid").where({channel_id: channel.id, mxid: event.sender}).get()) const matrixMember = select("member_cache", ["displayname", "avatar_url"], {room_id: message.room_id, mxid: event.sender}).get() - let name = matrixMember?.displayname || event.sender - let avatar = utils.getPublicUrlForMxc(matrixMember?.avatar_url) - - // Check for per-message profile - const perMessageProfile = event.content?.["com.beeper.per_message_profile"] - let profileNote = "" - if (perMessageProfile) { - if (perMessageProfile.displayname) { - name = perMessageProfile.displayname - } - if ("avatar_url" in perMessageProfile) { - if (perMessageProfile.avatar_url) { - // use provided avatar_url - avatar = utils.getPublicUrlForMxc(perMessageProfile.avatar_url) - } else if (perMessageProfile.avatar_url === "") { - // empty string avatar_url clears the avatar - avatar = undefined - } - // else, omitted/null falls back to member avatar - } - profileNote = "Sent with a per-message profile.\n" - } - + const name = matrixMember?.displayname || event.sender return { type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, data: { @@ -92,9 +70,9 @@ async function _interact({guild_id, data}, {api}) { author: { name, url: `https://matrix.to/#/${event.sender}`, - icon_url: avatar + icon_url: utils.getPublicUrlForMxc(matrixMember?.avatar_url) }, - description: `This Matrix message was delivered to Discord by **Out Of Your Element**.\n[View on Matrix →]()\n\n${profileNote}**User ID**: [${event.sender}]()`, + description: `This Matrix message was delivered to Discord by **Out Of Your Element**.\n[View on Matrix →]()\n\n**User ID**: [${event.sender}]()`, color: 0x0dbd8b, fields: [{ name: "In Channels", diff --git a/src/discord/interactions/matrix-info.test.js b/src/discord/interactions/matrix-info.test.js index 8347c12..f455700 100644 --- a/src/discord/interactions/matrix-info.test.js +++ b/src/discord/interactions/matrix-info.test.js @@ -85,118 +85,3 @@ test("matrix info: shows info for matrix source message", async t => { ) t.equal(called, 1) }) - -test("matrix info: shows username for per-message profile", async t => { - let called = 0 - const msg = await _interact({ - data: { - target_id: "1128118177155526666", - resolved: { - messages: { - "1141501302736695316": data.message.simple_reply_to_matrix_user - } - } - }, - guild_id: "112760669178241024" - }, { - api: { - async getEvent(roomID, eventID) { - called++ - t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe") - t.equal(eventID, "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4") - return { - event_id: eventID, - room_id: roomID, - type: "m.room.message", - content: { - msgtype: "m.text", - body: "master chief: i like the halo", - format: "org.matrix.custom.html", - formatted_body: "master chief: i like the halo", - "com.beeper.per_message_profile": { - has_fallback: true, - displayname: "master chief", - avatar_url: "" - } - }, - sender: "@cadence:cadence.moe" - } - }, - async getJoinedMembers(roomID) { - return { - joined: {} - } - }, - async getStateEventOuter(roomID, type, key) { - return { - content: { - room_version: "11" - } - } - }, - async getStateEvent(roomID, type, key) { - return {} - } - } - }) - t.equal(msg.data.embeds[0].author.name, "master chief") - t.match(msg.data.embeds[0].description, "Sent with a per-message profile") - t.equal(called, 1) -}) - -test("matrix info: shows avatar for per-message profile", async t => { - let called = 0 - const msg = await _interact({ - data: { - target_id: "1128118177155526666", - resolved: { - messages: { - "1141501302736695316": data.message.simple_reply_to_matrix_user - } - } - }, - guild_id: "112760669178241024" - }, { - api: { - async getEvent(roomID, eventID) { - called++ - t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe") - t.equal(eventID, "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4") - return { - event_id: eventID, - room_id: roomID, - type: "m.room.message", - content: { - msgtype: "m.text", - body: "?", - format: "org.matrix.custom.html", - formatted_body: "?", - "com.beeper.per_message_profile": { - avatar_url: "mxc://cadence.moe/HXfFuougamkURPPMflTJRxGc" - } - }, - sender: "@mystery:cadence.moe" - } - }, - async getJoinedMembers(roomID) { - return { - joined: {} - } - }, - async getStateEventOuter(roomID, type, key) { - return { - content: { - room_version: "11" - } - } - }, - async getStateEvent(roomID, type, key) { - return {} - } - } - }) - t.equal(msg.data.embeds[0].author.name, "@mystery:cadence.moe") - t.equal(msg.data.embeds[0].author.icon_url, "https://bridge.example.org/download/matrix/cadence.moe/HXfFuougamkURPPMflTJRxGc") - t.match(msg.data.embeds[0].description, "Sent with a per-message profile") - t.equal(called, 1) -}) diff --git a/src/m2d/converters/event-to-message.js b/src/m2d/converters/event-to-message.js index 95e477f..1b23787 100644 --- a/src/m2d/converters/event-to-message.js +++ b/src/m2d/converters/event-to-message.js @@ -550,30 +550,13 @@ async function eventToMessage(event, guild, channel, di) { /** @type {string[]} */ let messageIDsToEdit = [] let replyLine = "" - // Extract a basic display name from the sender const match = event.sender.match(/^@(.*?):/) 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 = mxUtils.getPublicUrlForMxc(member.avatar_url) - - // MSC4144: Override display name and avatar from per-message profile if present - const perMessageProfile = event.content["com.beeper.per_message_profile"] - if (perMessageProfile?.displayname) displayName = perMessageProfile.displayname - if (perMessageProfile && "avatar_url" in perMessageProfile) { - if (perMessageProfile.avatar_url) { - // use provided avatar_url - avatarURL = mxUtils.getPublicUrlForMxc(perMessageProfile.avatar_url) - } else if (perMessageProfile.avatar_url === "") { - // empty string avatar_url clears the avatar - avatarURL = undefined - } - // else, omitted/null falls back to member avatar - } - // If the display name is too long to be put into the webhook (80 characters is the maximum), // put the excess characters into displayNameRunoff, later to be put at the top of the message let [displayNameShortened, displayNameRunoff] = splitDisplayName(displayName) @@ -816,16 +799,6 @@ async function eventToMessage(event, guild, channel, di) { if (shouldProcessTextEvent) { if (event.content.format === "org.matrix.custom.html" && event.content.formatted_body) { let input = event.content.formatted_body - if (perMessageProfile?.has_fallback) { - // Strip fallback elements added for clients that don't support per-message profiles. - // Deviates from recommended regexp in MSC to be less strict. Avoiding an HTML parser for performance reasons. - // ┌────A────┐ Opening HTML tag: capture tag name and stay within tag - // ┆ ┆┌─────────────B────────────┐ This text in the tag somewhere, presumably an attribute name - // ┆ ┆┆ ┆┌─C──┐ Rest of the opening tag - // ┆ ┆┆ ┆┆ ┆┌─D─┐ Tag content (no more tags allowed within) - // ┆ ┆┆ ┆┆ ┆┆ ┆┌─E──┐ Closing tag matching opening tag name - input = input.replace(/<(\w+)[^>]*\bdata-mx-profile-fallback\b[^>]*>[^<]*<\/\1>/g, "") - } if (event.content.msgtype === "m.emote") { input = `* ${displayName} ${input}` } @@ -971,10 +944,6 @@ async function eventToMessage(event, guild, channel, di) { } else { // Looks like we're using the plaintext body! content = event.content.body - if (perMessageProfile?.has_fallback && perMessageProfile.displayname && content.startsWith(perMessageProfile.displayname + ": ")) { - // Strip the display name prefix fallback added for clients that don't support per-message profiles - content = content.slice(perMessageProfile.displayname.length + 2) - } if (event.content.msgtype === "m.emote") { content = `* ${displayName} ${content}` diff --git a/src/m2d/converters/event-to-message.test.js b/src/m2d/converters/event-to-message.test.js index bc73df7..1c263b4 100644 --- a/src/m2d/converters/event-to-message.test.js +++ b/src/m2d/converters/event-to-message.test.js @@ -5526,141 +5526,6 @@ test("event2message: known and unknown emojis in the end are used for sprite she ) }) -test("event2message: com.beeper.per_message_profile overrides displayname and avatar_url", async t => { - t.deepEqual( - await eventToMessage({ - type: "m.room.message", - sender: "@cadence:cadence.moe", - content: { - msgtype: "m.text", - body: "hello from unstable profile", - "com.beeper.per_message_profile": { - id: "custom-id", - displayname: "Unstable Name", - avatar_url: "mxc://maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo" - } - }, - event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", - room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" - }), - { - ensureJoined: [], - messagesToDelete: [], - messagesToEdit: [], - messagesToSend: [{ - username: "Unstable Name", - content: "hello from unstable profile", - avatar_url: "https://bridge.example.org/download/matrix/maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo", - allowed_mentions: { - parse: ["users", "roles"] - } - }] - } - ) -}) - -test("event2message: com.beeper.per_message_profile empty avatar_url clears avatar", async t => { - t.deepEqual( - await eventToMessage({ - type: "m.room.message", - sender: "@cadence:cadence.moe", - content: { - msgtype: "m.text", - body: "hello with cleared avatar", - "com.beeper.per_message_profile": { - id: "no-avatar", - displayname: "No Avatar User", - avatar_url: "" - } - }, - event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", - room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" - }), - { - ensureJoined: [], - messagesToDelete: [], - messagesToEdit: [], - messagesToSend: [{ - username: "No Avatar User", - content: "hello with cleared avatar", - avatar_url: undefined, - allowed_mentions: { - parse: ["users", "roles"] - } - }] - } - ) -}) - -test("event2message: data-mx-profile-fallback element is stripped from formatted_body when per-message profile is present", async t => { - t.deepEqual( - await eventToMessage({ - type: "m.room.message", - sender: "@cadence:cadence.moe", - content: { - msgtype: "m.text", - body: "Tidus Herboren: one more test", - format: "org.matrix.custom.html", - formatted_body: "Tidus Herboren: one more test", - "com.beeper.per_message_profile": { - id: "tidus", - displayname: "Tidus Herboren", - avatar_url: "mxc://maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo", - has_fallback: true - } - }, - event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", - room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" - }), - { - ensureJoined: [], - messagesToDelete: [], - messagesToEdit: [], - messagesToSend: [{ - username: "Tidus Herboren", - content: "one more test", - avatar_url: "https://bridge.example.org/download/matrix/maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo", - allowed_mentions: { - parse: ["users", "roles"] - } - }] - } - ) -}) - -test("event2message: displayname prefix is stripped from plain body when per-message profile has_fallback", async t => { - t.deepEqual( - await eventToMessage({ - type: "m.room.message", - sender: "@cadence:cadence.moe", - content: { - msgtype: "m.text", - body: "Tidus Herboren: one more test", - "com.beeper.per_message_profile": { - id: "tidus", - displayname: "Tidus Herboren", - has_fallback: true - } - }, - event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", - room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" - }), - { - ensureJoined: [], - messagesToDelete: [], - messagesToEdit: [], - messagesToSend: [{ - username: "Tidus Herboren", - content: "one more test", - avatar_url: undefined, - allowed_mentions: { - parse: ["users", "roles"] - } - }] - } - ) -}) - test("event2message: all unknown chess emojis are used for sprite sheet", async t => { t.deepEqual( await eventToMessage({