Add support for MSC-4144: Per-Message Profiles #82

Merged
cadence merged 6 commits from beanie/out-of-your-element:msc4144 into main 2026-03-25 03:10:54 +00:00
Contributor

This PR implements support for using per-message profile data if present in either com.beeper.per_message_profile (unstable), or m.per_message_profile (stable), updating the displayName and avatarURL as required.

If a message contains a fallback, we additionally strip the fallback identity from both the plaintext and formatted HTML components as per the specification.

Completes #59

This PR implements support for using per-message profile data if present in either `com.beeper.per_message_profile` (unstable), or `m.per_message_profile` (stable), updating the displayName and avatarURL as required. If a message contains a fallback, we additionally strip the fallback identity from both the plaintext and formatted HTML components as per the specification. Completes #59
beanie added 2 commits 2026-03-20 14:19:10 +00:00
Override webhook username and avatar_url from m.per_message_profile
(and unstable com.beeper.per_message_profile) when present.
The stable key takes priority over the unstable prefix.
Remove data-mx-profile-fallback elements from formatted_body and
displayname prefix from plain body when per-message profile is used.
Author
Contributor

To address one of the main criticisms I have with that MSC, they make the suggestion of matching specifically this tag: <strong\s+data-mx-profile-fallback(?:="")?\s*>([^<]+): </strong\s*>

I have instead implemented the following, which is safer, handling multi-line input, matching the same closing tag, etc.

input = input.replace(/<(\w+)[^>]*\bdata-mx-profile-fallback\b[^>]*>[\s\S]*?<\/\1>/g, "")

This however is not 100% safe, no regular expression is. Personally I'm going to argue for the non-fallback content to be explicitly stated in that MSC, because regex should be used for matching, not content manipulation in matrix client or bridge implementations.

Similarly, trimming the plaintext component also assumes that clients implement the spec accurately as it stands today, and do not deviate. This also cannot be guaranteed.

To address one of the main criticisms I have with that MSC, they make the suggestion of matching specifically this tag: `<strong\s+data-mx-profile-fallback(?:="")?\s*>([^<]+): </strong\s*>` I have instead implemented the following, which is safer, handling multi-line input, matching the same closing tag, etc. ```js input = input.replace(/<(\w+)[^>]*\bdata-mx-profile-fallback\b[^>]*>[\s\S]*?<\/\1>/g, "") ``` This however is not 100% safe, no regular expression is. Personally I'm going to argue for the non-fallback content to be explicitly stated in that MSC, because regex should be used for matching, not content manipulation in matrix client or bridge implementations. Similarly, trimming the plaintext component also assumes that clients implement the spec accurately as it stands today, and do not deviate. This also cannot be guaranteed.
beanie added 2 commits 2026-03-24 15:58:09 +00:00
beanie added 2 commits 2026-03-24 16:44:42 +00:00
- Empty string "" -> undefined (Discord uses default avatar)
- Valid MXC URI -> convert to public URL
- Omitted/null -> keep member avatar
beanie force-pushed msc4144 from 5d29104dea to 87fcdb18ab 2026-03-24 16:45:48 +00:00 Compare
Author
Contributor

@cadence I'm.. not convinced on the matrix info command changes (more specifically, reflecting the real user that posted it rather than the PMP seems more appropriate) let me know what you think!

@cadence I'm.. not convinced on the matrix info command changes (more specifically, reflecting the real user that posted it rather than the PMP seems more appropriate) let me know what you think!
Author
Contributor

I take it back, it looks fine
image

I take it back, it looks fine ![image](/attachments/eb3d8b48-2373-4edb-b6c9-24e00f6f262a)
214 KiB
cadence added 1 commit 2026-03-25 03:10:22 +00:00
cadence merged commit f742d8572a into main 2026-03-25 03:10:54 +00:00
Sign in to join this conversation.
No description provided.