Bot télégramme qui surveille le domaine

Bonjour aux habitants de Habr.

Dans le processus d'apprentissage de PHP, j'ai eu l'idée de m'exercer à écrire un bot en PHP, sans utiliser de frameworks.

Le choix s'est porté sur le bot, qui recevra des informations sur la durée de vie du domaine (whois), puis obtiendra la date d'enregistrement à partir de là et ajoutera ce domaine à la base de données (mysql), avec liaison ultérieure à l'utilisateur et notification par télégramme.

Le code source dans mon référentiel sur gita.

Je voulais utiliser la structure MVC , ce qui à mon avis n'était pas tout à fait vrai, car la vue n'était pas impliquée et cela ne peut plus être appelé mvc, mais bon ...

Structure d'application




Contrôleurs - Un lien qui connecte le modèle et la logique d'application.
Modèles - Fichiers de la "logique métier" de l'application (j'ai essayé de "fourrer" tout le sql ici).
Core - Fichiers «core» de l'application.
Bibliothèque - Les bibliothèques ont utilisé la bibliothèque pour analyser les informations de nom de domaine.

Acheminement


Le fichier de routage (routes.php) se trouve dans le répertoire principal .
2 adresses sont ajoutées dans l'application:

/ bot - Telegramm va à cette adresse (vous devez définir le webhook sur cette adresse uri / bot).
/ check - À cette adresse, wget rompt avec cron 1 par jour (à 12 heures), plus à ce sujet plus tard.

Botcontroller


Lors de la transition vers ce contrôleur, nous obtenons les valeurs du corps de la requête POST et les décodons sous forme de tableau.

json_decode(file_get_contents('php://input'), JSON_OBJECT_AS_ARRAY); 

php: // input - récupère le corps de la requête POST

Checkercontroller


Lors de la transition vers ce contrôleur, un script est déclenché qui vérifie l'expiration de tous les domaines et certificats SSL ajoutés, avec l'intervalle:

  • date courante
  • 2 jours
  • 7 jours
  • 30 jours

Et envoie des notifications si la date d'expiration du domaine et du certificat SSL se termine.

Ajout d'utilisateurs


Lorsque l'utilisateur écrit un message dans le bot de télégramme Webhook, l'envoie à notre site Web, puis nous recevons un message au format json, que nous devons décoder et convertir en tableau pour un travail ultérieur.



Nous travaillerons avec le tableau de messages.

Récupérer du message du tableau ['chat'] : id , prénom
où:

id - id de chat
first_name - Nom d'utilisateur

Et à partir du tableau de messages ['text'] , nous obtenons la commande envoyée par l'utilisateur.

On retrouve l'utilisateur dans le tableau des utilisateurs, s'il n'est pas là, créer

 //   $sql= "SELECT user_id FROM users WHERE chat_id=?"; $stmt = $db->prepare($sql); $stmt->execute([$chat_id]); $rows = $stmt->fetch(PDO::FETCH_ASSOC); return (int)$rows['user_id']; 

 //   $sql = 'INSERT INTO users (user_name, chat_id) VALUES (:user_name, :chat_id)'; $insert = $db->prepare($sql); $insert->execute([':user_name' => $name, ':chat_id' => $chat_id]); return true; 

Ajout de domaines et SSL


Lors de l'envoi de la commande / addDomain url au bot, nous obtenons l'url de domaine à partir de la commande et obtenons les données d'enregistrement de domaine à l'aide de cette bibliothèque .

Obtenez le domaine


Nous obtenons une réponse sous forme de texte:



En utilisant des expressions régulières , nous obtenons la date d'enregistrement du domaine.

 preg_match('/Registry\sExpiry\sDate:\s(.*)\\r/', $date, $matches); if (!$matches[1]){ preg_match('/paid-till:\s*(.*)\\n/', $date, $matches); } $matches[1] = $this->formatDate($matches[1]); return $matches[1]; 

Obtenez SSL


J'ai décidé d'obtenir un certificat SSL en utilisant openssl pour linux.

 $getDomainSSL = shell_exec("echo | openssl s_client -servername $url -connect $url:443 2>/dev/null | openssl x509 -noout -dates"); preg_match('~notAfter=(\w+)\s(\d+)\s.+\s(\d+)~', $getDomainSSL, $matches); $date = $matches[2].$matches[1].$matches[3]; $date = date("Ymd", strtotime($date)); $date = str_replace('.','-',$date); return $date; 

On obtient ainsi:

 echo | openssl s_client -servername google.com -connect google.com:443 2>/dev/null | openssl x509 -noout -dates notBefore=Jan 7 15:47:12 2020 GMT notAfter=Mar 31 15:47:12 2020 GMT 

Analyser le résultat à l'aide d'expressions régulières

 preg_match('~notAfter=(\w+)\s(\d+)\s.+\s(\d+)~', $getDomainSSL, $matches); 



Il ne reste plus qu'à ajouter les données à la table.

 $sql = 'INSERT INTO domains (domain_name, date_start, date_end, date_end_ssl) VALUES (:domain_name, :date_start, :date_end, :date_end_ssl)'; $insert = $db->prepare($sql); $insert->execute([':domain_name' => $url, ':date_end' => $exp, ':date_end_ssl' => $ssl_date]); 

Nous lions le domaine et SSL à l'utilisateur


Les données obtenues doivent simplement être enregistrées dans un tableau intermédiaire afin de ne pas «multiplier» les domaines.

 $sql = 'INSERT INTO domain_users (user_id, domain_id) VALUES (:user_id, :domain_id)'; $insert = $db->prepare($sql); $insert->execute([':user_id' => $user_id, ':domain_id' => $domain_id]); 

Vérification de la date de fin du domaine


Lorsque wget va à l'adresse / check, tous les domaines et certificats SSL avec une date d'expiration sont sélectionnés, et s'il y en a, il envoie un message de discussion auquel ce domaine est lié.

 $db = $this->db; $sql= " SELECT user_name, chat_id, domain_name, date_end FROM domain_users JOIN users USING (user_id) JOIN domains USING (domain_id) WHERE ( domains.date_end = CURDATE() OR domains.date_end = CURDATE() + INTERVAL 2 DAY OR domains.date_end = CURDATE() + INTERVAL 7 DAY OR domains.date_end = CURDATE() + INTERVAL 30 DAY ) "; $stmt = $db->prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 

CRON


La couronne dans ce projet est nécessaire pour organiser la transition vers l'adresse «/ chèque», tous les jours à 12 heures.

 crontab -e 0 12 * * * wget url/check 

Proxy Tor


Quelques mots sur l'envoi de messages au télégramme.

Malheureusement, sur le territoire de mon pays (Russie), ils bloquent le télégramme, y compris son api.
Je dois utiliser un proxy, mon choix s'est porté sur le proxy (depuis le dernier projet).

Il suffit de l'installer.

 sudo apt-get install tor 

Ensuite, le proxy sera disponible sur le port 9050.

 curl_setopt($myCurl, CURLOPT_PROXYTYPE, 7); curl_setopt($myCurl, CURLOPT_PROXY, "127.0.0.1:9050"); 

Merci à tous d'avoir lu cet article!

Ceci est mon premier article, alors ne jugez pas strictement :)

Commenter cet article, j'accepterai volontiers toute critique.

Le code source du projet dans mon dépôt github :)

Source: https://habr.com/ru/post/fr485392/


All Articles