Skip to content

Commit aac7531

Browse files
committed
feat: Enhance access token extraction to handle challenge pages automatically and improve type safety for media URL extraction
1 parent e9b6d8c commit aac7531

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/metaai_api/main.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,14 @@ def extract_access_token_from_page(self) -> Optional[str]:
174174
"""
175175
Extract the accessToken from meta.ai page HTML.
176176
This is the actual OAuth token needed for image upload, NOT the ecto_1_sess cookie.
177+
Handles challenge pages automatically.
177178
178179
Returns:
179180
str: The accessToken in format "ecto1:..." or None if extraction fails
180181
"""
181182
try:
182183
import re
184+
from metaai_api.utils import detect_challenge_page, handle_meta_ai_challenge
183185

184186
# Fetch meta.ai page with cookies
185187
cookie_header = self.get_cookie_header()
@@ -190,6 +192,28 @@ def extract_access_token_from_page(self) -> Optional[str]:
190192
}
191193

192194
response = self.session.get("https://meta.ai", headers=headers)
195+
196+
# Check for challenge page BEFORE calling raise_for_status
197+
challenge_url = detect_challenge_page(response.text)
198+
if challenge_url:
199+
logging.warning("⚠️ Meta AI returned a challenge page during token extraction. Attempting to handle it...")
200+
cookies_dict = self.get_cookies_dict()
201+
if handle_meta_ai_challenge(self.session, challenge_url=challenge_url, cookies_dict=cookies_dict):
202+
# Update cookies with rd_challenge if it was extracted
203+
if "rd_challenge" in cookies_dict:
204+
self.cookies["rd_challenge"] = cookies_dict["rd_challenge"]
205+
logging.info(f"[TOKEN] Saved rd_challenge: {cookies_dict['rd_challenge'][:50]}...")
206+
207+
# Retry after handling challenge
208+
logging.info("🔄 Re-fetching page after challenge resolution...")
209+
cookie_header = self.get_cookie_header()
210+
headers["cookie"] = cookie_header
211+
response = self.session.get("https://meta.ai", headers=headers)
212+
else:
213+
logging.error("❌ Failed to handle challenge page in extract_access_token_from_page.")
214+
return None
215+
216+
# Now check status after challenge handling
193217
response.raise_for_status()
194218

195219
# Extract accessToken from page HTML using regex (handles escaped quotes)
@@ -890,11 +914,13 @@ def get_cookies(self) -> dict:
890914
headers=headers,
891915
)
892916

917+
# Initialize cookies_dict before challenge check
918+
cookies_dict: Dict[str, str] = {}
919+
893920
# Check for challenge page
894921
challenge_url = detect_challenge_page(response.text)
895922
if challenge_url:
896923
logging.warning("⚠️ Meta AI returned a challenge page during get_cookies. Attempting to handle it...")
897-
cookies_dict = {}
898924
if fb_session:
899925
cookies_dict = {"abra_sess": fb_session["abra_sess"]}
900926
if handle_meta_ai_challenge(session, challenge_url=challenge_url, cookies_dict=cookies_dict):
@@ -1024,10 +1050,10 @@ def generate_image_new(
10241050
**kwargs
10251051
)
10261052

1027-
# Extract image URLs
1053+
# Extract image URLs with type safety
10281054
image_urls = response.get('images') or self.generation_api.extract_media_urls(response)
1029-
if image_urls and isinstance(image_urls[0], dict):
1030-
image_urls = [img.get('url') for img in image_urls if img.get('url')]
1055+
if image_urls and isinstance(image_urls, list) and len(image_urls) > 0 and isinstance(image_urls[0], dict):
1056+
image_urls = [img.get('url') for img in image_urls if isinstance(img, dict) and img.get('url')]
10311057

10321058
return {
10331059
"success": True,
@@ -1073,10 +1099,10 @@ def generate_video_new(
10731099
**kwargs
10741100
)
10751101

1076-
# Extract video URLs
1102+
# Extract video URLs with type safety
10771103
video_urls = response.get('videos') or self.generation_api.extract_media_urls(response)
1078-
if video_urls and isinstance(video_urls[0], dict):
1079-
video_urls = [vid.get('url') for vid in video_urls if vid.get('url')]
1104+
if video_urls and isinstance(video_urls, list) and len(video_urls) > 0 and isinstance(video_urls[0], dict):
1105+
video_urls = [vid.get('url') for vid in video_urls if isinstance(vid, dict) and vid.get('url')]
10801106

10811107
return {
10821108
"success": True,

0 commit comments

Comments
 (0)