Telegramm-Bot, der die Domain überwacht

Hallo an die Bewohner von Habr.

Während ich PHP lernte, kam ich auf die Idee, einen Bot in PHP zu schreiben, ohne dabei Frameworks zu verwenden.

Die Wahl fiel auf den Bot, der Informationen über die Lebensdauer der Domain (whois) erhält, dann das Registrierungsdatum von dort abruft und diese Domain zur Datenbank (mysql) hinzufügt, mit anschließender Bindung an den Benutzer und Benachrichtigung per Telegramm.

Der Quellcode in meinem Repository auf Gita.

Ich wollte die MVC- Struktur verwenden, was meiner Meinung nach nicht ganz richtig war, da View nicht involviert war und dies nicht mehr als MVC bezeichnet werden kann, aber na ja ...

Anwendungsstruktur




Controller - Eine Verknüpfung, die Modell- und Anwendungslogik verbindet.
Models - Dateien der "Geschäftslogik" der Anwendung (Ich habe versucht, die gesamte SQL hier "zu stopfen").
Core - Anwendungs-Core-Dateien.
Bibliothek - Bibliotheken verwendeten die Bibliothek zum Analysieren von Domainnameninformationen.

Routing


Die Routing-Datei (routes.php) befindet sich im Core- Verzeichnis.
2 Adressen werden in der Anwendung hinzugefügt:

/ bot - Telegramm geht an diese Adresse (Sie müssen den Webhook auf diese URI / Bot-Adresse einstellen ).
/ check - An dieser Adresse werden Pausen mit Cron 1 pro Tag (um 12 Uhr) eingelegt, dazu später mehr.

Botcontroller


Beim Übergang zu diesem Controller erhalten wir die Werte aus dem Hauptteil der POST- Anforderung und decodieren sie als Array.

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

php: // input - Liefert den Body der POST-Anfrage

Checkercontroller


Beim Übergang zu diesem Controller wird ein Skript ausgelöst, das alle hinzugefügten Domänen und SSL-Zertifikate mit dem folgenden Intervall auf Ablauf überprüft:

  • aktuelles Datum
  • 2 Tage
  • 7 tage
  • 30 tage

Und sendet Benachrichtigungen, wenn das Ablaufdatum der Domain und des SSL-Zertifikats endet.

Benutzer hinzufügen


Wenn der Benutzer eine Nachricht an den Webhook-Telegramm-Bot schreibt, diese an unsere Website sendet, erhalten wir eine Nachricht im JSON-Format, die wir dekodieren und für die weitere Arbeit in ein Array konvertieren müssen.



Wir werden mit dem Nachrichtenarray arbeiten.

Holen Sie sich aus der Array- Nachricht ['chat'] : id , first_name
wo:

id - Chat- ID
Vorname - Benutzername

Und aus dem message ['text'] -Array erhalten wir den vom Benutzer gesendeten Befehl.

Wir finden den Benutzer in der Benutzertabelle, wenn er nicht da ist, erstellen

 //   $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; 

Domains und SSL hinzufügen


Wenn Sie den Befehl / addDomain url an den Bot senden, rufen Sie die Domain-URL aus dem Befehl ab und rufen Sie die Domain-Registrierungsdaten mithilfe dieser Bibliothek ab .

Holen Sie sich die Domain


Wir erhalten eine Antwort in Form von Text:



Mit regulären Ausdrücken erhalten wir das Domain-Registrierungsdatum.

 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]; 

Holen Sie sich SSL


Ich habe mich für ein SSL-Zertifikat mit openssl für Linux entschieden.

 $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; 

So erhalten wir:

 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 

Analysieren Sie das Ergebnis mit regulären Ausdrücken

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



Es müssen nur noch die Daten zur Tabelle hinzugefügt werden.

 $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]); 

Wir binden die Domain und SSL an den Benutzer


Die erhaltenen Daten müssen lediglich in einer Zwischentabelle aufgezeichnet werden, um die Domänen nicht zu "multiplizieren".

 $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]); 

Überprüfen des Domain-Enddatums


Wenn wget an die Adresse / check geht, werden alle Domänen und SSL-Zertifikate mit einem Ablaufdatum ausgewählt. Wenn vorhanden, wird eine Chat-Nachricht gesendet, an die diese Domäne gebunden ist.

 $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


Die Krone in diesem Projekt wird benötigt, um den Übergang zur Adresse '/ check' jeden Tag um 12 Uhr zu organisieren.

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

Tor Proxy


Ein paar Worte zum Versenden von Nachrichten an Telegramme.

Leider blockieren sie auf dem Territorium meines Landes (Russland) das Telegramm, einschließlich seiner API.
Ich muss einen Proxy benutzen, meine Wahl fiel auf den Proxy (seit dem letzten Projekt).

Es muss nur installiert werden.

 sudo apt-get install tor 

Dann ist der Proxy auf Port 9050 verfügbar.

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

Vielen Dank für das Lesen dieses Artikels!

Dies ist mein erster Artikel, also nicht streng beurteilen :)

Kommentar zu diesem Beitrag, werde ich gerne jede Kritik annehmen.

Der Quellcode des Projekts in meinem Github-Repository :)

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


All Articles