Skip to content

Implement MUC MAM#2181

Open
jubalh wants to merge 25 commits into
masterfrom
mamtrial
Open

Implement MUC MAM#2181
jubalh wants to merge 25 commits into
masterfrom
mamtrial

Conversation

@jubalh

@jubalh jubalh commented Jun 25, 2026

Copy link
Copy Markdown
Member

I recommend to not run this on your regular system in case we didn't get things right yet regarding the database.
Either backup your sqlite db before or work on a separate linux user account or use a container or something like that.

@jubalh jubalh added this to the next milestone Jun 25, 2026
@jubalh jubalh self-assigned this Jun 25, 2026
@jubalh jubalh added the MAM label Jun 25, 2026
@jubalh jubalh mentioned this pull request Jun 25, 2026
18 tasks
jubalh added 16 commits June 25, 2026 20:31
Track whether a MUC supports MAM by resolving room features during
discovery.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Implement stanza_create_muc_mam_iq() to generate MUC targeted MAM
queries.
This sets the 'to' attribute to the rooms JID
and omits the personal 'with' field filter.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Adapt iq_mam_request and iq_mam_request_older to accept ProfWin*
and support WIN_MUC windows. Update _mam_buffer_commit_handler to
invoke the proper database history loader when page sync is complete.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Implement mucwin_db_history to load room logs from the sql db and
print them to the rooms buffer.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Distinguish in sv_ev_room_message() between MAM and regular MUC
messages.

Dont notify, flash, beep in case of MAM.
Use proper timestamps.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Trigger iq_mam_request for joined rooms that support MAM.
Add groupchat tag for /mam command.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Ensure servers receive the correct empty before tag and page
backward properly.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Add max_stanzas_zero parameter to stanza_create_room_join_presence.
When enabled, it adds <history maxstanzas="0"/> to the MUC join stanza.
Query this preference in presence.c and pass it to avoid replaying duplicate
history when MAM is active and supported.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Add a defensive check in _handle_mam to verify if the MAM result is from
an active MUC room. If so, discard any forwarded message that is not of
type "groupchat" (such as "chat" room PM leaks sent by buggy servers).

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Print `End of archive reached` to top of the window buffer if we reached
the end of the archive.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
New `/mam verify` checks the integrity of the local history.
It takes the dates from the messages on the current screen. Then asks
the server how many messages should be between those timestamps.
In case the server notifies us about more messages that we have in the
DB we will retrieve the messages.

It's useful to fill gaps in case the user knows that there is something
missing.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Use the messages original timestamp in mention and trigger related
code.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
When connection is re-established, trigger iq_mam_request for all active
chat and groupchat windows.
This automatically queries the database for the latest recorded timestamp
in each window and performs a targeted MAM query to
synchronize and catch up on any missed offline messages.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
jubalh added 5 commits June 26, 2026 09:46
XEP-0313 Section 4.1.2 states:
```
The <result/> element MUST have a 'by' attribute. [...] For archives
that are bound to a specific JID (like a MUC room or a pubsub node),
the value of this attribute is the JID of the entity that hosts the
archive. [...] If the 'by' attribute is not present, or if it does
not match the expected JID, the client MUST ignore the result.
```

But some XMPP servers omit this attribute on MUC MAM responses.
Previously, when the 'by' attribute was missing, Profanity assumed
a user archive and required the sender's JID to match our own bare JID:

if (from && !equals_our_barejid(from)) { ... ignore ... }

For MUC archives, the sender is the MUCs bare JID, which caused
Profanity to log a JID mismatch warning and discard the fetched messages.

Update the validation logic to also accept the result when the
sender is an active MUC.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Reset the scroll position to the top of the history and exit the paged/scrolled
state when the archive ends.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
In case we show the end of archive banner dont request older
MAM messages.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
We do the same for OMEMO etc.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
@jubalh jubalh marked this pull request as ready for review June 26, 2026 14:15
@jubalh

jubalh commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

Seems to work well. I still have some ideas and improvements to do later. Might merge it already though.

@jubalh jubalh force-pushed the mamtrial branch 2 times, most recently from 1479d22 to 1fee2f3 Compare June 26, 2026 14:28
jubalh added 3 commits June 26, 2026 16:33
Profanity requests bookmarks and queries the server features in
parallel.  Because the bookmark often arrives before the server features
are resolved, rooms are autojoined without knowing if the server
supports MAM.

So we ask to join the MUC without history disabled.  Then server sends
back standard room history, which also lacks delayed delivery tags under
certain configurations.  We then display and record these messages as
fresh messages.

We now postpone the bookmark request until after the service discovery
features have been received.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Profanity requests to enable message carbons immediately on connection.
Without knowing the server features yet.

If the server does not support message carbons, it responds with a
service-unavailable error which spams the user during login.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
When joining a MUC the local db history is loaded when the window is created.
Then the servers MAM response arrives including messages sent by the
ourselves in previous sessions.

The database layer correctly skips duplicate insertions.
But doesn't inform the caller that it skipped the insertion.

This caused the event handler to assume the replayed message was a
realtime message and render it a second time.

Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Fixes: #660
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
@jubalh

jubalh commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

Note: I didn't test yet whether message loading from DB works still as expected if MAM is disabled.

@jubalh

jubalh commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

That functional test fail is expected. I'll need to adapt the tests according to my changes. Probably should adapt stabber to advertise features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant