v0.4: background reads, JS-state login signals, blind sleeps dropped
get_or_open_tab(activate=True) — added, not replaced. Read paths pass activate=False; post flows keep the foreground for dialogs and file inputs. check_login moved off DOM signals onto session state: fb c_user, ig/threads ds_user_id, twitter twid, yt ytcfg.LOGGED_IN. Three platforms were reporting OUT on a signed-in account because their composer never mounts in a hidden tab. The fixed sleep(4)/sleep(5) before each check goes with them — every signal reads present the moment navigate() returns. Unreadable cookies raise instead of returning False: "cannot tell" is not "signed out". tiktok untouched and still activated — it reported visibilityState "visible" from a sibling-activated tab, so it has never been read from a genuine background. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+13
-6
@@ -103,18 +103,25 @@ async def _wait_for_post_complete(tab, timeout=30.0):
|
||||
|
||||
|
||||
async def check_login(cdp_client):
|
||||
tab, reused = await cdp_client.get_or_open_tab(S["url"], "threads.com")
|
||||
tab, reused = await cdp_client.get_or_open_tab(S["url"], "threads.com", activate=False)
|
||||
if reused:
|
||||
await tab.eval("window.onbeforeunload = null")
|
||||
await tab.navigate(S["url"])
|
||||
await asyncio.sleep(4)
|
||||
if await tab.exists(S["login_marker"]):
|
||||
return False
|
||||
return await tab.eval(
|
||||
"!!(document.querySelector('[placeholder=\"What\\'s new?\"]')"
|
||||
" || [...document.querySelectorAll('span,div')]"
|
||||
".find(e => e.innerText && e.innerText.trim() === 'What\\'s new?'))"
|
||||
# JS state, not the "What's new?" composer: that composer never mounts in a
|
||||
# backgrounded tab, so a signed-in account read as signed out (measured
|
||||
# 2026-09-12 — DOM signal False while the session cookie was right there).
|
||||
# Threads runs on the Instagram session, hence ds_user_id.
|
||||
state = await tab.eval(
|
||||
"(() => { const m = document.cookie.match(/(?:^|;\\s*)ds_user_id=(\\d+)/);"
|
||||
" return m ? 'in:' + m[1] : (document.cookie ? 'out' : 'unavailable'); })()"
|
||||
)
|
||||
if state.startswith("in:"):
|
||||
return True
|
||||
if state == "out":
|
||||
return False
|
||||
raise CDPError("threads: no cookies readable on threads.com — cannot tell signed-in from signed-out")
|
||||
|
||||
|
||||
async def get_notifications(cdp_client, count=10):
|
||||
|
||||
Reference in New Issue
Block a user