| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- <?php
- namespace App\Services;
- use App\Models\DeviceToken;
- use App\Models\PushNotificationLog;
- use App\Models\User;
- use App\Notifications\Push\BasePushNotification;
- use Illuminate\Support\Collection;
- use Kreait\Firebase\Contract\Messaging;
- use Kreait\Firebase\Messaging\AndroidConfig;
- use Kreait\Firebase\Messaging\CloudMessage;
- use Kreait\Firebase\Messaging\Notification;
- class PushNotificationService
- {
- public function __construct(private Messaging $messaging) {}
- /**
- * Envia uma push notification para todos os tokens ativos de um usuário.
- * Registra o envio no log e desativa tokens inválidos automaticamente.
- */
- public function sendToUser(User $user, BasePushNotification $notification): void
- {
- $tokens = DeviceToken::where('user_id', $user->id)
- ->where('app_type', $notification->target()->value)
- ->where('active', true)
- ->pluck('token')
- ->toArray();
- if (empty($tokens)) {
- return;
- }
- $message = CloudMessage::new()
- ->withNotification(Notification::create($notification->title(), $notification->body()))
- ->withAndroidConfig(AndroidConfig::fromArray([
- 'notification' => ['channel_id' => 'default'],
- 'priority' => 'high',
- ]));
- $report = $this->messaging->sendMulticast($message, $tokens);
- $this->deactivateInvalidTokens($report->invalidTokens());
- if ($report->successes()->count() > 0) {
- $this->log($user, $notification);
- }
- }
- /**
- * Envia para uma coleção de usuários, respeitando cooldowns.
- * Usuários sem tokens ativos são ignorados silenciosamente.
- */
- public function sendToUsers(Collection $users, BasePushNotification $notification): void
- {
- foreach ($users as $user) {
- $this->sendToUser($user, $notification);
- }
- }
- private function log(User $user, BasePushNotification $notification): void
- {
- PushNotificationLog::create([
- 'label' => $notification->label(),
- 'user_id' => $user->id,
- 'target' => $notification->target()->value,
- 'category' => $notification->category()->value,
- 'sent_at' => now(),
- ]);
- }
- private function deactivateInvalidTokens(array $tokens): void
- {
- if (empty($tokens)) {
- return;
- }
- DeviceToken::whereIn('token', $tokens)->update(['active' => false]);
- }
- }
|