Add SnapshotActionMail class and email template for snapshot actions; implement email notifications for create, remove, and revert actions

This commit is contained in:
baodev0
2026-07-17 10:17:52 +07:00
parent abc12b71ef
commit d9da3b5bb3
6 changed files with 353 additions and 21 deletions
@@ -5,23 +5,28 @@ namespace App\Jobs\VirtualMachine\Snapshot;
use App\Events\NotificationStatus;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Mail\Customer\SnapshotActionMail;
use App\Models\ModuleSnapshot;
use App\Models\ModuleSnapshotLimit;
use App\Models\ModuleVmware;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class CreateSnapshot implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected Telegram $telegram;
public function __construct(
public int $snapshotId
) {}
) {
$this->telegram = new Telegram();
}
public function handle(ServiceVCenter $serviceVCenter)
{
@@ -37,23 +42,20 @@ class CreateSnapshot implements ShouldQueue
$product = $snapshot->vm;
// Resolve vCenter using helper method
$vcenter = $serviceVCenter->resolveVCenterFromProduct($product);
if (!$vcenter) {
$snapshot->update([
'status' => 'failed',
'status' => 'failed',
'error_message' => 'Không tìm thấy thông tin vCenter',
]);
throw new \Exception('Không tìm thấy thông tin vCenter cho VM');
}
try {
// Config vCenter
$serviceVCenter->token = $vcenter->token;
$serviceVCenter->token = $vcenter->token;
$serviceVCenter->apiUri = $vcenter->host;
// Call vCenter with snapshot name from DB
$result = $serviceVCenter->CreateSnapShot($product, $snapshot->name);
if ($result === 'Login_Again') {
@@ -71,13 +73,11 @@ class CreateSnapshot implements ShouldQueue
throw new \Exception($result['message'] ?? 'Lỗi tạo snapshot');
}
// Update DB SUCCESS
$snapshot->update([
'status' => 'success',
'status' => 'success',
'snapshot_ref' => $result['data'] ?? $snapshot->name,
]);
// Increment quota CHỈ khi success
ModuleSnapshotLimit::where('customer_id', $snapshot->customer_id)
->increment('used');
@@ -85,9 +85,34 @@ class CreateSnapshot implements ShouldQueue
"Snapshot {$snapshot->name} tạo thành công",
true
));
$product->loadMissing('customer');
if ($product->customer?->email) {
Mail::to($product->customer->email)->queue(new SnapshotActionMail([
'action' => 'create',
'fullname' => $product->customer->fullname,
'vm_name' => $product->name,
'snapshot_name' => $snapshot->name,
'action_at' => now()->format('d/m/Y H:i:s'),
]));
}
$this->telegram->SendMessage(
"📸 <b>SNAPSHOT CREATED SUCCESSFULLY</b>\n\n" .
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
"🖥️ <b>Server:</b> `{$product->name}`\n" .
"📸 <b>Snapshot:</b> `{$snapshot->name}`\n" .
"👤 <b>Customer:</b> `#{$snapshot->customer_id}`\n" .
"🆔 <b>VM ID:</b> `{$product->vmware_id}`\n" .
"⏰ <b>Created:</b> `" . now()->format('d/m/Y H:i:s') . "`\n" .
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
"💡 <b>Status:</b> ✅ Completed\n" .
"🔧 <b>Action:</b> Snapshot Creation\n" .
"📊 <b>Queue:</b> snapshots"
);
} catch (\Throwable $e) {
$snapshot->update([
'status' => 'failed',
'status' => 'failed',
'error_message' => $e->getMessage(),
]);
@@ -101,7 +126,7 @@ class CreateSnapshot implements ShouldQueue
if ($snapshot) {
$snapshot->update([
'status' => 'failed',
'status' => 'failed',
'error_message' => $exception->getMessage(),
]);
}
@@ -110,5 +135,12 @@ class CreateSnapshot implements ShouldQueue
"Snapshot thất bại: {$exception->getMessage()}",
false
));
$this->telegram->SendErrorMessage([
'job_name' => 'CreateSnapshot',
'snapshot_id' => $this->snapshotId,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
}
}
@@ -5,6 +5,7 @@ namespace App\Jobs\VirtualMachine\Snapshot;
use App\Events\NotificationStatus;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Mail\Customer\SnapshotActionMail;
use App\Models\ModuleSnapshot;
use App\Models\ModuleSnapshotLimit;
use App\Models\ModuleVmware;
@@ -14,6 +15,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class RemoveSnapshot implements ShouldQueue
{
@@ -117,6 +119,17 @@ class RemoveSnapshot implements ShouldQueue
// Send success notification
Event(new NotificationStatus("Xóa snapshot thành công cho VPS {$product->name}", true));
$product->loadMissing('customer');
if ($product->customer?->email) {
Mail::to($product->customer->email)->queue(new SnapshotActionMail([
'action' => 'remove',
'fullname' => $product->customer->fullname,
'vm_name' => $product->name,
'snapshot_name' => $snapshotName,
'action_at' => now()->format('d/m/Y H:i:s'),
]));
}
// Send Telegram notification
$this->telegram->SendMessage(
"🗑️ <b>SNAPSHOT REMOVED SUCCESSFULLY</b>\n\n" .
@@ -5,6 +5,7 @@ namespace App\Jobs\VirtualMachine\Snapshot;
use App\Events\NotificationStatus;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Mail\Customer\SnapshotActionMail;
use App\Models\ModuleSnapshot;
use App\Models\ModuleVmware;
use Illuminate\Bus\Queueable;
@@ -13,6 +14,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class RevertSnapshot implements ShouldQueue
{
@@ -107,6 +109,17 @@ class RevertSnapshot implements ShouldQueue
// Send success notification
Event(new NotificationStatus("Khôi phục snapshot thành công cho VPS {$product->name}", true));
$product->loadMissing('customer');
if ($product->customer?->email) {
Mail::to($product->customer->email)->queue(new SnapshotActionMail([
'action' => 'revert',
'fullname' => $product->customer->fullname,
'vm_name' => $product->name,
'snapshot_name' => $snapshot->name,
'action_at' => now()->format('d/m/Y H:i:s'),
]));
}
// Send Telegram notification
$this->telegram->SendMessage(
"🔄 <b>SNAPSHOT REVERTED SUCCESSFULLY</b>\n\n" .