瀏覽代碼

Fetch shared reel data to bridge as video

Fixes #78
Tulir Asokan 2 年之前
父節點
當前提交
3ecd240acd
共有 4 個文件被更改,包括 35 次插入0 次删除
  1. 8 0
      mauigpapi/http/thread.py
  2. 1 0
      mauigpapi/types/__init__.py
  3. 17 0
      mauigpapi/types/thread_item.py
  4. 9 0
      mautrix_instagram/portal.py

+ 8 - 0
mauigpapi/http/thread.py

@@ -25,6 +25,7 @@ from ..types import (
     CommandResponse,
     DMInboxResponse,
     DMThreadResponse,
+    FetchedClipInfo,
     Thread,
     ThreadAction,
     ThreadItemType,
@@ -254,3 +255,10 @@ class ThreadAPI(BaseAndroidAPI):
         return await self._broadcast(
             thread_id, item_type.value, CommandResponse, signed, client_context, **kwargs
         )
+
+    async def fetch_clip(self, media_id: int) -> FetchedClipInfo:
+        return await self.std_http_get(
+            f"/api/v1/clips/item/",
+            query={"clips_media_id": str(media_id)},
+            response_type=FetchedClipInfo,
+        )

+ 1 - 0
mauigpapi/types/__init__.py

@@ -80,6 +80,7 @@ from .thread_item import (
     CreateModeAttribution,
     CreativeConfig,
     ExpiredMediaItem,
+    FetchedClipInfo,
     ImageVersion,
     ImageVersions,
     LinkContext,

+ 17 - 0
mauigpapi/types/thread_item.py

@@ -17,6 +17,7 @@ from typing import List, Optional, Union
 import logging
 
 from attr import dataclass
+from yarl import URL
 import attr
 
 from mautrix.types import (
@@ -517,6 +518,16 @@ class XMAMediaShareItem(SerializableAttrs):
     preview_width: Optional[int] = None
     preview_height: Optional[int] = None
 
+    @property
+    def reel_share_clip_id(self) -> Optional[int]:
+        if "instagram.com/reel/" not in self.target_url:
+            return None
+        try:
+            real_id, extra_id = URL(self.target_url).query["id"].split("_")
+            return int(real_id)
+        except (ValueError, KeyError):
+            return None
+
 
 @dataclass
 class XMAMediaProfileShareItem(SerializableAttrs):
@@ -558,6 +569,12 @@ class PlaceholderItem(SerializableAttrs):
     # is_linked: bool
 
 
+@dataclass
+class FetchedClipInfo(SerializableAttrs):
+    media: MediaShareItem
+    status: str
+
+
 @dataclass(kw_only=True)
 class ThreadItem(SerializableAttrs):
     item_id: Optional[str] = None

+ 9 - 0
mautrix_instagram/portal.py

@@ -864,6 +864,15 @@ class Portal(DBPortal, BasePortal):
     async def _reupload_instagram_xma(
         self, source: u.User, media: XMAMediaShareItem, intent: IntentAPI
     ) -> MediaMessageEventContent:
+        reel_clip_id = media.reel_share_clip_id
+        if reel_clip_id:
+            try:
+                fetched_clip = await source.client.fetch_clip(reel_clip_id)
+                return await self._reupload_instagram_media(source, fetched_clip.media, intent)
+            except Exception:
+                self.log.exception(f"Failed to fetch clip {reel_clip_id}, using fallback")
+        elif "/reel/" in media.target_url:
+            self.log.warning(f"No reel share clip ID found in {media.target_url}")
         url = media.preview_url
         info = ImageInfo(
             mimetype=media.preview_url_mime_type,