Olá para os moradores de Habr.
No processo de aprendizado de PHP, tive a idéia de praticar escrever alguns bot em PHP, sem usar estruturas.
A escolha recaiu sobre o bot, que receberá informações sobre a vida útil do domínio (whois), obterá a data de registro e incluirá esse domínio no banco de dados (mysql), com subsequente vinculação ao usuário e notificação em telegrama.
O código fonte no
meu repositório no gita.
Eu queria usar a estrutura
MVC , o que na
minha opinião não era bem verdade, já que a visão não estava envolvida e isso não pode mais ser chamado de mvc, mas tudo bem ...
Estrutura de aplicação
Controladores - Um link que conecta o modelo e a lógica do aplicativo.
Modelos - Arquivos da "lógica de negócios" do aplicativo (tentei "empinar" todo o sql aqui).
Núcleo - arquivos "principais" do aplicativo.
Biblioteca - as bibliotecas usaram a biblioteca para analisar informações de nome de domínio.
Encaminhamento
O arquivo de roteamento (routes.php) está localizado no diretório
principal .
2 endereços são adicionados no aplicativo:
/ bot - o
Telegramm vai para esse endereço (você precisa definir o
webhook para este endereço de uri / bot).
/ check - Nesse endereço, o
wget rompe com o cron 1 por dia (às 12 horas), mais sobre isso mais tarde.
Botcontroller
Após a transição para esse controlador, obtemos os valores do corpo da solicitação
POST e decodificamos como uma matriz.
json_decode(file_get_contents('php://input'), JSON_OBJECT_AS_ARRAY);
php: // input - pega o corpo da solicitação POST
Checkercontroller
Após a transição para este controlador, é acionado um script que verifica todos os domínios e certificados SSL adicionados quanto à expiração, com o intervalo:
- data atual
- 2 dias
- 7 dias
- 30 dias
E envia notificações se a data de validade do domínio e do certificado SSL terminar.
Adicionando usuários
Quando o usuário escreve uma mensagem no bot de telegrama webhook e a envia para o nosso site, recebemos uma mensagem no formato json, que precisamos decodificar e converter em uma matriz para trabalhos futuros.

Vamos trabalhar com a matriz de
mensagens.Obter da
mensagem da matriz
['chat'] :
id ,
first_nameonde:
id -
id de bate-papo
first_name - Nome de usuário
E a partir da matriz da
mensagem ['text'] , obtemos o comando enviado pelo usuário.
Encontramos o usuário na tabela de usuários, se ele não estiver lá, crie
Adicionando domínios e SSL
Ao enviar o
comando / addDomain url para o bot, obtemos o URL do domínio a partir do comando e obtemos os dados de registro do domínio usando
esta biblioteca .
Obter o domínio
Recebemos uma resposta na forma de texto:

Usando
expressões regulares , obtemos a data de registro do domínio.
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];
Obter SSL
Eu decidi obter um certificado SSL usando o
openssl para 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;
Assim temos:
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
Analise o resultado usando expressões regulares
preg_match('~notAfter=(\w+)\s(\d+)\s.+\s(\d+)~', $getDomainSSL, $matches);

Resta apenas adicionar os dados à tabela.
$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]);
Ligamos o domínio e o ssl ao usuário
Os dados obtidos simplesmente precisam ser registrados em
uma tabela intermediária para não "multiplicar" os domínios.
$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]);
Verificando a data de término do domínio
Quando o wget vai para o endereço / check, todos os domínios e certificados SSL com data de validade são selecionados e, se houver algum, ele envia uma mensagem de bate-papo à qual esse domínio está vinculado.
$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
A coroa deste projeto é necessária para organizar a transição para o endereço '/ check', todos os dias às 12 horas.
crontab -e 0 12 * * * wget url/check
Proxy Tor
Algumas palavras sobre o envio de mensagens para o telegrama.
Infelizmente, no território do meu país (Rússia), eles bloqueiam o telegrama, incluindo sua API.
Eu tenho que usar um proxy, minha escolha recaiu sobre o
proxy (desde o último projeto).
Ele só precisa ser instalado.
sudo apt-get install tor
O proxy estará disponível na porta 9050.
curl_setopt($myCurl, CURLOPT_PROXYTYPE, 7); curl_setopt($myCurl, CURLOPT_PROXY, "127.0.0.1:9050");
Obrigado a todos por ler este artigo!
Este é o meu primeiro artigo, por isso não julgue estritamente :)
Comente este post, terei prazer em aceitar qualquer crítica.
O código fonte do projeto no
meu repositório github :)