diff --git a/app/Jobs/VirtualMachine/Provision/AssignIpToGuestJob.php b/app/Jobs/VirtualMachine/Provision/AssignIpToGuestJob.php
index 6131c7a..2656979 100644
--- a/app/Jobs/VirtualMachine/Provision/AssignIpToGuestJob.php
+++ b/app/Jobs/VirtualMachine/Provision/AssignIpToGuestJob.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Jobs\VirtualMachine\Provision;
use App\Http\Facade\SignRSA;
+use App\Http\Services\Telegram;
use App\Models\IpPool;
use App\Models\ModuleIpAddress;
use App\Models\ModuleVmware;
@@ -16,6 +17,7 @@ use App\Models\vCenter;
use App\Services\VirtualMachine\VmProvisionLogger;
use App\Services\VmProvisionService;
use App\Services\VsphereHostSshService;
+use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -65,7 +67,7 @@ class AssignIpToGuestJob implements ShouldQueue
// ─────────────────────────────────────────────────────────────────────────
- public function handle(VsphereHostSshService $ssh, vCenterService $vCenterService, VmProvisionLogger $logger): void
+ public function handle(VsphereHostSshService $ssh, vCenterService $vCenterService, VmProvisionLogger $logger, Telegram $telegram): void
{
$logger->for('AssignIpToGuestJob');
@@ -161,6 +163,13 @@ class AssignIpToGuestJob implements ShouldQueue
'attempt' => $attempt,
'output' => trim($assignOutput),
]);
+ $telegram->SendMessage(
+ "⚠️ AssignIP thất bại\n" .
+ "🖥️ VM: {$this->vmId} | IP: {$ip}\n" .
+ "🔁 Lần thử: {$attempt}/{$maxAttempts}\n" .
+ "📋 Output: " . htmlspecialchars(trim($assignOutput) ?: '(trống)') . "\n" .
+ "🕒 " . Carbon::now()->format('d/m/Y H:i:s')
+ );
$this->releaseIp($reservation, $ipPoolId, $logger);
continue;
}
@@ -237,6 +246,31 @@ class AssignIpToGuestJob implements ShouldQueue
ModuleVmware::where('id', $this->moduleVmwareId)->update(['status' => 0]);
Service::where('vm_id', $this->moduleVmwareId)->update(['status' => 'failed']);
+ // Notify admin via Telegram with order/customer context
+ try {
+ $vm = ModuleVmware::with(['order.customer', 'order.orderItems.product'])->find($this->moduleVmwareId);
+ $customer = $vm?->order?->customer;
+ $order = $vm?->order;
+ $product = $order?->orderItems?->first()?->getProductAttribute();
+
+ $telegram->SendMessage(
+ "🚨 Khởi tạo VM thất bại hoàn toàn\n" .
+ "━━━━━━━━━━━━━━━━━━━━\n" .
+ "🖥️ VM ID: {$this->vmId}\n" .
+ "📦 Sản phẩm: " . ($product?->name ?? 'N/A') . "\n" .
+ "🧾 Đơn hàng: #" . ($order?->order_num ?? 'N/A') . "\n" .
+ "👤 Khách hàng: " . ($customer ? trim($customer->firstname . ' ' . $customer->lastname) : 'N/A') . "\n" .
+ "📧 Email: " . ($customer?->email ?? 'N/A') . "\n" .
+ "🔁 Số lần thử: {$maxAttempts}\n" .
+ "⚡ Trạng thái: VM đã bị đánh dấu inactive\n" .
+ "🕒 " . Carbon::now()->format('d/m/Y H:i:s') . "\n" .
+ "━━━━━━━━━━━━━━━━━━━━\n" .
+ "⚠️ Vui lòng kiểm tra và xử lý thủ công!"
+ );
+ } catch (\Throwable $e) {
+ $logger->warning('could not send Telegram failure notification', ['error' => $e->getMessage()]);
+ }
+
// Attempt to recover IP from vSphere guest identity for admin visibility only.
// Do not send credentials here: password has not been rotated yet.
try {