diff --git a/app/Http/Controllers/APIController.php b/app/Http/Controllers/APIController.php index fc1693d..8a847a6 100644 --- a/app/Http/Controllers/APIController.php +++ b/app/Http/Controllers/APIController.php @@ -129,26 +129,95 @@ class APIController extends Controller ]); } - public function follow($user, $follow) + public function follow($user, $tweetid) { $stack = $this->Oauth1($user); // Créer le client Guzzle avec le handler stack $client = new Client([ - 'base_uri' => 'https://api.twitter.com/1.1/', + 'base_uri' => 'https://api.twitter.com/graphql/', 'handler' => $stack, 'proxy' => [ 'http' => 'http://xtjnmwvl-'.$user->id.':lp7iv1lq9glu@p.webshare.io:80', ] ]); + $params = [ + "variables" => [ + "referrer" => "profile", + "includeTweetImpression" => true, + "includeHasBirdwatchNotes" => false, + "isReaderMode" => false, + "includeEditPerspective" => false, + "includeEditControl" => true, + "focalTweetId" => $tweetid, + "includeCommunityTweetRelationship" => true, + "includeTweetVisibilityNudge" => true, + ], + "features" => [ + "longform_notetweets_inline_media_enabled" => true, + "super_follow_badge_privacy_enabled" => true, + "longform_notetweets_rich_text_read_enabled" => true, + "super_follow_user_api_enabled" => true, + "unified_cards_ad_metadata_container_dynamic_card_content_query_enabled" => true, + "super_follow_tweet_api_enabled" => true, + "articles_api_enabled" => true, + "android_graphql_skip_api_media_color_palette" => true, + "creator_subscriptions_tweet_preview_api_enabled" => true, + "freedom_of_speech_not_reach_fetch_enabled" => true, + "tweetypie_unmention_optimization_enabled" => true, + "longform_notetweets_consumption_enabled" => true, + "subscriptions_verification_info_enabled" => true, + "blue_business_profile_image_shape_enabled" => true, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled" => true, + "immersive_video_status_linkable_timestamps" => true, + "super_follow_exclusive_tweet_notifications_enabled" => true, + ], + ]; // Effectuer la requête POST avec OAuth et les en-têtes personnalisés - $res = $client->post('friendships/create.json?screen_name='.$follow.'&follow=true', [ + $res = $client->get('NAHO_rBo3Yf1hBXROp7Msg/ConversationTimelineV2', [ 'headers' => $this->twitterHeaders, // Ajouter les en-têtes ici - 'auth' => 'oauth' // Assurez-vous que l'authentification OAuth est incluse + 'auth' => 'oauth', + 'json' => $params ]); + // Décoder le JSON en tableau PHP + $data = json_decode($res->getBody()->getContents(), true); + + // Initialiser un tableau pour stocker les IDs + $userMentionIds = []; + + // Extraire les IDs des mentions uniquement pour la première instruction et la première entrée + if (isset($data['data']['timeline_response']['instructions'][0]['entries'][0]['content']['content']['tweetResult']['result']['legacy']['entities']['user_mentions'])) { + $userMentionIds[] = $data['data']['timeline_response']['instructions'][0]['entries'][0]['content']['content']['tweetResult']['result']['legacy']['user_id_str']; + $mentions = $data['data']['timeline_response']['instructions'][0]['entries'][0]['content']['content']['tweetResult']['result']['legacy']['entities']['user_mentions']; + foreach ($mentions as $mention) { + $userMentionIds[] = $mention['id_str']; + } + } + + $userMentionIds = array_unique($userMentionIds); + + foreach ($userMentionIds as $mention) { + $stack = $this->Oauth1($user); + + $client = new Client([ + 'base_uri' => 'https://api.twitter.com/1.1/', + 'handler' => $stack, + 'proxy' => [ + 'http' => 'http://xtjnmwvl-'.$user->id.':lp7iv1lq9glu@p.webshare.io:80', + ] + ]); + + + // Effectuer la requête POST avec OAuth et les en-têtes personnalisés + $res = $client->post('friendships/create.json?user_id='.$mention.'&ext=mediaRestrictions,altText,mediaStats,mediaColor,info360,highlightedLabel,unmentionInfo,editControl,previousCounts,limitedActionResults,superFollowMetadata&send_error_codes=true&handles_challenges=1', [ + 'headers' => $this->twitterHeaders, // Ajouter les en-têtes ici + 'auth' => 'oauth' // Assurez-vous que l'authentification OAuth est incluse + ]); + sleep(15); + } } public function like($user, $tweetid) @@ -259,7 +328,7 @@ class APIController extends Controller $unred = json_decode($res->getBody()->getContents(), true); // L'URL des deux liens - $url = 'https://myx.ovh/nova/resources/accounts/'.$user->id; + $url = 'https://myx.ovh/accounts/'.$user->id; $keyboard = [ 'inline_keyboard' => [ @@ -579,6 +648,7 @@ class APIController extends Controller 'text' => $text, ]); } + $stack = $this->Oauth1($user); } } diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index f8e71cf..4809024 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -3,9 +3,9 @@ namespace App\Http\Controllers; use App\Jobs\ProcessNews; -use App\Jobs\ProcessTweet; use App\Models\Account; -use Illuminate\Support\Facades\Cache; +use Artesaos\SEOTools\Facades\SEOTools; +use foroco\BrowserDetection; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\DB; @@ -292,5 +292,33 @@ class AccountController extends Controller } } + public function all() + { + $accounts = Account::where('enable', true)->get(); -} \ No newline at end of file + $browser = new BrowserDetection(); + $useragent = $_SERVER['HTTP_USER_AGENT']; + + $browser = $browser->getOS($useragent); + + SEOTools::setTitle('Liste des comptes'); + + return view('accounts.index', compact('accounts', 'browser')); + } + + public function account($id) + { + $account = Account::find($id); + + $browser = new BrowserDetection(); + $useragent = $_SERVER['HTTP_USER_AGENT']; + + $browser = $browser->getOS($useragent); + + SEOTools::setTitle('Compte '.$account->name); + + return view('accounts.view', compact('account', 'browser')); + } + + +} diff --git a/app/Http/Controllers/ContestController.php b/app/Http/Controllers/ContestController.php index eb655ec..83adecd 100644 --- a/app/Http/Controllers/ContestController.php +++ b/app/Http/Controllers/ContestController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Models\Block; use App\Models\Contest; +use Artesaos\SEOTools\Facades\SEOTools; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; @@ -437,65 +438,72 @@ class ContestController extends Controller } private function getDate($string) { - // Pattern pour détecter les dates au format JJ/MM ou JJ.MM - $pattern_jjmm = '/\b(\d{1,2})(\/|\.)\d{1,2}\b/'; + // Pattern pour détecter les dates au format JJ/MM ou JJ.MM + $pattern_jjmm = '/\b(\d{1,2})(\/|\.)\d{1,2}\b/'; - // Pattern pour détecter les dates du style "1 août" (ou autre mois en français) - $mois_fr = array( - 'janvier', 'février', 'mars', 'avril', 'mai', 'juin', - 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre' - ); - $pattern_jj_mois_fr = '/\b(\d{1,2}) (' . implode('|', $mois_fr) . ')\b/i'; + // Pattern pour détecter les dates du style "1 août" (ou autre mois en français) + $mois_fr = array( + 'janvier', 'février', 'mars', 'avril', 'mai', 'juin', + 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre' + ); + $pattern_jj_mois_fr = '/\b(\d{1,2}) (' . implode('|', $mois_fr) . ')\b/i'; - // Stocker les correspondances dans un tableau - $correspondances = []; + // Stocker les correspondances dans un tableau + $correspondances = []; - // Chercher les dates au format JJ/MM ou JJ.MM - if (preg_match_all($pattern_jjmm, $string, $matches)) { - $correspondances = array_merge($correspondances, $matches[0]); - } - - // Chercher les dates du style "1 août" (ou autre mois en français) - if (preg_match_all($pattern_jj_mois_fr, $string, $matches)) { - // Convertir le mois en format numérique (1 pour janvier, 2 pour février, etc.) - $mois_numerique = array_flip($mois_fr); - foreach ($matches[2] as $index => $mois) { - $matches[0][$index] = $matches[1][$index] . '/' . str_pad($mois_numerique[strtolower($mois)] + 1, 2, '0', STR_PAD_LEFT); - } - $correspondances = array_merge($correspondances, $matches[0]); - } - - // Vérifier s'il y a des dates détectées - if (empty($correspondances)) { - return ""; // Retourne une chaîne vide si aucune date n'est trouvée - } - - // Récupérer la dernière date détectée - $derniere_date = end($correspondances); - - // Convertir la dernière date au format "Y-m-d" (année-mois-jour) - if (strpos($derniere_date, '/') !== false) { - // Format JJ/MM - list($jour, $mois) = explode('/', $derniere_date); - $annee = date('Y'); - } elseif (strpos($derniere_date, '.') !== false) { - // Format JJ.MM - list($jour, $mois) = explode('.', $derniere_date); - $annee = date('Y'); - } else { - return ""; // Cas inattendu (ne devrait pas se produire) - } - - // Convertir en date avec gestion des erreurs (ex. : février 30) - try { - $date_convertie = date('Y-m-d', strtotime("$annee-$mois-$jour")); - } catch (Exception $e) { - return ""; // Retourne une chaîne vide si la conversion échoue - } - - return $date_convertie; + // Chercher les dates au format JJ/MM ou JJ.MM + if (preg_match_all($pattern_jjmm, $string, $matches)) { + $correspondances = array_merge($correspondances, $matches[0]); } + // Chercher les dates du style "1 août" (ou autre mois en français) + if (preg_match_all($pattern_jj_mois_fr, $string, $matches)) { + // Convertir le mois en format numérique (1 pour janvier, 2 pour février, etc.) + $mois_numerique = array_flip($mois_fr); + foreach ($matches[2] as $index => $mois) { + $matches[0][$index] = $matches[1][$index] . '/' . str_pad($mois_numerique[strtolower($mois)] + 1, 2, '0', STR_PAD_LEFT); + } + $correspondances = array_merge($correspondances, $matches[0]); + } + + // Vérifier s'il y a des dates détectées + if (empty($correspondances)) { + return ""; // Retourne une chaîne vide si aucune date n'est trouvée + } + + // Si plusieurs dates sont trouvées, trier les dates et récupérer la dernière + usort($correspondances, function ($a, $b) { + $dateA = strtotime($a); + $dateB = strtotime($b); + return $dateB - $dateA; // Tri décroissant + }); + + // Récupérer la dernière date détectée après le tri + $derniere_date = $correspondances[0]; + + // Convertir la dernière date au format "Y-m-d" (année-mois-jour) + if (strpos($derniere_date, '/') !== false) { + // Format JJ/MM + list($jour, $mois) = explode('/', $derniere_date); + $annee = date('Y'); + } elseif (strpos($derniere_date, '.') !== false) { + // Format JJ.MM + list($jour, $mois) = explode('.', $derniere_date); + $annee = date('Y'); + } else { + return ""; // Cas inattendu (ne devrait pas se produire) + } + + // Convertir en date avec gestion des erreurs (ex. : février 30) + try { + $date_convertie = date('Y-m-d', strtotime("$annee-$mois-$jour")); + } catch (Exception $e) { + return ""; // Retourne une chaîne vide si la conversion échoue + } + + return $date_convertie; +} + private function getTwitterDate($text) { // Utilisez une expression régulière pour extraire toutes les dates @@ -503,8 +511,15 @@ class ContestController extends Controller preg_match_all($pattern, $text, $matches); if (!empty($matches[1])) { - // Récupérer la dernière date trouvée - $lastDateString = end($matches[1]); + // Trier les dates pour obtenir la plus récente (dernière) + usort($matches[1], function ($a, $b) { + $dateA = Carbon::createFromFormat('M d, Y', $a); + $dateB = Carbon::createFromFormat('M d, Y', $b); + return $dateB->timestamp - $dateA->timestamp; // Tri décroissant + }); + + // Récupérer la dernière date trouvée après le tri + $lastDateString = $matches[1][0]; // Analyse de la date $date = Carbon::createFromFormat('M d, Y', $lastDateString); @@ -518,4 +533,15 @@ class ContestController extends Controller return Carbon::now()->addDays(1)->format('Y-m-d'); } } + + public function all() + { + $contests = Contest::where('fin', '>=', Carbon::now()->format('Y-m-d'))->where('participated', 0)->where('enable', 1)->paginate(20); + + $count = Contest::where('fin', '>=', Carbon::now()->format('Y-m-d'))->where('participated', 0)->where('enable', 1)->count(); + + SEOTools::setTitle('Les concours à venir'); + + return view('contests', compact('contests', 'count')); + } } \ No newline at end of file diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index dfd2f7e..c91063b 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -24,4 +24,4 @@ class HomeController extends Controller return view('history', compact('contests')); } -} +} \ No newline at end of file diff --git a/app/Jobs/ProcessNews.php b/app/Jobs/ProcessNews.php index 33b6e6b..5ee9b2a 100644 --- a/app/Jobs/ProcessNews.php +++ b/app/Jobs/ProcessNews.php @@ -12,6 +12,8 @@ class ProcessNews implements ShouldQueue { use Queueable; + public $timeout = 300; + private $authid; /** @@ -32,6 +34,11 @@ class ProcessNews implements ShouldQueue $user = Account::find($this->authid); try{ + + //On check si le compte est ok + $API->check($user); + + //On check les notifs $API->unread($user); if (Cache::has('news')) { @@ -50,14 +57,14 @@ class ProcessNews implements ShouldQueue foreach ($selectedArticles as $article) { $tweetid = $article['conversation_id_str']; $API->retweet($user, $tweetid); - sleep(15); + sleep(30); } } }catch (Exception $exception){ $text = "Le compte Twitter " . $user->name . " : " . $exception->getMessage(); // L'URL des deux liens - $url = 'https://myx.ovh/nova/resources/accounts/'.$user->id; + $url = 'https://myx.ovh/accounts/'.$user->id; $keyboard = [ 'inline_keyboard' => [ @@ -78,4 +85,4 @@ class ProcessNews implements ShouldQueue ]); } } -} +} \ No newline at end of file diff --git a/app/Jobs/ProcessTweet.php b/app/Jobs/ProcessTweet.php index 8de4e4e..4f43632 100644 --- a/app/Jobs/ProcessTweet.php +++ b/app/Jobs/ProcessTweet.php @@ -16,7 +16,7 @@ class ProcessTweet implements ShouldQueue { use Queueable; - public $timeout = 90; + public $timeout = 900; public $tries = 1; private $id; @@ -54,10 +54,11 @@ class ProcessTweet implements ShouldQueue $hashtags = $this->getHashtags($text); - $follows = $this->getFollows($text); - $API = new APIController(); + //On check si le compte est ok + $API->check($user); + //On check les notifs $API->unread($user); @@ -71,7 +72,6 @@ class ProcessTweet implements ShouldQueue //On reply $API->reply($user, $contest->tweetid, $retweet); - sleep(15); }elseif(isset($tweetcomment) && isset($tags)) { $comments = config('twitter.sentence_for_tag'); @@ -80,7 +80,6 @@ class ProcessTweet implements ShouldQueue //On reply $API->reply($user, $contest->tweetid, $retweet); - sleep(15); }elseif(isset($tweetspecial)){ @@ -88,7 +87,6 @@ class ProcessTweet implements ShouldQueue //On reply $API->reply($user, $contest->tweetid, $retweet); - sleep(15); }elseif(isset($tweetcomment)){ @@ -98,7 +96,6 @@ class ProcessTweet implements ShouldQueue //On reply $API->reply($user, $contest->tweetid, $retweet); - sleep(15); }elseif(isset($tags)){ @@ -106,22 +103,13 @@ class ProcessTweet implements ShouldQueue //On reply $API->reply($user, $contest->tweetid, $retweet); - sleep(15); } - - //On follow le créateur - $API->follow($user, $contest->screen); sleep(15); - - if(isset($follows)){ - foreach ($follows as $follow){ - //On folow les personnes demandées - $API->follow($user, $follow); - sleep(5); - } - } + //On follow + $API->follow($user, $contest->tweetid); + sleep(15); //On like si besoin preg_match("/LIKE/i", $text, $like); @@ -161,7 +149,7 @@ class ProcessTweet implements ShouldQueue $text = "Le compte Twitter " . $user->name . " : " . $exception->getMessage(); // L'URL des deux liens - $url = 'https://myx.ovh/nova/resources/accounts/'.$user->id; + $url = 'https://myx.ovh/accounts/'.$user->id; $keyboard = [ 'inline_keyboard' => [ @@ -258,27 +246,31 @@ class ProcessTweet implements ShouldQueue //On recherche si ça demande un tag $word_tags = config('twitter.word_tag'); $combined_regex = implode('|', array_map('preg_quote', $word_tags, array_fill(0, count($word_tags), '/'))); + $tags = collect(config('twitter.tags')); if (preg_match('/' . $combined_regex . '/i', $text, $matches)) { //On recherche si ça demande 1 tag $one_people_lists = config('twitter.one_people_list'); $combined_regex = implode('|', array_map('preg_quote', $one_people_lists, array_fill(0, count($one_people_lists), '/'))); if (preg_match('/' . $combined_regex . '/i', $text, $matches)) { - return '@chauchettes'; + $values = $tags->random(1); + return '@' . $values[0]; } //On recherche si ça demande 2 tags $two_people_lists = config('twitter.two_people_list'); $combined_regex = implode('|', array_map('preg_quote', $two_people_lists, array_fill(0, count($two_people_lists), '/'))); if (preg_match('/' . $combined_regex . '/i', $text, $matches)) { - return '@chauchettes @totorunior'; + $values = $tags->random(2); + return '@' . $values[0]. ' @' . $values[1]; } //On recherche si ça demande 3 tags ou plus $three_or_more_people_lists = config('twitter.three_or_more_people_list'); $combined_regex = implode('|', array_map('preg_quote', $three_or_more_people_lists, array_fill(0, count($three_or_more_people_lists), '/'))); if (preg_match('/' . $combined_regex . '/i', $text, $matches)) { - return '@chauchettes @totorunior @crakotte84'; + $values = $tags->random(3); + return '@' . $values[0]. ' @' . $values[1]. ' @' . $values[2]; } } } diff --git a/config/twitter.php b/config/twitter.php index c28f4c2..49a0f10 100644 --- a/config/twitter.php +++ b/config/twitter.php @@ -589,4 +589,21 @@ return [ 'freebets', 'rtbf' ], + + 'tags' => [ + "gl1tz_4ll", + 'daizy_dit1', + "sheison447179", + "TourisTourisk", + "ptitemo43", + "newrayane11292", + "huhu80fr", + "birezievfr", + 'malamomotic', + 'wilaxe8', + 'informilit13896', + 'quoteur69', + 'RipPony31340', + 'FollowPurf47871', + ], ]; diff --git a/resources/views/accounts/index.blade.php b/resources/views/accounts/index.blade.php new file mode 100644 index 0000000..7a89d97 --- /dev/null +++ b/resources/views/accounts/index.blade.php @@ -0,0 +1,82 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Liste des comptes actifs

+ +
+
+
+
+
+
+
+ + + + + + + + + + + + @foreach($accounts as $account) + + + + + + + + @endforeach + +
IDNomAccèsWebmailVoir
{{$account->id}}{{$account->name}} + @if(str_contains($browser['os_family'], 'android')) + + + + @else + + + + @endif + + + + + + + + +
+
+
+
+ @endsection + @section('js') + + + + + + + + + + + + + +@endsection diff --git a/resources/views/accounts/view.blade.php b/resources/views/accounts/view.blade.php new file mode 100644 index 0000000..15a30ee --- /dev/null +++ b/resources/views/accounts/view.blade.php @@ -0,0 +1,57 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

{{$account->name}}

+ +
+
+
+
+
+
+

+ ID: {{$account->id}} +

+

+ Nom: {{$account->name}} +

+

+ Accès: + @if(str_contains($browser['os_family'], 'android')) + + + + @else + + + + @endif +

+

+ Webmail: + + + +

+

+ Voir: + + + +

+

+ Auth Token: {{$account->auth_token}} +

+
+
+ +
+@endsection + diff --git a/resources/views/contests.blade.php b/resources/views/contests.blade.php new file mode 100644 index 0000000..2cc7321 --- /dev/null +++ b/resources/views/contests.blade.php @@ -0,0 +1,72 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Liste des concours à venir ({{$count}})

+ +
+
+
+
+
+ @foreach($contests as $contest) +
+ +
+ @endforeach +
+
+ {!! $contests->links() !!} +
+
+@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 7742415..b488c7f 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -57,11 +57,17 @@ +
@livewireScripts +@yield('js') diff --git a/routes/web.php b/routes/web.php index 4d7f646..a3e1c6f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,6 +11,11 @@ use Illuminate\Support\Facades\Route; Route::get('/', [HomeController::class, 'index'])->middleware(['auth']); Route::get('/history', [HomeController::class, 'history'])->middleware(['auth']); +Route::get('/accounts', [AccountController::class, 'all'])->middleware(['auth']); +Route::get('/accounts/{id}', [AccountController::class, 'account'])->middleware(['auth']); + +Route::get('/contests', [ContestController::class, 'all'])->middleware(['auth']); + Route::view('profile', 'profile.edit') ->name('profile.edit') ->middleware(['auth']);