fix: use reels_media endpoint for stories (returns actual items)
- /feed/user/{id}/story/ only returns reel metadata, not items
- /feed/reels_media/ with POST returns actual story media
- Batch user IDs (20 per request) for efficiency
- Fallback: reels_tray -> reels_media batch
This commit is contained in:
@@ -194,10 +194,12 @@ class InstagramMonitor:
|
|||||||
return followees
|
return followees
|
||||||
|
|
||||||
def _get_user_stories(self, user_pk: int) -> list[dict]:
|
def _get_user_stories(self, user_pk: int) -> list[dict]:
|
||||||
|
"""Fetch stories via reels_media endpoint (returns actual items)."""
|
||||||
try:
|
try:
|
||||||
resp = self.session.get(
|
resp = self.session.post(
|
||||||
f"{API_BASE}/feed/user/{user_pk}/story/",
|
f"{API_BASE}/feed/reels_media/",
|
||||||
params={"user_id": user_pk},
|
json={"user_ids": [user_pk]},
|
||||||
|
headers={**IG_HEADERS, "Content-Type": "application/x-www-form-urlencoded"},
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
@@ -206,9 +208,7 @@ class InstagramMonitor:
|
|||||||
|
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
items = data.get("items", [])
|
items = data.get("items", [])
|
||||||
logger.debug(f"Stories {user_pk}: {len(items)} items, keys={list(data.keys())}")
|
|
||||||
if not items:
|
if not items:
|
||||||
logger.debug(f"Stories {user_pk} raw: {resp.text[:400]}")
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
stories = []
|
stories = []
|
||||||
@@ -364,16 +364,36 @@ class InstagramMonitor:
|
|||||||
all_stories = self._get_all_stories()
|
all_stories = self._get_all_stories()
|
||||||
total_stories = sum(len(s) for s in all_stories.values())
|
total_stories = sum(len(s) for s in all_stories.values())
|
||||||
|
|
||||||
# Method 2: per-user stories for known active users (fallback)
|
# Method 2: per-user stories via reels_media (fallback)
|
||||||
if total_stories == 0:
|
if total_stories == 0:
|
||||||
logger.info("reels_tray empty, trying per-user story fetch for followees...")
|
logger.info("reels_tray empty, trying reels_media for followees...")
|
||||||
for user in followees[:10]:
|
# Batch user IDs for reels_media
|
||||||
user_pk = user["pk"]
|
user_pks = [u["pk"] for u in followees]
|
||||||
stories = self._get_user_stories(user_pk)
|
for batch_start in range(0, len(user_pks), 20):
|
||||||
if stories:
|
batch = user_pks[batch_start:batch_start + 20]
|
||||||
all_stories[user_pk] = stories
|
try:
|
||||||
total_stories += len(stories)
|
resp = self.session.post(
|
||||||
logger.info(f"@{user['username']}: {len(stories)} stories via per-user endpoint")
|
f"{API_BASE}/feed/reels_media/",
|
||||||
|
json={"user_ids": batch},
|
||||||
|
headers={**IG_HEADERS, "Content-Type": "application/x-www-form-urlencoded"},
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
data = resp.json()
|
||||||
|
items = data.get("items", [])
|
||||||
|
for item in items:
|
||||||
|
user_info = item.get("user", {})
|
||||||
|
user_pk = user_info.get("pk", item.get("user_pk", 0))
|
||||||
|
media_id = str(item.get("pk", item.get("id", "")))
|
||||||
|
if self.db.is_downloaded(media_id):
|
||||||
|
continue
|
||||||
|
if user_pk not in all_stories:
|
||||||
|
all_stories[user_pk] = []
|
||||||
|
all_stories[user_pk].append(item)
|
||||||
|
total_stories += 1
|
||||||
|
logger.info(f"reels_media batch: {len(items)} stories from {len(data.get('statuses', []))} users")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"reels_media batch error: {e}")
|
||||||
|
|
||||||
logger.info(f"Total stories found: {total_stories}")
|
logger.info(f"Total stories found: {total_stories}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user