diff --git a/src/discord/interactions/matrix-info.js b/src/discord/interactions/matrix-info.js index f5aa539..c85cec2 100644 --- a/src/discord/interactions/matrix-info.js +++ b/src/discord/interactions/matrix-info.js @@ -62,20 +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() - // Check for per-message profile - const perMessageProfile = event.content?.["com.beeper.per_message_profile"] - let name = matrixMember?.displayname || event.sender - let avatar = utils.getPublicUrlForMxc(matrixMember?.avatar_url) - let profileNote = "" - if (perMessageProfile) { - if (perMessageProfile.displayname) { - name = perMessageProfile.displayname - } - if ("avatar_url" in perMessageProfile) { - avatar = perMessageProfile.avatar_url ? utils.getPublicUrlForMxc(perMessageProfile.avatar_url) : undefined - } - profileNote = " (sent with a per-message profile)" - } + const name = matrixMember?.displayname || event.sender return { type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, data: { @@ -83,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**${profileNote}.\n[View on Matrix →]()\n\n**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/m2d/converters/event-to-message.js b/src/m2d/converters/event-to-message.js index 7c233c7..fb666e2 100644 --- a/src/m2d/converters/event-to-message.js +++ b/src/m2d/converters/event-to-message.js @@ -557,18 +557,10 @@ async function eventToMessage(event, guild, channel, di) { 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"] + // Override display name and avatar from MSC4144 per-message profile if present + const perMessageProfile = event.content["m.per_message_profile"] || event.content["com.beeper.per_message_profile"] if (perMessageProfile?.displayname) displayName = perMessageProfile.displayname - if (perMessageProfile && "avatar_url" in perMessageProfile) { - if (perMessageProfile.avatar_url === "") { - // empty string avatar_url clears the avatar (use default) - avatarURL = undefined - } else if (perMessageProfile.avatar_url) { - // omitted/null falls back to member avatar - avatarURL = mxUtils.getPublicUrlForMxc(perMessageProfile.avatar_url) - } - } + if (perMessageProfile?.avatar_url) avatarURL = mxUtils.getPublicUrlForMxc(perMessageProfile.avatar_url) // 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) @@ -813,7 +805,7 @@ async function eventToMessage(event, guild, channel, di) { let input = event.content.formatted_body if (perMessageProfile?.has_fallback) { // Strip fallback elements added for clients that don't support per-message profiles - input = input.replace(/<(\w+)[^>]*\bdata-mx-profile-fallback\b[^>]*>[^<]*<\/\1>/g, "") + input = input.replace(/<(\w+)[^>]*\bdata-mx-profile-fallback\b[^>]*>[\s\S]*?<\/\1>/g, "") } if (event.content.msgtype === "m.emote") { input = `* ${displayName} ${input}` diff --git a/src/m2d/converters/event-to-message.test.js b/src/m2d/converters/event-to-message.test.js index bc73df7..1c37b7a 100644 --- a/src/m2d/converters/event-to-message.test.js +++ b/src/m2d/converters/event-to-message.test.js @@ -5526,7 +5526,40 @@ 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 => { +test("event2message: m.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 a custom profile", + "m.per_message_profile": { + id: "custom-id", + displayname: "Custom Name", + avatar_url: "mxc://maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo" + } + }, + event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", + room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" + }), + { + ensureJoined: [], + messagesToDelete: [], + messagesToEdit: [], + messagesToSend: [{ + username: "Custom Name", + content: "hello from a custom profile", + avatar_url: "https://bridge.example.org/download/matrix/maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo", + allowed_mentions: { + parse: ["users", "roles"] + } + }] + } + ) +}) + +test("event2message: com.beeper.per_message_profile (unstable prefix) overrides displayname and avatar_url", async t => { t.deepEqual( await eventToMessage({ type: "m.room.message", @@ -5559,18 +5592,21 @@ test("event2message: com.beeper.per_message_profile overrides displayname and av ) }) -test("event2message: com.beeper.per_message_profile empty avatar_url clears avatar", async t => { +test("event2message: m.per_message_profile takes priority over com.beeper.per_message_profile", async t => { t.deepEqual( await eventToMessage({ type: "m.room.message", sender: "@cadence:cadence.moe", content: { msgtype: "m.text", - body: "hello with cleared avatar", + body: "stable wins", + "m.per_message_profile": { + id: "stable-id", + displayname: "Stable Name" + }, "com.beeper.per_message_profile": { - id: "no-avatar", - displayname: "No Avatar User", - avatar_url: "" + id: "unstable-id", + displayname: "Unstable Name" } }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", @@ -5581,8 +5617,8 @@ test("event2message: com.beeper.per_message_profile empty avatar_url clears avat messagesToDelete: [], messagesToEdit: [], messagesToSend: [{ - username: "No Avatar User", - content: "hello with cleared avatar", + username: "Stable Name", + content: "stable wins", avatar_url: undefined, allowed_mentions: { parse: ["users", "roles"]