feat(core): node veth idempotency, multi-node cdp ports, brain last ids persistence, and pulse interval variable
This commit is contained in:
+58
-2
@@ -135,10 +135,64 @@ def cmd_login_activity(port):
|
||||
section = body[idx:idx+1500] if idx >= 0 else ""
|
||||
return {"where_logged_in": section}
|
||||
|
||||
def cmd_link_instagram(agent, port):
|
||||
"""Automate Meta Accounts Center linking flow and second-click OAuth handoff."""
|
||||
import websocket
|
||||
tab = get_ac_tab(port)
|
||||
ws = websocket.create_connection(tab["webSocketDebuggerUrl"], timeout=15)
|
||||
try:
|
||||
# Step 1: Navigate to manage accounts
|
||||
ws.send(json.dumps({"id": 1, "method": "Page.navigate", "params": {"url": f"{AC_BASE}/manage/"}}))
|
||||
ws.recv()
|
||||
time.sleep(3)
|
||||
|
||||
# Step 2: Look for 'Add profiles and devices' button or check if already linked
|
||||
expr_find_add = """(() => {
|
||||
const btns = [...document.querySelectorAll("div[role='button'], button, a")];
|
||||
const addBtn = btns.find(b => /add profiles|add accounts/i.test((b.innerText||"").trim()));
|
||||
if (addBtn) {
|
||||
addBtn.click();
|
||||
return {status: "clicked_add", text: addBtn.innerText};
|
||||
}
|
||||
return {status: "no_add_button"};
|
||||
})()"""
|
||||
ws.send(json.dumps({"id": 2, "method": "Runtime.evaluate", "params": {"expression": expr_find_add, "returnByValue": True}}))
|
||||
res2 = json.loads(ws.recv()).get("result", {}).get("result", {}).get("value", {})
|
||||
time.sleep(3)
|
||||
|
||||
# Step 3: Check dialog / popup for Instagram option or FXCAL handoff
|
||||
expr_handle_dialog = """(() => {
|
||||
const btns = [...document.querySelectorAll("div[role='button'], button, a")];
|
||||
// Check for Add Instagram button or Continue/Confirm
|
||||
const igBtn = btns.find(b => /instagram/i.test((b.innerText||"").trim()) && /add|connect/i.test((b.innerText||"").trim()));
|
||||
if (igBtn) {
|
||||
igBtn.click();
|
||||
return {status: "clicked_instagram_option"};
|
||||
}
|
||||
const confirmBtn = btns.find(b => /continue|confirm|yes, finish/i.test((b.innerText||"").trim()));
|
||||
if (confirmBtn) {
|
||||
confirmBtn.click();
|
||||
return {status: "clicked_confirm", text: confirmBtn.innerText};
|
||||
}
|
||||
return {status: "dialog_scanned", current_url: window.location.href};
|
||||
})()"""
|
||||
ws.send(json.dumps({"id": 3, "method": "Runtime.evaluate", "params": {"expression": expr_handle_dialog, "returnByValue": True}}))
|
||||
res3 = json.loads(ws.recv()).get("result", {}).get("result", {}).get("value", {})
|
||||
time.sleep(2)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"step1_add": res2,
|
||||
"step2_dialog": res3,
|
||||
"current_url": tab.get("url")
|
||||
}
|
||||
finally:
|
||||
ws.close()
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
if len(sys.argv) < 3:
|
||||
print(__doc__.strip().split("\n")[0])
|
||||
print("Usage: meta-acct.py <list-linked|security-status|login-activity> <agent>")
|
||||
print("Usage: meta-acct.py <list-linked|security-status|login-activity|link-instagram> <agent>")
|
||||
sys.exit(2)
|
||||
cmd, agent = sys.argv[1], sys.argv[2]
|
||||
port = cdp_port(agent)
|
||||
@@ -149,6 +203,8 @@ def main():
|
||||
out = cmd_security_status(port)
|
||||
elif cmd == "login-activity":
|
||||
out = cmd_login_activity(port)
|
||||
elif cmd == "link-instagram":
|
||||
out = cmd_link_instagram(agent, port)
|
||||
else:
|
||||
raise SystemExit(f"meta-acct: unknown command '{cmd}'")
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user