· 3 min read
Un bot Twitter (sur la vaccination) avec les commandes de symfony 5 et la crontab
Aujourd'hui nous allons voir comment mettre en place un Bot pour Twitter ! Notre objectif sera de récupérer le nombre officiel de personnes vaccinées contre la Covid 19 et de publier une fois par jour les données sur un compte Twitter.
![Aujourd'hui nous allons voir comment mettre en place un Bot pour Twitter ! Notre objectif sera de récupérer le nombre officiel de personnes vaccinées contre la Covid 19 et de publier une fois par jour les données sur un compte Twitter.](/img/f9e067d9-920e-49d1-9059-0793a4e475f5.webp)
Introduction
Aujourd’hui nous allons voir comment mettre en place un Bot pour Twitter !
Notre objectif sera de récupérer le nombre officiel de personnes vaccinées contrela Covid 19 (sur https://www.data.gouv.fr/fr/datasets/donnees-relatives-aux-personnes-vaccinees-contre-la-covid-19/) et de publier une fois par jour (à 20h00) les données sur un compte Twitter (https://twitter.com/VaccinBot).
Ce tuto sera plus minimaliste que les précédents, le sujet étant simple à traiter.
Compte “Developer” Twitter
Pour suivre ce tuto, vous devez posséder un compte “Developer” sur Twitter. L’opération nécessite de répondre à un certains nombres de critères, et répondre à un certain nombre de questions (éventuellement par mail).
Je vous laisse réaliser cette opération seule sur https://developer.twitter.com/en et créer votre application (en lecture écriture !).
Nouveau projet Symfony, Bundle et librairies
Pour ce projet nous aurons besoin de :
- Symfony HttpClient pour récupérer les données
- TwitterOAuth pour exploiter simplement l’API de Twitter
Installons Symfony, HttpClient et TwitterOAuth.
symfony new VaccinBot
composer require symfony/http-client
composer require abraham/twitteroauth
Consumer Key et Access Token pour l’API de Twitter
Pour utiliser l’API de Twitter nous devons utiliser 4 variables:
- TWITTER_CONSUMER_KEY
- TWITTER_CONSUMER_SECRET
- TWITTER_ACCESS_TOKEN
- TWITTER_ACCESS_TOKEN_SECRET
Vous trouverez ces valeurs dans votre tableau de bord “Developer Twitter”.
Commençons par créer un fichier .env.local dans notre répertoire.
touch .env.local
Éditons-le :
# TWITTER CHANNEL
TWITTER_CONSUMER_KEY='vos_valeurs'
TWITTER_CONSUMER_SECRET='vos_valeurs'
TWITTER_ACCESS_TOKEN='vos_valeurs'
TWITTER_ACCESS_TOKEN_SECRET='vos_valeurs'
Et ajoutons ces variables dans notre fichier **./config/services.yaml** pour y avoir accès dans notre application
parameters:
TWITTER_CONSUMER_KEY: '%env(TWITTER_CONSUMER_KEY)%'
TWITTER_CONSUMER_SECRET: '%env(TWITTER_CONSUMER_SECRET)%'
TWITTER_ACCESS_TOKEN: '%env(TWITTER_ACCESS_TOKEN)%'
TWITTER_ACCESS_TOKEN_SECRET: '%env(TWITTER_ACCESS_TOKEN_SECRET)%'
Récupérer les données du Gouvernement
Nous récupérons les données sur le site du gouvernement :
Nous utiliserons le jeu de donnée “suivi-vaccins-covid19-national.json”, dont le lien stable est :
Pour faire notre appel API, mettons en place un service dédié dans ./src/Service/GetData.php qui retournera directement une “string”, ce string sera le contenu du post Twitter !
<?php
namespace App\Service;
use DateTime;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class GetDataService
{
private $client;
public function __construct(HttpClientInterface $client)
{
$this->client = $client;
}
public function fromGouv(): string
{
$response = $this->client->request(
'GET',
'https://www.data.gouv.fr/fr/datasets/r/b39196f2-97c4-42f4-8dee-5eb07e823377'
);
$lastData = array_key_last($response->toArray());
$date = new DateTime($response->toArray()[$lastData]['date']);
$nombre = $response->toArray()[$lastData]['total_vaccines'];
return 'Au ' . $date->format('d/m/Y') . ', il y a ' . $nombre . ' personnes de vaccinées en France !';
}
}
Envoyer un Tweet
Nous allons avoir besoin d’envoyer un tweet (c’est un peu le but non), créons-nous un service dédié à cette fonction dans ./src/Service/TwitterApiService.php.
Nous utiliserons ici nos variables de connexion pour l’API de Twitter, et utiliserons la libraire “TwitterOAuth”.
<?php
namespace App\Service;
use Abraham\TwitterOAuth\TwitterOAuth;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class TwitterApiService
{
private $getParams;
public function __construct(ParameterBagInterface $getParams)
{
$this->getParams = $getParams;
}
public function post(string $content)
{
$consumerKey = $this->getParams->get('TWITTER_CONSUMER_KEY');
$consumerSecret = $this->getParams->get('TWITTER_CONSUMER_SECRET');
$accesToken = $this->getParams->get('TWITTER_ACCESS_TOKEN');
$accesTokenSecret = $this->getParams->get('TWITTER_ACCESS_TOKEN_SECRET');
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accesToken, $accesTokenSecret);
$connection->post("statuses/update", ["status" => $content]);
}
}
Création de la commande
Créons un fichier ./src/Command/VaccinBot.php, et mettons en place la commande “php bin/console bot:post”.
<?php
namespace App\Command;
use App\Service\GetDataService;
use App\Service\TwitterApiService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class VaccinBot extends Command
{
private $getData;
private $twitterApi;
protected static $defaultName = 'bot:post';
public function __construct(GetDataService $getData, TwitterApiService $twitterApi)
{
parent::__construct();
$this->getData = $getData;
$this->twitterApi = $twitterApi;
}
protected function configure()
{
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$content = $this->getData->fromGouv();
$this->twitterApi->post($content);
return Command::SUCCESS;
}
}
Testons notre commande dans le terminal.
php bin/console bot:post
Et vérifions sur notre compte Twitter !
Programmons l’exécution de notre commande (Exemple sous Ubuntu 20.04)
Nous souhaitons envoyer notre tweet tous les jours à 18:00 par exemple. Ajoutons notre commande dans la crontab.
Éditons le fichier /etc/crontab
sudo nano /etc/crontab
Et ajoutons l’exécution de commande tous les jours à 18:00.
0 18 * * * root cd /foo/bar/VaccinBot && php bin/console bot:post
Et voilà ;-)