- Switch from requests to httpx.AsyncClient (full async HTTP)
- Add _request() with exponential backoff on 429/401
- Cache followees with 5-min TTL to reduce API calls
- Remove dead code (_get_all_stories, instagram_password, session_file)
- Graceful shutdown via asyncio.Event + SIGTERM/SIGINT handlers
- Add /health command with connection status
- Stream media downloads with httpx + aiofiles
- Track story expiring_at for smart cleanup
- Sanitize .env.example (remove real tokens)
- Replace broken reels_tray/reels_media (403 login_required) with per-user web API
- Fix response parsing: stories are in reel.items, not root items
- Use Chrome UA and web X-IG-App-ID for web API endpoint
- /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
- /debug @username shows raw API response for stories endpoint
- Debug logging enabled for story fetch
- /status now shows SQLite stats (story/post counts)
- Replace JSON state with SQLite (media.db)
- Schema: media_id, username, media_type, shortcode, file_path, downloaded_at
- Automatic cleanup of old records and files
- Fallback: per-user story fetch when reels_tray is empty
- Stats query for monitoring
- /feed/reels_tray/ fetches all stories in one API call
- Stories sent before posts (they're more time-sensitive)
- Per-user story fetch kept as fallback
- Much faster: 1 request vs 85 individual requests
- Stories and posts fetched simultaneously via asyncio.gather
- Semaphore limits concurrent followee checks (default 5)
- CONCURRENT_CHECKS env var to tune parallelism
- 5-10x faster first run on large followee lists
- Login check uses /friendships/{ds_user_id}/following/ (works reliably)
- Store own_user_id from cookies to avoid extra API call
- Skip separate user info fetch
- /users/self/info/ for profile info (not /accounts/current_user/)
- /friendships/{user_id}/following/ for followees list
- Added own_user_id fetch before followees
- Better debug logging for response structure
instaloader blocked by Instagram GraphQL 403. Using mobile API instead:
- i.instagram.com/api/v1 endpoints (same as Android app)
- Direct cookie loading from cookies.txt
- Stories, posts, albums, videos
- Random delays between requests
- Removed instaloader dependency, using requests directly
- iPhone Safari user-agent + X-IG-App-ID header
- 2-6s random delay between profile checks
- 1-3s delay between media downloads
- RateController for built-in throttling
- Try/except per followee to not stop on errors
- Add _verify_session() to check profile exists after loading session
- Skip session files from wrong accounts
- Clear cookies before trying next auth method
- Try instaloader session file first
- Then cookies.txt (Mozilla format from browser extension)
- Then cookies.json (from browser extensions)
- Direct login as last resort with clear instructions
- aiogram 3 bot with commands /start /check /status /stop
- InstagramMonitor: periodic check of followees stories and posts
- Docker deployment with docker-compose
- State tracking to avoid duplicate sends
- Auto-cleanup of old media files