Initial Commit

This commit is contained in:
Hosteroid
2025-10-08 14:23:07 +03:00
commit b3b3ac66ff
78 changed files with 14248 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
<?php
namespace App\Services\Channels;
use GuzzleHttp\Client;
class DiscordChannel implements NotificationChannelInterface
{
private Client $client;
public function __construct()
{
$this->client = new Client(['timeout' => 10]);
}
public function send(array $config, string $message, array $data = []): bool
{
if (!isset($config['webhook_url'])) {
return false;
}
try {
$embed = $this->createEmbed($message, $data);
$response = $this->client->post($config['webhook_url'], [
'json' => [
'embeds' => [$embed]
]
]);
return $response->getStatusCode() === 204;
} catch (\Exception $e) {
error_log("Discord send failed: " . $e->getMessage());
return false;
}
}
private function createEmbed(string $message, array $data): array
{
$color = $this->getColorByDaysLeft($data['days_left'] ?? null);
$embed = [
'title' => '🔔 Domain Expiration Alert',
'description' => $message,
'color' => $color,
'timestamp' => date('c'),
'footer' => [
'text' => 'Domain Monitor'
]
];
if (isset($data['domain'])) {
$embed['fields'] = [
[
'name' => 'Domain',
'value' => $data['domain'],
'inline' => true
],
[
'name' => 'Days Left',
'value' => $data['days_left'],
'inline' => true
],
[
'name' => 'Expiration Date',
'value' => $data['expiration_date'],
'inline' => true
]
];
}
return $embed;
}
private function getColorByDaysLeft(?int $daysLeft): int
{
if ($daysLeft === null) {
return 0x808080; // Gray
}
if ($daysLeft <= 0) {
return 0xFF0000; // Red
}
if ($daysLeft <= 3) {
return 0xFF4500; // Orange Red
}
if ($daysLeft <= 7) {
return 0xFFA500; // Orange
}
if ($daysLeft <= 30) {
return 0xFFFF00; // Yellow
}
return 0x00FF00; // Green
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Services\Channels;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class EmailChannel implements NotificationChannelInterface
{
public function send(array $config, string $message, array $data = []): bool
{
$mail = new PHPMailer(true);
try {
// Server settings
$mail->isSMTP();
$mail->Host = $_ENV['MAIL_HOST'];
$mail->SMTPAuth = true;
$mail->Username = $_ENV['MAIL_USERNAME'];
$mail->Password = $_ENV['MAIL_PASSWORD'];
$mail->SMTPSecure = $_ENV['MAIL_ENCRYPTION'];
$mail->Port = $_ENV['MAIL_PORT'];
// Recipients
$mail->setFrom($_ENV['MAIL_FROM_ADDRESS'], $_ENV['MAIL_FROM_NAME']);
$mail->addAddress($config['email']);
// Content
$mail->isHTML(true);
$mail->Subject = $this->getSubject($data);
$mail->Body = $this->formatHtmlBody($message, $data);
$mail->AltBody = strip_tags($message);
$mail->send();
return true;
} catch (Exception $e) {
error_log("Email send failed: {$mail->ErrorInfo}");
return false;
}
}
private function getSubject(array $data): string
{
if (isset($data['domain'])) {
$daysLeft = $data['days_left'];
if ($daysLeft <= 0) {
return "🚨 URGENT: Domain {$data['domain']} has EXPIRED";
}
if ($daysLeft == 1) {
return "⚠️ CRITICAL: Domain {$data['domain']} expires TOMORROW";
}
return "⚠️ Domain Expiration Alert: {$data['domain']} ({$daysLeft} days)";
}
return "Domain Monitor Alert";
}
private function formatHtmlBody(string $message, array $data): string
{
$messageHtml = nl2br(htmlspecialchars($message));
return "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: #4A90E2; color: white; padding: 20px; border-radius: 5px 5px 0 0; }
.content { background: #f9f9f9; padding: 20px; border: 1px solid #ddd; }
.footer { background: #333; color: white; padding: 10px; text-align: center; font-size: 12px; border-radius: 0 0 5px 5px; }
.button { display: inline-block; padding: 10px 20px; background: #4A90E2; color: white; text-decoration: none; border-radius: 5px; margin-top: 10px; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h2>🔔 Domain Monitor Alert</h2>
</div>
<div class='content'>
<p>$messageHtml</p>
</div>
<div class='footer'>
<p>This is an automated message from Domain Monitor</p>
</div>
</div>
</body>
</html>
";
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Services\Channels;
interface NotificationChannelInterface
{
/**
* Send notification through the channel
*
* @param array $config Channel-specific configuration
* @param string $message Message to send
* @param array $data Additional data for formatting
* @return bool Success status
*/
public function send(array $config, string $message, array $data = []): bool;
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Services\Channels;
use GuzzleHttp\Client;
class SlackChannel implements NotificationChannelInterface
{
private Client $client;
public function __construct()
{
$this->client = new Client(['timeout' => 10]);
}
public function send(array $config, string $message, array $data = []): bool
{
if (!isset($config['webhook_url'])) {
return false;
}
try {
$payload = [
'text' => $message,
'blocks' => $this->createBlocks($message, $data)
];
$response = $this->client->post($config['webhook_url'], [
'json' => $payload
]);
return $response->getStatusCode() === 200;
} catch (\Exception $e) {
error_log("Slack send failed: " . $e->getMessage());
return false;
}
}
private function createBlocks(string $message, array $data): array
{
$blocks = [
[
'type' => 'header',
'text' => [
'type' => 'plain_text',
'text' => '🔔 Domain Expiration Alert'
]
],
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => $message
]
]
];
if (isset($data['domain'])) {
$blocks[] = [
'type' => 'section',
'fields' => [
[
'type' => 'mrkdwn',
'text' => "*Domain:*\n{$data['domain']}"
],
[
'type' => 'mrkdwn',
'text' => "*Days Left:*\n{$data['days_left']}"
],
[
'type' => 'mrkdwn',
'text' => "*Expiration:*\n{$data['expiration_date']}"
],
[
'type' => 'mrkdwn',
'text' => "*Registrar:*\n{$data['registrar']}"
]
]
];
}
return $blocks;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Services\Channels;
use GuzzleHttp\Client;
class TelegramChannel implements NotificationChannelInterface
{
private Client $client;
public function __construct()
{
$this->client = new Client([
'base_uri' => 'https://api.telegram.org',
'timeout' => 10,
]);
}
public function send(array $config, string $message, array $data = []): bool
{
if (!isset($config['bot_token']) || !isset($config['chat_id'])) {
return false;
}
try {
$response = $this->client->post("/bot{$config['bot_token']}/sendMessage", [
'json' => [
'chat_id' => $config['chat_id'],
'text' => $message,
'parse_mode' => 'HTML',
'disable_web_page_preview' => true,
]
]);
return $response->getStatusCode() === 200;
} catch (\Exception $e) {
error_log("Telegram send failed: " . $e->getMessage());
return false;
}
}
}