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énomoù:
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
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 :)