298 lines
11 KiB
PHP
298 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Jobs\ProcessNews;
|
|
use App\Jobs\ProcessTweet;
|
|
use App\Models\Account;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Webklex\PHPIMAP\ClientManager;
|
|
|
|
class AccountController extends Controller
|
|
{
|
|
public function login($id)
|
|
{
|
|
$user = Account::find($id);
|
|
|
|
try{
|
|
$username = $user->name;
|
|
$password = $user->password;
|
|
$email = $user->rambler_email;
|
|
$rambler_password = $user->rambler_password;
|
|
|
|
$proxy = 'http://xtjnmwvl-'.$id.':lp7iv1lq9glu@p.webshare.io:80';
|
|
|
|
// Clés et jetons de Twitter
|
|
$TW_CONSUMER_KEY = '3nVuSoBZnx6U4vzUxf5w';
|
|
$TW_CONSUMER_SECRET = 'Bcs59EFbbsdF6Sl9Ng71smgStWEGwXXKSjYvPVt7qys';
|
|
$TW_ANDROID_BASIC_TOKEN = 'Basic ' . base64_encode("$TW_CONSUMER_KEY:$TW_CONSUMER_SECRET");
|
|
|
|
// Requête pour obtenir le bearer token
|
|
$response = Http::withHeaders([
|
|
'Authorization' => $TW_ANDROID_BASIC_TOKEN,
|
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
])->asForm()->post('https://api.twitter.com/oauth2/token', [
|
|
'grant_type' => 'client_credentials',
|
|
]);
|
|
|
|
$bearerToken = collect($response->json())->implode(' ');
|
|
|
|
// Requête pour obtenir le guest token
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.twitter.com/1.1/guest/activate.json',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Authorization: ' . $bearerToken
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
$reponse = json_decode($response, true);
|
|
$guestToken = $reponse['guest_token'];
|
|
|
|
// Configuration des en-têtes pour les futures requêtes
|
|
$twitterHeaders = [
|
|
'Authorization' => $bearerToken,
|
|
'User-Agent' => 'TwitterAndroid/10.46.0-release.0 (310460000-r-0) Android+SDK+built+for+x86/11 (unknown;Android+SDK+built+for+x86;Android;sdk_phone_x86;0;;1;2013)',
|
|
'x-twitter-api-version' => '5',
|
|
'x-twitter-client' => 'TwitterAndroid',
|
|
'x-twitter-client-version' => '10.46.0-release.0',
|
|
'x-twitter-active-user' => 'yes',
|
|
'os-version' => '30',
|
|
'x-twitter-client-language' => 'en-US',
|
|
'x-attest-token' => 'no_token',
|
|
'X-Guest-Token' => $guestToken,
|
|
];
|
|
|
|
// Initialisation de la session avec Laravel HTTP pour le flux de connexion
|
|
// Étape 1 : Commencer le flux de connexion
|
|
$task1 = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json?flow_name=login&api_version=1&known_device_token=', [
|
|
'input_flow_data' => [
|
|
'country_code' => null,
|
|
'flow_context' => [
|
|
'start_location' => [
|
|
'location' => 'deeplink',
|
|
],
|
|
],
|
|
'requested_variant' => null,
|
|
'target_user_id' => 0,
|
|
],
|
|
]);
|
|
|
|
// Stockage de l'en-tête 'att' pour les futures requêtes
|
|
$twitterHeaders['att'] = $task1->header('att');
|
|
|
|
sleep(5);
|
|
\DB::reconnect();
|
|
|
|
// Étape 2 : Saisie du nom d'utilisateur
|
|
$task2 = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task1->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_text' => [
|
|
'text' => $username,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginEnterUserIdentifier',
|
|
],
|
|
],
|
|
]);
|
|
|
|
sleep(5);
|
|
|
|
if ($task2->json()['subtasks'][0]['subtask_id'] === 'LoginEnterAlternateIdentifierSubtask') {
|
|
$task2bis = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task2->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_text' => [
|
|
'text' => $email,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginEnterAlternateIdentifierSubtask',
|
|
],
|
|
],
|
|
]);
|
|
|
|
$task2 = $task2bis;
|
|
}
|
|
|
|
sleep(5);
|
|
\DB::reconnect();
|
|
|
|
// Étape 3 : Saisie du mot de passe
|
|
$task3 = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task2->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_password' => [
|
|
'password' => $password,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginEnterPassword',
|
|
],
|
|
],
|
|
]);
|
|
|
|
if ($task3->json()['subtasks'][0]['subtask_id'] === 'LoginAcid') {
|
|
sleep(5);
|
|
if(isset($task3->json()['subtasks'][0]['enter_text']['hint_text'])){
|
|
$code = $this->getCodeFromLastEmail($email, $rambler_password);
|
|
$task3bis = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task3->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_text' => [
|
|
'text' => $code,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginAcid',
|
|
],
|
|
],
|
|
]);
|
|
}else{
|
|
$task3bis = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task3->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_text' => [
|
|
'text' => $email,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginAcid',
|
|
],
|
|
],
|
|
]);
|
|
}
|
|
$task3 = $task3bis;
|
|
}
|
|
|
|
if($task3->json()['subtasks'][0]['subtask_id'] === 'LoginEnterOtp'){
|
|
$code = $this->getCodeFromLastEmail($email, $rambler_password);
|
|
$task3bis = Http::withOptions([
|
|
'proxy' => $proxy
|
|
])->withHeaders($twitterHeaders)->post('https://api.twitter.com/1.1/onboarding/task.json', [
|
|
'flow_token' => $task3->json()['flow_token'],
|
|
'subtask_inputs' => [
|
|
[
|
|
'enter_text' => [
|
|
'text' => $code,
|
|
'link' => 'next_link',
|
|
],
|
|
'subtask_id' => 'LoginEnterOtp',
|
|
],
|
|
],
|
|
]);
|
|
$task3 = $task3bis;
|
|
}
|
|
|
|
if($task3->json()['subtasks']['0']['subtask_id'] == 'LoginSuccessSubtask' ){
|
|
$user->update([
|
|
'oauth_token' => $task3->json()['subtasks']['0']['open_account']['oauth_token'],
|
|
'oauth_token_secret' => $task3->json()['subtasks']['0']['open_account']['oauth_token_secret'],
|
|
'known_device_token' => $task3->json()['subtasks']['0']['open_account']['known_device_token'],
|
|
'enable' => true,
|
|
]);
|
|
|
|
return true;
|
|
}else{
|
|
return false;
|
|
}
|
|
}catch (\Exception $e){
|
|
return false;
|
|
}
|
|
|
|
}
|
|
private function getCodeFromLastEmail($email, $password)
|
|
{
|
|
// Attendre 15 secondes avant de vérifier les emails
|
|
sleep(10);
|
|
|
|
// Configurer le client IMAP de manière dynamique
|
|
$clientManager = new ClientManager();
|
|
|
|
$client = $clientManager->make([
|
|
'host' => 'imap.rambler.ru',
|
|
'port' => '993',
|
|
'encryption' => 'ssl',
|
|
'validate_cert' => true,
|
|
'username' => $email,
|
|
'password' => $password,
|
|
'protocol' => 'imap'
|
|
]);
|
|
|
|
// Se connecter au compte
|
|
$client->connect();
|
|
|
|
// Sélectionner la boîte de réception
|
|
$folder = $client->getFolder('INBOX');
|
|
|
|
// Récupérer le dernier email de l'expéditeur "verify@x.com"
|
|
$messages = $folder->messages()->all()->get();
|
|
$count = count($messages);
|
|
$message = $messages[$count - 1];
|
|
|
|
if ($message) {
|
|
// Vérifier le titre de l'email
|
|
$subject = $message->getSubject();
|
|
|
|
// Chercher le code dans le sujet
|
|
if (preg_match('/Your X confirmation code is (\w+)/', $subject, $matches)) {
|
|
return $matches[1]; // Retourner le code trouvé dans le titre
|
|
}
|
|
|
|
// Si aucun code trouvé dans le sujet, vérifier le corps du mail
|
|
$body = $message->getTextBody();
|
|
if (preg_match('/\b(\d{6})\b/', $body, $matches)) {
|
|
return $matches[1]; // Retourner le code trouvé dans le corps
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function tweetnews()
|
|
{
|
|
// Vérifier si la queue est vide (en fonction de votre driver)
|
|
$queue = Queue::getDefaultDriver(); // Par défaut, c'est 'default'
|
|
|
|
$jobsCount = Queue::size($queue);
|
|
|
|
if ($jobsCount === 0) {
|
|
|
|
$accounts = Account::where('enable', true)->get();
|
|
|
|
foreach($accounts as $user){
|
|
ProcessNews::dispatch($user->id);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|