Recherche des tweets de réponse avec l'API Tweeter
This commit is contained in:
521
app/Http/Controllers/ContestController.php
Normal file
521
app/Http/Controllers/ContestController.php
Normal file
@@ -0,0 +1,521 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Block;
|
||||
use App\Models\Contest;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
|
||||
class ContestController extends Controller
|
||||
{
|
||||
public function twitterlist()
|
||||
{
|
||||
$client = new HttpBrowser(HttpClient::create(['verify_peer' => false, 'verify_host' => false, 'timeout' => '60']));
|
||||
|
||||
// Création des informations d'authentification
|
||||
$username = 'MyX';
|
||||
$password = '@Gaudin95';
|
||||
$credentials = base64_encode("$username:$password");
|
||||
|
||||
// Ajout des informations d'authentification à l'en-tête de la demande HTTP
|
||||
$client->setServerParameter('HTTP_AUTHORIZATION', 'Basic ' . $credentials);
|
||||
$client->setServerParameter('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36');
|
||||
$crawler = $client->request('GET', 'https://nitter-myx.fly.dev/i/lists/1686126753205387264');
|
||||
|
||||
$i = 1;
|
||||
|
||||
while ($i < 50){
|
||||
$results = $crawler->filterXPath('//div[@class="timeline-item "]')->each(function ($node) {
|
||||
$id = ($node->filterXPath('//*[@class="tweet-link"]'))->attr('href');
|
||||
$created_at = ($node->filterXPath('//span[@class="tweet-date"]/a'))->attr('title');
|
||||
$text = ($node->filterXPath('//*[@class="tweet-content media-body"]'))->text();
|
||||
$screen = ($node->filterXPath('//a[@class="username"]'))->text();
|
||||
$fullname = ($node->filterXPath('//a[@class="fullname"]'))->text();
|
||||
$imageNode = $node->filterXPath('//a[@class="still-image"]');
|
||||
$nbretweet = ($node->filterXPath('//*[@class="tweet-stat"][2]'))->text();
|
||||
$nbretweet = str_replace(',', '', $nbretweet);
|
||||
$nblike = ($node->filterXPath('//*[@class="tweet-stat"][4]'))->text();
|
||||
$nblike = str_replace(',', '', $nblike);
|
||||
$nbreply = ($node->filterXPath('//*[@class="tweet-stat"][1]'))->text();
|
||||
$nbreply = str_replace(',', '', $nbreply);
|
||||
|
||||
//Modifications
|
||||
if ($imageNode->count() > 0) {
|
||||
$picture = $imageNode->attr('href');
|
||||
$picture = urldecode($picture);
|
||||
$picture = str_replace('/pic/orig/', 'https://pbs.twimg.com/', $picture);
|
||||
}else{
|
||||
$picture = null;
|
||||
}
|
||||
|
||||
$screen = str_replace('@', '', $screen);
|
||||
$id = str_replace('/'.$screen.'/status/', '', $id);
|
||||
$id = str_replace('#m', '', $id);
|
||||
|
||||
$contest = Contest::where('tweetid', $id)->first();
|
||||
$fake = Block::where('screen_name', $screen)->first();
|
||||
$containsBlacklistedWord = preg_match('/' . implode('|', array_map('preg_quote', config('twitter.giveaway_to_blacklist'), ['/'])) . '/i', $text) === 1;
|
||||
|
||||
if(!$contest && !$fake && $nbretweet > 100 && $containsBlacklistedWord !== true) {
|
||||
$regex_detect_rts =
|
||||
[
|
||||
"/\bRT\b/",
|
||||
"/RETWEET/i",
|
||||
"/REPUBL/i",
|
||||
"/REPOST/i",
|
||||
];
|
||||
foreach ($regex_detect_rts as $regex_detect_rt) {
|
||||
//if (strstr($string, $url)) { // mine version
|
||||
preg_match($regex_detect_rt, $text, $invites);
|
||||
if (isset($invites[0])) {
|
||||
$rt = true;
|
||||
}
|
||||
}
|
||||
|
||||
//On verifie que si RT
|
||||
if (isset($rt)) {
|
||||
$inputs = array();
|
||||
//On recherche la date de fin du concours
|
||||
$date = $this->getDate($text);
|
||||
if ($date != null) {
|
||||
$fin = $date;
|
||||
} else {
|
||||
$fin = $this->getTwitterDate($created_at);
|
||||
}
|
||||
//On recherche la date de fin du concours
|
||||
if ($fin >= Carbon::now()->format('Y-m-d')) {
|
||||
|
||||
Contest::create([
|
||||
'name' => $fullname,
|
||||
'screen' => $screen,
|
||||
'description' => $text,
|
||||
'url' => 'https://x.com/'.$screen.'/status/'.$id,
|
||||
'picture' => $picture,
|
||||
'tweetid' => $id,
|
||||
'fin' => $fin,
|
||||
'nbretweet' => $nbretweet,
|
||||
'nblike' => $nblike,
|
||||
'nbreply' => $nbreply,
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
$nextPageButton = $crawler->filterXPath('//div[@class="show-more"]/a')->link();
|
||||
$url = $nextPageButton->getUri();
|
||||
$crawler = $client->request('GET', $url);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$reponse = $client->getResponse();
|
||||
var_dump($reponse);
|
||||
|
||||
echo 'Fait !';
|
||||
|
||||
}
|
||||
|
||||
public function searchcontest()
|
||||
{
|
||||
$search = [
|
||||
'giveaway',
|
||||
'#concours',
|
||||
'concours like',
|
||||
'concours rt',
|
||||
'concours follow',
|
||||
'#JeuConcours',
|
||||
'JeuConcours',
|
||||
'jeu concours',
|
||||
'offre follow gagnant',
|
||||
'concours pour gagner',
|
||||
'gagner rt',
|
||||
'Gagnez rt follow',
|
||||
'RT follow',
|
||||
'concours rt like',
|
||||
'concours rt fav',
|
||||
'RT tweet Follow',
|
||||
'concours rt follow',
|
||||
'rt follow tas',
|
||||
'rt follow tirage au sort',
|
||||
'rt follow gagner',
|
||||
'rt follow commente',
|
||||
'rt suivre concours',
|
||||
'rt suivez concours',
|
||||
'rt suivre tirage au sort',
|
||||
'rt suivre tas',
|
||||
'concours remporter',
|
||||
'remporter rt',
|
||||
'concours tas le',
|
||||
'concours résultats le rt',
|
||||
'tirage au sort concours',
|
||||
'concours résultat le rt'
|
||||
];
|
||||
|
||||
$k = array_rand($search);
|
||||
$phrase = $search[$k];
|
||||
|
||||
$date = Carbon::now()->subDays(2)->format('Y-m-d');
|
||||
|
||||
$url = 'https://nitter-myx.fly.dev/search?f=tweets&q='.urlencode('min_replies:100 '.$phrase).'&e-nativeretweets=on&e-replies=on&&since='.$date;
|
||||
|
||||
$client = new HttpBrowser(HttpClient::create(['verify_peer' => false, 'verify_host' => false, 'timeout' => '60']));
|
||||
|
||||
// Création des informations d'authentification
|
||||
$username = 'MyX';
|
||||
$password = '@Gaudin95';
|
||||
$credentials = base64_encode("$username:$password");
|
||||
|
||||
// Ajout des informations d'authentification à l'en-tête de la demande HTTP
|
||||
$client->setServerParameter('HTTP_AUTHORIZATION', 'Basic ' . $credentials);
|
||||
$client->setServerParameter('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36');
|
||||
$crawler = $client->request('GET', $url);
|
||||
|
||||
$crawler->filterXPath('//div[@class="timeline-item "]')->each(function ($node) {
|
||||
$id = ($node->filterXPath('//*[@class="tweet-link"]'))->attr('href');
|
||||
$created_at = ($node->filterXPath('//span[@class="tweet-date"]/a'))->attr('title');
|
||||
$text = ($node->filterXPath('//*[@class="tweet-content media-body"]'))->text();
|
||||
$screen = ($node->filterXPath('//a[@class="username"]'))->text();
|
||||
$fullname = ($node->filterXPath('//a[@class="fullname"]'))->text();
|
||||
$imageNode = $node->filterXPath('//a[@class="still-image"]');
|
||||
$nbretweet = ($node->filterXPath('//*[@class="tweet-stat"][2]'))->text();
|
||||
$nbretweet = str_replace(',', '', $nbretweet);
|
||||
$nblike = ($node->filterXPath('//*[@class="tweet-stat"][4]'))->text();
|
||||
$nblike = str_replace(',', '', $nblike);
|
||||
$nbreply = ($node->filterXPath('//*[@class="tweet-stat"][1]'))->text();
|
||||
$nbreply = str_replace(',', '', $nbreply);
|
||||
|
||||
//Modifications
|
||||
if ($imageNode->count() > 0) {
|
||||
$picture = $imageNode->attr('href');
|
||||
$picture = urldecode($picture);
|
||||
$picture = str_replace('/pic/orig/', 'https://pbs.twimg.com/', $picture);
|
||||
} else {
|
||||
$picture = null;
|
||||
}
|
||||
|
||||
$screen = str_replace('@', '', $screen);
|
||||
$id = str_replace('/' . $screen . '/status/', '', $id);
|
||||
$id = str_replace('#m', '', $id);
|
||||
|
||||
$contest = Contest::where('tweetid', $id)->first();
|
||||
$fake = Block::where('screen_name', $screen)->first();
|
||||
$containsBlacklistedWord = preg_match('/' . implode('|', array_map('preg_quote', config('twitter.giveaway_to_blacklist'), ['/'])) . '/i', $text) === 1;
|
||||
|
||||
if (!$contest && !$fake && $nbretweet > 1000 && $containsBlacklistedWord !== true) {
|
||||
|
||||
$regex_detect_rts =
|
||||
[
|
||||
"/\bRT\b/",
|
||||
"/RETWEET/i",
|
||||
"/REPUBL/i",
|
||||
"/REPOST/i",
|
||||
"/LIKE/i",
|
||||
"/MENTION/i",
|
||||
];
|
||||
|
||||
foreach ($regex_detect_rts as $regex_detect_rt) {
|
||||
//if (strstr($string, $url)) { // mine version
|
||||
preg_match($regex_detect_rt, $text, $invites);
|
||||
if (isset($invites[0])) {
|
||||
$rt = true;
|
||||
}
|
||||
}
|
||||
|
||||
//On verifie que si RT
|
||||
if (isset($rt)) {
|
||||
$inputs = array();
|
||||
//On recherche la date de fin du concours
|
||||
$date = $this->getDate($text);
|
||||
if ($date != null) {
|
||||
$fin = $date;
|
||||
} else {
|
||||
$fin = $this->getTwitterDate($created_at);
|
||||
}
|
||||
//On recherche la date de fin du concours
|
||||
if ($fin >= Carbon::now()->format('Y-m-d')) {
|
||||
|
||||
Contest::create([
|
||||
'name' => $fullname,
|
||||
'screen' => $screen,
|
||||
'description' => $text,
|
||||
'url' => 'https://x.com/' . $screen . '/status/' . $id,
|
||||
'picture' => $picture,
|
||||
'tweetid' => $id,
|
||||
'fin' => $fin,
|
||||
'nbretweet' => $nbretweet,
|
||||
'nblike' => $nblike,
|
||||
'nbreply' => $nbreply,
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$reponse = $client->getResponse();
|
||||
var_dump($reponse);
|
||||
|
||||
echo 'Fait !';
|
||||
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
|
||||
$response = Http::get('https://rtandfollow.com/apibot');
|
||||
$tweets = $response->json();
|
||||
|
||||
foreach($tweets as $status) {
|
||||
|
||||
$tweetid = $status['tweetid'];
|
||||
$screen_name = $status['organizer']['screen_name'];
|
||||
$text = $status['description'];
|
||||
|
||||
$concours = Contest::where('tweetid', $tweetid)->first();
|
||||
$blocking = Block::where('screen_name', $screen_name)->first();
|
||||
$containsBlacklistedWord = preg_match('/' . implode('|', array_map('preg_quote', config('twitter.giveaway_to_blacklist'), ['/'])) . '/i', $text) === 1;
|
||||
|
||||
//On verifie que le concours n'est pas dans la BDD ou que l'utilisateur n'est pas bloqué
|
||||
if (empty($concours) and empty($blocking) and $containsBlacklistedWord !== true) {
|
||||
|
||||
//On recherche la date de fin du concours
|
||||
$fin = $status['fin'];
|
||||
|
||||
if ($fin >= Carbon::now()->format('Y-m-d')) {
|
||||
Contest::create([
|
||||
'name' => $status['organizer']['name'],
|
||||
'screen' => $screen_name,
|
||||
'description' => $text,
|
||||
'url' => $status['url'],
|
||||
'picture' => '',
|
||||
'tweetid' => $tweetid,
|
||||
'fin' => $fin,
|
||||
'nbretweet' => $status['nbretweet'],
|
||||
'nblike' => $status['nblike'],
|
||||
'nbreply' => $status['nbreply'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getOrganizer($screen)
|
||||
{
|
||||
$organiser = Organizer::where('screen_name', $screen)->first();
|
||||
|
||||
if ($organiser){
|
||||
return $organiser->id;
|
||||
}else
|
||||
{
|
||||
$client = new HttpBrowser(HttpClient::create(['verify_peer' => false, 'verify_host' => false, 'timeout' => '60']));
|
||||
// Création des informations d'authentification
|
||||
$username = 'autokdo';
|
||||
$password = '@Gaudin95';
|
||||
$credentials = base64_encode("$username:$password");
|
||||
|
||||
// Ajout des informations d'authentification à l'en-tête de la demande HTTP
|
||||
$client->setServerParameter('HTTP_AUTHORIZATION', 'Basic ' . $credentials);
|
||||
$client->setServerParameter('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36');
|
||||
$crawler = $client->request('GET', 'https://nitter-autokdo.fly.dev/'.$screen);
|
||||
try{
|
||||
$name = $crawler->filterXPath('//*[@class="profile-card-fullname"]')->text();
|
||||
$description = $crawler->filterXPath('//*[@class="profile-bio"]')->text();
|
||||
$profileUrl = $crawler->getUri();
|
||||
$parsedUrl = parse_url($profileUrl);
|
||||
$baseTwitterUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
|
||||
|
||||
|
||||
$image = $crawler->filterXPath('//meta[@property="og:image"]')->attr('content');
|
||||
$url = str_replace("http://nitter-autokdo.fly.dev/pic/", "", $image);
|
||||
$url = urldecode($url);
|
||||
$url = 'https://'.$url;
|
||||
$response = Http::get($url);
|
||||
$contents = $response->body();
|
||||
|
||||
// Utilisation de getimagesize pour obtenir les informations sur l'image
|
||||
$imageInfo = getimagesizefromstring($contents);
|
||||
|
||||
if ($imageInfo === false) {
|
||||
$filename = 'icon-96x96.png';
|
||||
}
|
||||
|
||||
$format = image_type_to_extension($imageInfo[2], false);
|
||||
$filename = uniqid() . '.' . $format;
|
||||
|
||||
// Stocker l'image dans le répertoire 'ads' du stockage
|
||||
Storage::put('/public/logo/'.$filename, $contents);
|
||||
|
||||
$organiser = Organizer::create([
|
||||
'name' => $name,
|
||||
'screen_name' => $screen,
|
||||
'description' => $description,
|
||||
'logo' => $filename,
|
||||
'url' => 'https://twitter.com/'.$screen,
|
||||
]);
|
||||
|
||||
return $organiser->id;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
dd($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function getCategorie($data)
|
||||
{
|
||||
$client = new HttpBrowser(HttpClient::create(['verify_peer' => false, 'verify_host' => false, 'timeout' => '60']));
|
||||
$client->request('GET', 'https://api.uclassify.com/v1/twittercontests/categories/classify/?readKey=c7ivTcoN2ycU&text='.$data);
|
||||
|
||||
$json = $client->getResponse()->getContent();
|
||||
|
||||
$array = json_decode($json,true);
|
||||
|
||||
$laravelArray = collect($array);
|
||||
|
||||
$laravelArray = $laravelArray->sortDesc();
|
||||
|
||||
$value = $laravelArray->first();
|
||||
|
||||
if($value < '0.5'){
|
||||
$categorie = '20';
|
||||
}
|
||||
else{
|
||||
|
||||
$cat = $laravelArray->keys()->first();
|
||||
|
||||
if($cat == 'argent'){
|
||||
$categorie = '1';
|
||||
}elseif($cat == 'beaute'){
|
||||
$categorie = '2';
|
||||
}elseif($cat == 'console'){
|
||||
$categorie = '3';
|
||||
}elseif($cat == 'cuisine'){
|
||||
$categorie = '4';
|
||||
}elseif($cat == 'dvd'){
|
||||
$categorie = '5';
|
||||
}elseif($cat == 'enfant'){
|
||||
$categorie = '6';
|
||||
}elseif($cat == 'goodies'){
|
||||
$categorie = '7';
|
||||
}elseif($cat == 'invitation'){
|
||||
$categorie = '8';
|
||||
}elseif($cat == 'livre'){
|
||||
$categorie = '9';
|
||||
}elseif($cat == 'maison'){
|
||||
$categorie = '10';
|
||||
}elseif($cat == 'mode'){
|
||||
$categorie = '11';
|
||||
}elseif($cat == 'pc'){
|
||||
$categorie = '12';
|
||||
}elseif($cat == 'sport'){
|
||||
$categorie = '13';
|
||||
}elseif($cat == 'telephone'){
|
||||
$categorie = '14';
|
||||
}elseif($cat == 'voiture'){
|
||||
$categorie = '15';
|
||||
}elseif($cat == 'voyage'){
|
||||
$categorie = '16';
|
||||
}else{
|
||||
$categorie = '20';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $categorie;
|
||||
|
||||
}
|
||||
|
||||
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 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 = [];
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
private function getTwitterDate($text)
|
||||
{
|
||||
// Utilisez une expression régulière pour extraire toutes les dates
|
||||
$pattern = '/(\w{3} \d{1,2}, \d{4})/';
|
||||
preg_match_all($pattern, $text, $matches);
|
||||
|
||||
if (!empty($matches[1])) {
|
||||
// Récupérer la dernière date trouvée
|
||||
$lastDateString = end($matches[1]);
|
||||
|
||||
// Analyse de la date
|
||||
$date = Carbon::createFromFormat('M d, Y', $lastDateString);
|
||||
|
||||
// Obtenez la date au format Y-m-d
|
||||
$formattedDate = $date->addDays(1)->format('Y-m-d');
|
||||
|
||||
return $formattedDate;
|
||||
} else {
|
||||
// Retourne la date actuelle +1 jour si aucune date n'est trouvée
|
||||
return Carbon::now()->addDays(1)->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user