first(); if ($record) { $setting = json_decode($record->value); $this->token = $setting->discord_webhook_id ?? null; $this->group = $setting->discord_webhook_token ?? null; } else { $this->token = null; $this->group = null; } } protected function sendDiscordMessage(array $payload) { if (!$this->token || !$this->group) { Log::channel('Custom')->warning('Discord notification not sent: Missing webhook ID or token'); return null; } $webhookUrl = "https://discord.com/api/webhooks/{$this->token}/{$this->group}"; try { return Http::post($webhookUrl, $payload); } catch (\Exception $exception) { Log::channel('Custom')->error('Failed to send Discord notification: ' . $exception->getMessage()); return null; } } /** * Send simple message with embed */ public function SendMessage($message = '', $color = self::COLOR_INFO, $title = null) { $embed = [ 'description' => $message, 'color' => $color, 'timestamp' => now()->toIso8601String(), ]; if ($title) { $embed['title'] = $title; } $payload = [ 'embeds' => [$embed] ]; return $this->sendDiscordMessage($payload); } /** * Send error message with embed */ public function NotifyDiscordFailure($reason, $data = null) { $fields = [ [ 'name' => '🚫 Lý do lỗi', 'value' => $reason, 'inline' => false, ], ]; if ($data) { $fields[] = [ 'name' => '📄 Dữ liệu liên quan', 'value' => "```json\n" . substr(json_encode($data, JSON_PRETTY_PRINT), 0, 1000) . "\n```", 'inline' => false, ]; } $embed = [ 'title' => '🔴 Gửi Discord thất bại', 'color' => self::COLOR_ERROR, 'fields' => $fields, 'timestamp' => now()->toIso8601String(), ]; Log::channel('Custom')->error('NotifyDiscordFailure: ' . $reason, ['data' => $data]); return null; } /** * Send VPS information with enhanced embed */ public function SendInformation($product = [], $user = '', $password = '', $port = 22) { $fields = [ [ 'name' => '🌐 Địa chỉ IP', 'value' => isset($product->IpAddress->ip) ? $product->IpAddress->ip : 'N/A', 'inline' => true, ], [ 'name' => '👤 Tài khoản', 'value' => $user ?: 'root', 'inline' => true, ], [ 'name' => '🔌 Cổng SSH', 'value' => (string) $port, 'inline' => true, ], [ 'name' => '🔐 Mật khẩu', 'value' => "||{$password}||", // Spoiler text 'inline' => true, ], [ 'name' => '⏰ Hết hạn', 'value' => isset($product->next_due_date) ? Carbon::parse($product->next_due_date)->format('d/m/Y H:i') : 'Không giới hạn', 'inline' => true, ], [ 'name' => '💻 Hệ điều hành', 'value' => (isset($product->Os->OsGroup->name) ? $product->Os->OsGroup->name : '') . ' ' . (isset($product->Os->version) ? $product->Os->version : ''), 'inline' => true, ], ]; // Add SSH command $ipAddress = isset($product->IpAddress->ip) ? $product->IpAddress->ip : 'IP_ADDRESS'; $sshCommand = "ssh {$user}@{$ipAddress}"; if ($port != 22) { $sshCommand .= " -p {$port}"; } $embed = [ 'title' => '🎉 VPS đã được khởi tạo thành công!', 'description' => "**Đơn hàng:** #" . (isset($product->order_id) ? $product->order_id : '') . "\n**SSH Command:**\n```bash\n{$sshCommand}\n```", 'color' => self::COLOR_SUCCESS, 'fields' => $fields, 'footer' => [ 'text' => 'VPS Management System', 'icon_url' => 'https://cdn-icons-png.flaticon.com/512/868/868681.png' ], 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send error message with enhanced formatting */ public function SendErrorMessage($data, $context = null) { $content = is_string($data) ? $data : json_encode($data, JSON_PRETTY_PRINT); $fields = []; if ($context) { $fields[] = [ 'name' => '📍 Ngữ cảnh', 'value' => $context, 'inline' => false, ]; } $fields[] = [ 'name' => '⚠️ Chi tiết lỗi', 'value' => "```json\n" . substr($content, 0, 1000) . "\n```", 'inline' => false, ]; $embed = [ 'title' => '🚨 Lỗi hệ thống', 'description' => '**Admin:** Đã xảy ra lỗi trong quá trình xử lý dịch vụ', 'color' => self::COLOR_ERROR, 'fields' => $fields, 'footer' => [ 'text' => 'Error Notification System' ], 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send new user registration notification */ public function SendNewUserRegistration($email, $code, $verificationLink) { $fields = [ [ 'name' => '📧 Email đăng ký', 'value' => $email, 'inline' => true, ], [ 'name' => '🔢 Mã xác thực', 'value' => "`{$code}`", 'inline' => true, ], [ 'name' => '🔗 Link xác thực', 'value' => "[Nhấn để xác thực]({$verificationLink})", 'inline' => false, ], ]; $embed = [ 'title' => '🎉 Thành viên mới đăng ký!', 'description' => '**Có người dùng mới vừa tạo tài khoản**', 'color' => self::COLOR_SUCCESS, 'fields' => $fields, 'thumbnail' => [ 'url' => 'https://cdn-icons-png.flaticon.com/512/1077/1077114.png' ], 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send customer recharge notification */ public function SendCustomerRecharge($customer, $amount, $method = null) { $customerName = trim("{$customer->firstname} {$customer->lastname}"); $fields = [ [ 'name' => '👤 Khách hàng', 'value' => $customerName ?: 'N/A', 'inline' => true, ], [ 'name' => '📧 Email', 'value' => isset($customer->email) ? $customer->email : 'N/A', 'inline' => true, ], [ 'name' => '💰 Số tiền nạp', 'value' => '**' . number_format($amount, 0, ',', '.') . ' VNĐ**', 'inline' => true, ], ]; if ($method) { $fields[] = [ 'name' => '💳 Phương thức', 'value' => $method, 'inline' => true, ]; } $fields[] = [ 'name' => '🕒 Thời gian', 'value' => Carbon::now()->format('d/m/Y H:i:s'), 'inline' => true, ]; $embed = [ 'title' => '💎 Khách hàng nạp tiền thành công', 'description' => "**{$customerName}** vừa nạp tiền vào tài khoản", 'color' => self::COLOR_VIP, 'fields' => $fields, 'thumbnail' => [ 'url' => 'https://cdn-icons-png.flaticon.com/512/3135/3135715.png' ], 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send job execution notification */ public function SendJobRunInfo($jobName, $status, $additionalInfo = null, $duration = null) { $statusEmoji = match (strtolower($status)) { 'success', 'completed' => '✅', 'failed', 'error' => '❌', 'running', 'processing' => '⏳', 'warning' => '⚠️', default => '📊' }; $color = match (strtolower($status)) { 'success', 'completed' => self::COLOR_SUCCESS, 'failed', 'error' => self::COLOR_ERROR, 'warning' => self::COLOR_WARNING, default => self::COLOR_INFO }; $fields = [ [ 'name' => '⏱️ Thời gian chạy', 'value' => Carbon::now()->format('d/m/Y H:i:s'), 'inline' => true, ], [ 'name' => '📊 Trạng thái', 'value' => "{$statusEmoji} {$status}", 'inline' => true, ], ]; if ($duration) { $fields[] = [ 'name' => '⏲️ Thời gian thực thi', 'value' => $duration, 'inline' => true, ]; } if ($additionalInfo) { $info = is_string($additionalInfo) ? $additionalInfo : json_encode($additionalInfo, JSON_PRETTY_PRINT); $fields[] = [ 'name' => '📋 Thông tin chi tiết', 'value' => "```\n" . substr($info, 0, 1000) . "\n```", 'inline' => false, ]; } $embed = [ 'title' => "⚙️ Job Execution: {$jobName}", 'color' => $color, 'fields' => $fields, 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send order paid notification with enhanced formatting */ public function SendOrderPaidNotification($invoice) { $invoiceItem = $invoice->invoiceItem()->with([ 'vps', 'hosting', 'os.osGroup', 'addons.addonItems' ])->first(); if (!$invoiceItem) { return $this->SendErrorMessage('Không tìm thấy invoice item từ invoice ID: ' . $invoice->id, 'Order Paid Process'); } $product = $invoiceItem->product; $os = $invoiceItem->os; $osGroup = isset($os->osGroup) ? $os->osGroup : null; $addons = $invoiceItem->addons; $customer = $invoice->customer; $fields = [ [ 'name' => '🧾 Mã đơn hàng', 'value' => "**#{$invoice->order_num}**", 'inline' => true, ], [ 'name' => '📦 Sản phẩm', 'value' => "#" . (isset($product->id) ? $product->id : '') . " - " . (isset($product->name) ? $product->name : ''), 'inline' => true, ], [ 'name' => '💰 Tổng thanh toán', 'value' => '**' . number_format($invoice->total, 0, ',', '.') . ' VNĐ**', 'inline' => true, ], [ 'name' => '👤 Khách hàng', 'value' => trim((isset($customer->firstname) ? $customer->firstname : '') . ' ' . (isset($customer->lastname) ? $customer->lastname : '')), 'inline' => true, ], [ 'name' => '📧 Email', 'value' => isset($customer->email) ? $customer->email : 'N/A', 'inline' => true, ], [ 'name' => '🕒 Thời gian thanh toán', 'value' => Carbon::parse($invoice->date_paid)->format('d/m/Y H:i:s'), 'inline' => true, ], ]; if ($osGroup || $os) { $fields[] = [ 'name' => '🖥️ Hệ điều hành', 'value' => (isset($osGroup->name) ? $osGroup->name : '') . ' ' . (isset($os->version) ? $os->version : ''), 'inline' => true, ]; } // Add addons if exist if ($addons && $addons->count()) { $addonsText = ""; foreach ($addons as $addon) { $addonsText .= "• {$addon->addonItems->name} (x{$addon->qty}) - " . number_format($addon->price, 0, ',', '.') . " VNĐ\n"; } $fields[] = [ 'name' => '➕ Dịch vụ bổ sung', 'value' => $addonsText, 'inline' => false, ]; } $embed = [ 'title' => '💵 Đơn hàng được thanh toán thành công!', 'description' => "**Khách hàng:** " . (isset($customer->firstname) ? $customer->firstname : '') . " " . (isset($customer->lastname) ? $customer->lastname : '') . "\n**Đơn hàng:** #{$invoice->order_num}", 'color' => self::COLOR_SUCCESS, 'fields' => $fields, 'thumbnail' => [ 'url' => 'https://cdn-icons-png.flaticon.com/512/3135/3135673.png' ], 'footer' => [ 'text' => 'Order Management System' ], 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send service renewal notification */ public function SendServiceRenewal($service, $period) { $fields = [ [ 'name' => '🏷️ Dịch vụ', 'value' => isset($service->name) ? $service->name : 'N/A', 'inline' => true, ], [ 'name' => '📅 Gia hạn thêm', 'value' => $period, 'inline' => true, ], [ 'name' => '📅 Ngày hết hạn mới', 'value' => Carbon::parse($service->next_due_date)->format('d/m/Y'), 'inline' => true, ], ]; $embed = [ 'title' => '🔄 Dịch vụ được gia hạn', 'color' => self::COLOR_INFO, 'fields' => $fields, 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } /** * Send system maintenance notification */ public function SendMaintenanceNotification($title, $description, $startTime = null, $endTime = null) { $fields = []; if ($startTime) { $fields[] = [ 'name' => '🕐 Bắt đầu', 'value' => Carbon::parse($startTime)->format('d/m/Y H:i:s'), 'inline' => true, ]; } if ($endTime) { $fields[] = [ 'name' => '🕑 Kết thúc dự kiến', 'value' => Carbon::parse($endTime)->format('d/m/Y H:i:s'), 'inline' => true, ]; } $embed = [ 'title' => "🔧 {$title}", 'description' => $description, 'color' => self::COLOR_WARNING, 'fields' => $fields, 'timestamp' => now()->toIso8601String(), ]; return $this->sendDiscordMessage(['embeds' => [$embed]]); } }