Browse Source

Send delivery receipt after bridging message

Tulir Asokan 4 years ago
parent
commit
0857301f8b
4 changed files with 21 additions and 11 deletions
  1. 4 3
      mausignald/signald.py
  2. 8 6
      mautrix_signal/matrix.py
  3. 8 1
      mautrix_signal/portal.py
  4. 1 1
      mautrix_signal/signal.py

+ 4 - 3
mausignald/signald.py

@@ -108,9 +108,10 @@ class SignaldClient(SignaldRPCClient):
                            timestamp=timestamp, **self._recipient_to_args(recipient))
                            timestamp=timestamp, **self._recipient_to_args(recipient))
         # TODO return something?
         # TODO return something?
 
 
-    async def mark_read(self, username: str, sender: Address, timestamps: List[int],
-                        when: Optional[int] = None) -> None:
-        await self.request_nowait("mark_read", username=username, timestamps=timestamps, when=when,
+    async def send_receipt(self, username: str, sender: Address, timestamps: List[int],
+                           when: Optional[int] = None, read: bool = False) -> None:
+        await self.request_nowait("mark_read" if read else "mark_delivered", username=username,
+                                  timestamps=timestamps, when=when,
                                   recipientAddress=sender.serialize())
                                   recipientAddress=sender.serialize())
 
 
     async def list_contacts(self, username: str) -> List[Contact]:
     async def list_contacts(self, username: str) -> List[Contact]:

+ 8 - 6
mautrix_signal/matrix.py

@@ -20,7 +20,7 @@ from mausignald.types import Address
 from mautrix.bridge import BaseMatrixHandler
 from mautrix.bridge import BaseMatrixHandler
 from mautrix.types import (Event, ReactionEvent, MessageEvent, StateEvent, EncryptedEvent, RoomID,
 from mautrix.types import (Event, ReactionEvent, MessageEvent, StateEvent, EncryptedEvent, RoomID,
                            EventID, UserID, ReactionEventContent, RelationType, EventType,
                            EventID, UserID, ReactionEventContent, RelationType, EventType,
-                           ReceiptEvent, TypingEvent, PresenceEvent, RedactionEvent)
+                           ReceiptEvent, TypingEvent, PresenceEvent, RedactionEvent, ReceiptType)
 
 
 from .db import Message as DBMessage
 from .db import Message as DBMessage
 from . import puppet as pu, portal as po, user as u, signal as s
 from . import puppet as pu, portal as po, user as u, signal as s
@@ -87,9 +87,11 @@ class MatrixHandler(BaseMatrixHandler):
 
 
     async def handle_receipt(self, evt: ReceiptEvent) -> None:
     async def handle_receipt(self, evt: ReceiptEvent) -> None:
         # These events come from custom puppet syncing, so there's always only one user.
         # These events come from custom puppet syncing, so there's always only one user.
-        event_id, receipts = evt.content.popitem()
-        receipt_type, users = receipts.popitem()
-        user_id, data = users.popitem()
+        try:
+            event_id, receipts = evt.content.popitem()
+            user_id, data = receipts[ReceiptType.READ].popitem()
+        except KeyError:
+            return
 
 
         user = await u.User.get_by_mxid(user_id, create=False)
         user = await u.User.get_by_mxid(user_id, create=False)
         if not user or not user.username:
         if not user or not user.username:
@@ -104,8 +106,8 @@ class MatrixHandler(BaseMatrixHandler):
             return
             return
 
 
         user.log.trace(f"Sending read receipt for {message.timestamp} to {message.sender}")
         user.log.trace(f"Sending read receipt for {message.timestamp} to {message.sender}")
-        await self.signal.mark_read(user.username, Address(uuid=message.sender),
-                                    timestamps=[message.timestamp], when=data.ts)
+        await self.signal.send_receipt(user.username, Address(uuid=message.sender),
+                                       timestamps=[message.timestamp], when=data.ts, read=True)
 
 
     async def handle_typing(self, room_id: RoomID, typing: List[UserID]) -> None:
     async def handle_typing(self, room_id: RoomID, typing: List[UserID]) -> None:
         pass
         pass

+ 8 - 1
mautrix_signal/portal.py

@@ -289,16 +289,21 @@ class Portal(DBPortal, BasePortal):
         except MatrixError:
         except MatrixError:
             return reply_msg.mxid
             return reply_msg.mxid
 
 
-    async def handle_signal_message(self, sender: 'p.Puppet', message: MessageData) -> None:
+    async def handle_signal_message(self, source: 'u.User', sender: 'p.Puppet',
+                                    message: MessageData) -> None:
         if (sender.uuid, message.timestamp) in self._msgts_dedup:
         if (sender.uuid, message.timestamp) in self._msgts_dedup:
             self.log.debug(f"Ignoring message {message.timestamp} by {sender.uuid}"
             self.log.debug(f"Ignoring message {message.timestamp} by {sender.uuid}"
                            " as it was already handled (message.timestamp in dedup queue)")
                            " as it was already handled (message.timestamp in dedup queue)")
+            await self.signal.send_receipt(source.username, sender.address,
+                                           timestamps=[message.timestamp])
             return
             return
         old_message = await DBMessage.get_by_signal_id(sender.uuid, message.timestamp,
         old_message = await DBMessage.get_by_signal_id(sender.uuid, message.timestamp,
                                                        self.chat_id, self.receiver)
                                                        self.chat_id, self.receiver)
         if old_message is not None:
         if old_message is not None:
             self.log.debug(f"Ignoring message {message.timestamp} by {sender.uuid}"
             self.log.debug(f"Ignoring message {message.timestamp} by {sender.uuid}"
                            " as it was already handled (message.id found in database)")
                            " as it was already handled (message.id found in database)")
+            await self.signal.send_receipt(source.username, sender.address,
+                                           timestamps=[message.timestamp])
             return
             return
         self.log.debug(f"Started handling message {message.timestamp} by {sender.uuid}")
         self.log.debug(f"Started handling message {message.timestamp} by {sender.uuid}")
         self.log.trace(f"Message content: {message}")
         self.log.trace(f"Message content: {message}")
@@ -343,6 +348,8 @@ class Portal(DBPortal, BasePortal):
                             sender=sender.uuid, timestamp=message.timestamp,
                             sender=sender.uuid, timestamp=message.timestamp,
                             signal_chat_id=self.chat_id, signal_receiver=self.receiver)
                             signal_chat_id=self.chat_id, signal_receiver=self.receiver)
             await msg.insert()
             await msg.insert()
+            await self.signal.send_receipt(source.username, sender.address,
+                                           timestamps=[message.timestamp])
             await self._send_delivery_receipt(event_id)
             await self._send_delivery_receipt(event_id)
             self.log.debug(f"Handled Signal message {message.timestamp} -> {event_id}")
             self.log.debug(f"Handled Signal message {message.timestamp} -> {event_id}")
         else:
         else:

+ 1 - 1
mautrix_signal/signal.py

@@ -86,7 +86,7 @@ class SignalHandler(SignaldClient):
         if msg.reaction:
         if msg.reaction:
             await portal.handle_signal_reaction(sender, msg.reaction)
             await portal.handle_signal_reaction(sender, msg.reaction)
         if msg.body or msg.attachments or msg.sticker:
         if msg.body or msg.attachments or msg.sticker:
-            await portal.handle_signal_message(sender, msg)
+            await portal.handle_signal_message(user, sender, msg)
         if msg.group and msg.group.type == "UPDATE":
         if msg.group and msg.group.type == "UPDATE":
             await portal.update_info(msg.group)
             await portal.update_info(msg.group)