瀏覽代碼

Find links when sending messages to Instagram

Tulir Asokan 3 年之前
父節點
當前提交
c8f0d9bc64
共有 2 個文件被更改,包括 23 次插入3 次删除
  1. 13 2
      mauigpapi/mqtt/conn.py
  2. 10 1
      mautrix_instagram/portal.py

+ 13 - 2
mauigpapi/mqtt/conn.py

@@ -764,16 +764,27 @@ class AndroidMQTT:
         self,
         thread_id: str,
         text: str = "",
+        urls: list[str] | None = None,
         shh_mode: bool = False,
         client_context: str | None = None,
         replied_to_item_id: str | None = None,
         replied_to_client_context: str | None = None,
     ) -> Awaitable[CommandResponse]:
+        args = {
+            "text": text,
+        }
+        item_type = ThreadItemType.TEXT
+        if urls is not None:
+            args = {
+                "link_text": text,
+                "link_urls": json.dumps(urls or []),
+            }
+            item_type = ThreadItemType.LINK
         return self.send_item(
             thread_id,
-            text=text,
+            **args,
             shh_mode=shh_mode,
-            item_type=ThreadItemType.TEXT,
+            item_type=item_type,
             client_context=client_context,
             replied_to_item_id=replied_to_item_id,
             replied_to_client_context=replied_to_client_context,

+ 10 - 1
mautrix_instagram/portal.py

@@ -21,6 +21,7 @@ from io import BytesIO
 import asyncio
 import json
 import mimetypes
+import re
 
 import asyncpg
 import magic
@@ -97,6 +98,11 @@ MediaData = Union[
 ]
 MediaUploadFunc = Callable[["u.User", MediaData, IntentAPI], Awaitable[MediaMessageEventContent]]
 
+# This doesn't need to capture all valid URLs, it's enough to catch most of them.
+# False negatives simply mean the link won't be linkified on Instagram,
+# but false positives will cause the message to fail to send.
+SIMPLE_URL_REGEX = re.compile(r"(?P<url>https?://[\da-z.-]+\.[a-z]{2,}(?:/[^\s]*)?)", flags=re.IGNORECASE)
+
 
 class Portal(DBPortal, BasePortal):
     by_mxid: dict[RoomID, Portal] = {}
@@ -396,8 +402,9 @@ class Portal(DBPortal, BasePortal):
             if message.msgtype == MessageType.EMOTE:
                 text = f"/me {text}"
             self.log.trace(f"Sending Matrix text from {event_id} with request ID {request_id}")
+            urls = SIMPLE_URL_REGEX.findall(text) or None
             resp = await sender.mqtt.send_text(
-                self.thread_id, text=text, client_context=request_id, **reply_to
+                self.thread_id, text=text, urls=urls, client_context=request_id, **reply_to
             )
         elif message.msgtype.is_media:
             if message.file and decrypt_attachment:
@@ -1069,6 +1076,8 @@ class Portal(DBPortal, BasePortal):
     async def _handle_instagram_item(
         self, source: u.User, sender: p.Puppet, item: ThreadItem, is_backfill: bool = False
     ) -> None:
+        if not item.client_context and item.link and item.link.client_context:
+            item.client_context = item.link.client_context
         if not isinstance(item, ThreadItem):
             # Parsing these items failed, they should have been logged already
             return