fix(gateway): fix matrix read receipts

This commit is contained in:
asheriif 2026-04-15 13:03:31 +00:00 committed by Teknium
parent 1dd6b5d5fb
commit 6c34bf3d00
3 changed files with 52 additions and 10 deletions

View file

@ -1598,11 +1598,21 @@ class MatrixAdapter(BasePlatformAdapter):
if not self._client:
return False
try:
await self._client.set_read_markers(
RoomID(room_id),
fully_read_event=EventID(event_id),
read_receipt=EventID(event_id),
)
room = RoomID(room_id)
event = EventID(event_id)
if hasattr(self._client, "set_fully_read_marker"):
await self._client.set_fully_read_marker(room, event, event)
elif hasattr(self._client, "send_receipt"):
await self._client.send_receipt(room, event)
elif hasattr(self._client, "set_read_markers"):
await self._client.set_read_markers(
room,
fully_read_event=event,
read_receipt=event,
)
else:
logger.debug("Matrix: client has no read receipt method")
return False
logger.debug("Matrix: sent read receipt for %s in %s", event_id, room_id)
return True
except Exception as exc:

View file

@ -69,6 +69,7 @@ AUTHOR_MAP = {
"241404605+MestreY0d4-Uninter@users.noreply.github.com": "MestreY0d4-Uninter",
"109555139+davetist@users.noreply.github.com": "davetist",
# contributors (manual mapping from git names)
"ahmedsherif95@gmail.com": "asheriif",
"dmayhem93@gmail.com": "dmahan93",
"samherring99@gmail.com": "samherring99",
"desaiaum08@gmail.com": "Aum08Desai",

View file

@ -1740,16 +1740,49 @@ class TestMatrixReadReceipts:
def setup_method(self):
self.adapter = _make_adapter()
@pytest.mark.asyncio
async def test_accepted_message_schedules_read_receipt(self):
self.adapter._is_dm_room = AsyncMock(return_value=True)
self.adapter._get_display_name = AsyncMock(return_value="Alice")
self.adapter._background_read_receipt = MagicMock()
ctx = await self.adapter._resolve_message_context(
room_id="!room:ex",
sender="@alice:ex",
event_id="$event1",
body="hello",
source_content={"body": "hello"},
relates_to={},
)
assert ctx is not None
self.adapter._background_read_receipt.assert_called_once_with(
"!room:ex", "$event1"
)
@pytest.mark.asyncio
async def test_send_read_receipt(self):
"""send_read_receipt should call client.set_read_markers."""
"""send_read_receipt should call mautrix's real read-marker API."""
mock_client = MagicMock()
mock_client.set_read_markers = AsyncMock(return_value=None)
mock_client.set_fully_read_marker = AsyncMock(return_value=None)
self.adapter._client = mock_client
result = await self.adapter.send_read_receipt("!room:ex", "$event1")
assert result is True
mock_client.set_read_markers.assert_called_once()
mock_client.set_fully_read_marker.assert_awaited_once_with(
"!room:ex", "$event1", "$event1"
)
@pytest.mark.asyncio
async def test_send_read_receipt_falls_back_to_receipt_only(self):
"""send_read_receipt should still work with clients lacking read markers."""
mock_client = MagicMock(spec=["send_receipt"])
mock_client.send_receipt = AsyncMock(return_value=None)
self.adapter._client = mock_client
result = await self.adapter.send_read_receipt("!room:ex", "$event1")
assert result is True
mock_client.send_receipt.assert_awaited_once_with("!room:ex", "$event1")
@pytest.mark.asyncio
async def test_read_receipt_no_client(self):
@ -1852,5 +1885,3 @@ class TestMatrixPresence:
self.adapter._client = None
result = await self.adapter.set_presence("online")
assert result is False