diff --git a/bin/twitter.ml b/bin/twitter.ml index 6e7fd54..3b94451 100644 --- a/bin/twitter.ml +++ b/bin/twitter.ml @@ -2,48 +2,78 @@ open Pusk.Net open Pusk.Utils (* open Twostep *) -let login_twitter ctx username password _secret = - (* Navigate to login page and wait for page loaded*) - ignore (navigate ctx.session_id "https://twitter.com/i/flow/login"); - Unix.sleep 5; +type credentials = + { username : string + ; password : string + } + +let inject_username session_id way creds = (* Find username input *) + let xpath = + match way with + | 0 -> + XPath + "/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input" + | 1 -> + XPath + "/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[2]/label/div/div[2]/div/input" + | _ -> raise (Any "Unknown page to use for injecting username") + in let input_username = - match - find - ctx.session_id - (XPath - "/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input") - with - | [] -> raise (Any "Username input not found") + match find session_id xpath with + | [] -> raise (Any (fmt "Username input not found (page %d)" way)) | _ as l -> if List.length l > 1 then raise (Any "Too many element found as the username input") else List.nth l 0 in (* Insert the username *) - send_keys ctx.session_id input_username username; + send_keys session_id input_username creds.username; Unix.sleep 1; - send_keys ctx.session_id input_username Keys.return; - Unix.sleep 3; - (* Find password input *) + send_keys session_id input_username Keys.return; + Unix.sleep 3 +;; + +let rec _inject_password session_id creds try_count = + if try_count == 0 then raise (Any "Password input not found"); let input_password = match find - ctx.session_id + session_id (XPath "/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div/div[3]/div/label/div/div[2]/div[1]/input") with - | [] -> raise (Any "Password input not found") + | [] -> + (* Retry to inject username with the second page *) + inject_username session_id 1 creds; + _inject_password session_id creds (try_count - 1); + None | _ as l -> if List.length l > 1 then raise (Any "Too many element found as the password input") - else List.nth l 0 + else Some (List.nth l 0) in - (* Insert password *) - send_keys ctx.session_id input_password password; - Unix.sleep 1; - send_keys ctx.session_id input_password Keys.return; + match input_password with + | Some input -> + (* Insert password *) + send_keys session_id input creds.password; + Unix.sleep 1; + send_keys session_id input Keys.return; + Unix.sleep 5 + | None -> () +;; + +let inject_password session_id creds = _inject_password session_id creds 1 + +let login_twitter ctx username password _secret = + (* Navigate to login page and wait for page loaded*) + ignore (navigate ctx.session_id "https://twitter.com/i/flow/login"); Unix.sleep 5; + let creds = { username; password } in + (* Insert the username *) + inject_username ctx.session_id 0 creds; + (* Find password input *) + inject_password ctx.session_id creds; (* Detection of 2FA *) (* TODO *) (* Generate code if possible *)