Created
September 30, 2026 21:57
-
-
Save A35G/af301c31014b1073c10714e664866d0f to your computer and use it in GitHub Desktop.
Contatore di numero di download di una Libreria, dal portale Packagist con invio di Notifiche ad un Bot Telegram
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| /* | |
| * Packagist 2 Telegram notifier | |
| * | |
| * Requisiti: | |
| * - PHP 8+ | |
| * - cURL | |
| * - un bot Telegram | |
| * | |
| * Esecuzione: | |
| * php packagist-telegram.php | |
| */ | |
| $package = 'vendor/nome-pacchetto'; | |
| $telegramBotToken = 'BOT_TOKEN'; | |
| $telegramChatId = 'CHAT_ID'; | |
| $stateFile = __DIR__ . '/packagist-state.json'; | |
| function queryJson(string $url): array | |
| { | |
| $ch = curl_init($url); | |
| curl_setopt_array($ch, [ | |
| CURLOPT_RETURNTRANSFER => true, | |
| CURLOPT_FOLLOWLOCATION => true, | |
| CURLOPT_TIMEOUT => 15, | |
| CURLOPT_HTTPHEADER => [ | |
| 'Accept: application/json', | |
| 'User-Agent: PackagistTelegramNotifier/1.0', | |
| ], | |
| ]); | |
| $response = curl_exec($ch); | |
| if ($response === false) { | |
| $error = curl_error($ch); | |
| curl_close($ch); | |
| throw new RuntimeException('cURL error: ' . $error); | |
| } | |
| $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
| curl_close($ch); | |
| if ($statusCode < 200 OR $statusCode >= 300) throw new RuntimeException("HTTP error {$statusCode} ricevuto da Packagist"); | |
| $data = json_decode($response, true); | |
| if (!is_array($data)) throw new RuntimeException('Risposta JSON non valida.'); | |
| return $data; | |
| } | |
| function send2Telegram(string $botToken, string $chatId, string $message): void | |
| { | |
| $url = "https://api.telegram.org/bot{$botToken}/sendMessage"; | |
| $ch = curl_init($url); | |
| curl_setopt_array($ch, [ | |
| CURLOPT_POST => true, | |
| CURLOPT_RETURNTRANSFER => true, | |
| CURLOPT_TIMEOUT => 15, | |
| CURLOPT_POSTFIELDS => [ | |
| 'chat_id' => $chatId, | |
| 'text' => $message, | |
| 'parse_mode' => 'HTML', | |
| ] | |
| ]); | |
| $response = curl_exec($ch); | |
| if ($response === false) { | |
| $error = curl_error($ch); | |
| curl_close($ch); | |
| throw new RuntimeException('Errore Telegram: ' . $error); | |
| } | |
| $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
| curl_close($ch); | |
| if ($statusCode < 200 OR $statusCode >= 300) throw new RuntimeException("Telegram ha restituito HTTP {$statusCode}: {$response}"); | |
| } | |
| function loadState(string $file): ?int | |
| { | |
| if (!file_exists($file)) return; | |
| $content = file_get_contents($file); | |
| if ($content === false) return; | |
| $data = json_decode($content, true); | |
| if (!is_array($data) OR !isset($data['downloads'])) return; | |
| return (int)$data['downloads']; | |
| } | |
| function saveState(string $file, int $downloads): void | |
| { | |
| $data = [ | |
| 'downloads' => $downloads, | |
| 'updated_at' => date(DATE_ATOM), | |
| ]; | |
| file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX); | |
| } | |
| try { | |
| $url = 'https://packagist.org/packages/' . rawurlencode($package) . '.json'; | |
| $data = queryJson($url); | |
| if (!isset($data['package']['downloads']['total'])) throw new RuntimeException('Il campo downloads.total non è presente nella risposta di Packagist.'); | |
| $currentDownloads = (int)$data['package']['downloads']['total']; | |
| $previousDownloads = loadState($stateFile); | |
| if ($previousDownloads === null) { | |
| saveState($stateFile, $currentDownloads); | |
| echo "Prima esecuzione.\n"; | |
| echo "Download attuali: {$currentDownloads}\n"; | |
| exit(0); | |
| } | |
| if ($currentDownloads <= $previousDownloads) { | |
| echo sprintf("[%s] Nessun nuovo download. Totale: %d\n", date('Y-m-d H:i:s'), $currentDownloads); | |
| saveState($stateFile, $currentDownloads); | |
| exit(0); | |
| } | |
| $newDownloads = $currentDownloads - $previousDownloads; | |
| $message = sprintf("<b>%s</b>\n\n<b>+%d nuovi download</b>\nTotale: <b>%d</b>\n %s", htmlspecialchars($package, ENT_QUOTES, 'UTF-8'), $newDownloads, $currentDownloads, date('d/m/Y H:i:s')); | |
| send2Telegram($telegramBotToken, $telegramChatId, $message); | |
| saveState($stateFile, $currentDownloads); | |
| echo sprintf("[%s] Notifica inviata: +%d download. Totale: %d\n", date('Y-m-d H:i:s'), $newDownloads, $currentDownloads); | |
| } catch (Throwable $e) { | |
| fwrite(STDERR, '[' . date('Y-m-d H:i:s') . '] ERRORE: ' . $e->getMessage() . PHP_EOL); | |
| exit(1); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment