| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- <?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\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())
- );
- $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]);
- }
- }
|