Browse Source

Sync read receipts from Instagram after backfilling

Tulir Asokan 4 years ago
parent
commit
ab4cecdfe6
2 changed files with 18 additions and 4 deletions
  1. 1 1
      mauigpapi/types/thread.py
  2. 17 3
      mautrix_instagram/portal.py

+ 1 - 1
mauigpapi/types/thread.py

@@ -78,7 +78,7 @@ class Thread(SerializableAttrs['Thread']):
     has_newer: bool
     has_newer: bool
 
 
     theme: ThreadTheme
     theme: ThreadTheme
-    last_seen_at: Dict[int, ThreadUserLastSeenAt] = attr.ib(factory=lambda: {})
+    last_seen_at: Dict[str, ThreadUserLastSeenAt] = attr.ib(factory=lambda: {})
 
 
     newest_cursor: Optional[str] = None
     newest_cursor: Optional[str] = None
     oldest_cursor: Optional[str] = None
     oldest_cursor: Optional[str] = None

+ 17 - 3
mautrix_instagram/portal.py

@@ -26,7 +26,7 @@ import magic
 from mauigpapi.types import (Thread, ThreadUser, ThreadItem, RegularMediaItem, MediaType,
 from mauigpapi.types import (Thread, ThreadUser, ThreadItem, RegularMediaItem, MediaType,
                              ReactionStatus, Reaction, AnimatedMediaItem, ThreadItemType,
                              ReactionStatus, Reaction, AnimatedMediaItem, ThreadItemType,
                              VoiceMediaItem, ExpiredMediaItem, MessageSyncMessage, ReelShareType,
                              VoiceMediaItem, ExpiredMediaItem, MessageSyncMessage, ReelShareType,
-                             TypingStatus)
+                             TypingStatus, ThreadUserLastSeenAt)
 from mautrix.appservice import AppService, IntentAPI
 from mautrix.appservice import AppService, IntentAPI
 from mautrix.bridge import BasePortal, NotificationDisabler, async_getter_lock
 from mautrix.bridge import BasePortal, NotificationDisabler, async_getter_lock
 from mautrix.types import (EventID, MessageEventContent, RoomID, EventType, MessageType, ImageInfo,
 from mautrix.types import (EventID, MessageEventContent, RoomID, EventType, MessageType, ImageInfo,
@@ -665,8 +665,6 @@ class Portal(DBPortal, BasePortal):
             return ""
             return ""
 
 
     async def update_info(self, thread: Thread, source: 'u.User') -> None:
     async def update_info(self, thread: Thread, source: 'u.User') -> None:
-        if self.is_direct and self.other_user_pk == source.igpk and not thread.thread_title:
-            thread.thread_title = "Instagram chat with yourself"
         changed = await self._update_name(self._get_thread_name(thread))
         changed = await self._update_name(self._get_thread_name(thread))
         if changed:
         if changed:
             await self.update_bridge_info()
             await self.update_bridge_info()
@@ -700,6 +698,20 @@ class Portal(DBPortal, BasePortal):
                 await self.main_intent.kick_user(self.mxid, p.Puppet.get_mxid_from_id(pk),
                 await self.main_intent.kick_user(self.mxid, p.Puppet.get_mxid_from_id(pk),
                                                  reason="User had left this Instagram DM")
                                                  reason="User had left this Instagram DM")
 
 
+    async def _update_read_receipts(self, receipts: Dict[int, ThreadUserLastSeenAt]) -> None:
+        for user_id, receipt in receipts.items():
+            message = await DBMessage.get_by_item_id(receipt.item_id, self.receiver)
+            if not message:
+                continue
+            puppet = await p.Puppet.get_by_pk(int(user_id), create=False)
+            if not puppet:
+                continue
+            try:
+                await puppet.intent_for(self).mark_read(message.mx_room, message.mxid)
+            except Exception:
+                self.log.warning(f"Failed to mark {message.mxid} in {message.mx_room} "
+                                 f"as read by {puppet.intent.mxid}", exc_info=True)
+
     # endregion
     # endregion
     # region Backfilling
     # region Backfilling
 
 
@@ -819,6 +831,7 @@ class Portal(DBPortal, BasePortal):
                 self.log.debug(f"Last permanent item ({info.last_permanent_item.item_id})"
                 self.log.debug(f"Last permanent item ({info.last_permanent_item.item_id})"
                                " not found in database, starting backfilling")
                                " not found in database, starting backfilling")
                 await self.backfill(source, is_initial=False)
                 await self.backfill(source, is_initial=False)
+        await self._update_read_receipts(info.last_seen_at)
 
 
         # TODO
         # TODO
         # up = DBUserPortal.get(source.fbid, self.fbid, self.fb_receiver)
         # up = DBUserPortal.get(source.fbid, self.fbid, self.fb_receiver)
@@ -904,6 +917,7 @@ class Portal(DBPortal, BasePortal):
                 await self.backfill(source, is_initial=True)
                 await self.backfill(source, is_initial=True)
             except Exception:
             except Exception:
                 self.log.exception("Failed to backfill new portal")
                 self.log.exception("Failed to backfill new portal")
+            await self._update_read_receipts(info.last_seen_at)
 
 
         return self.mxid
         return self.mxid