PushNotificationDispatcher.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. namespace App\Services;
  3. use App\Models\PushNotificationLog;
  4. use App\Notifications\Push\BasePushNotification;
  5. use App\Notifications\Push\Cliente\Contextual\ContextualSegundaPush;
  6. use App\Notifications\Push\Cliente\Contextual\ContextualSextaPush;
  7. use App\Notifications\Push\Cliente\Contextual\ContextualVisitaPush;
  8. use App\Notifications\Push\Cliente\Educativo\Educativo1Push;
  9. use App\Notifications\Push\Cliente\Educativo\Educativo2Push;
  10. use App\Notifications\Push\Cliente\Educativo\Educativo3Push;
  11. use App\Notifications\Push\Cliente\Educativo\Educativo4Push;
  12. use App\Notifications\Push\Cliente\EducativoConversao\EducativoConversao1Push;
  13. use App\Notifications\Push\Cliente\EducativoConversao\EducativoConversao2Push;
  14. use App\Notifications\Push\Cliente\Marketing\Marketing1Push;
  15. use App\Notifications\Push\Cliente\Marketing\Marketing2Push;
  16. use App\Notifications\Push\Cliente\Marketing\Marketing3Push;
  17. use App\Notifications\Push\Cliente\Marketing\Marketing4Push;
  18. use App\Notifications\Push\Cliente\Motivacional\Motivacional1Push as ClienteMotivacional1Push;
  19. use App\Notifications\Push\Cliente\Motivacional\Motivacional2Push as ClienteMotivacional2Push;
  20. use App\Notifications\Push\Cliente\Motivacional\Motivacional3Push as ClienteMotivacional3Push;
  21. use App\Notifications\Push\Cliente\Recorrencia\Recorrencia1Push;
  22. use App\Notifications\Push\Cliente\Recorrencia\Recorrencia2Push;
  23. use App\Notifications\Push\Cliente\Recorrencia\Recorrencia3Push;
  24. use App\Notifications\Push\Cliente\SocialProof\SocialProof1Push;
  25. use App\Notifications\Push\Cliente\SocialProof\SocialProof2Push;
  26. use App\Notifications\Push\Prestador\Motivacional\Motivacional1Push as PrestadorMotivacional1Push;
  27. use App\Notifications\Push\Prestador\ReforcoEducativo\ReforcoEducativo1Push;
  28. use App\Notifications\Push\Prestador\ReforcoEducativo\ReforcoEducativo2Push;
  29. use Illuminate\Support\Collection;
  30. class PushNotificationDispatcher
  31. {
  32. public function __construct(private PushNotificationService $pushService) {}
  33. /**
  34. * Lista central de todas as notificações registradas.
  35. * Para adicionar uma nova: basta instanciá-la aqui.
  36. *
  37. * @return BasePushNotification[]
  38. */
  39. public function all(): array
  40. {
  41. return [
  42. // Prestador
  43. new ReforcoEducativo1Push,
  44. new ReforcoEducativo2Push,
  45. new PrestadorMotivacional1Push,
  46. // Cliente — Marketing
  47. new Marketing1Push,
  48. new Marketing2Push,
  49. new Marketing3Push,
  50. new Marketing4Push,
  51. // Cliente — Recorrência
  52. new Recorrencia1Push,
  53. new Recorrencia2Push,
  54. new Recorrencia3Push,
  55. // Cliente — Educativo
  56. new Educativo1Push,
  57. new Educativo2Push,
  58. new Educativo3Push,
  59. new Educativo4Push,
  60. // Cliente — Educativo + Conversão
  61. new EducativoConversao1Push,
  62. new EducativoConversao2Push,
  63. // Cliente — Social Proof
  64. new SocialProof1Push,
  65. new SocialProof2Push,
  66. // Cliente — Motivacional
  67. new ClienteMotivacional1Push,
  68. new ClienteMotivacional2Push,
  69. new ClienteMotivacional3Push,
  70. // Cliente — Contextual
  71. new ContextualSextaPush,
  72. new ContextualSegundaPush,
  73. new ContextualVisitaPush,
  74. ];
  75. }
  76. /**
  77. * Processa todas as notificações: aplica cooldowns e envia para elegíveis.
  78. */
  79. public function dispatch(): void
  80. {
  81. foreach ($this->all() as $notification) {
  82. $users = $notification->eligibleUsers();
  83. if ($users->isEmpty()) {
  84. continue;
  85. }
  86. $filtered = $this->applyCooldowns($users, $notification);
  87. if ($filtered->isEmpty()) {
  88. continue;
  89. }
  90. $this->pushService->sendToUsers($filtered, $notification);
  91. }
  92. }
  93. /**
  94. * Remove da coleção os usuários que ainda estão em cooldown
  95. * (tanto de categoria quanto de notificação específica).
  96. */
  97. private function applyCooldowns(Collection $users, BasePushNotification $notification): Collection
  98. {
  99. $userIds = $users->pluck('id');
  100. $blockedByCategory = collect();
  101. if ($notification->categoryCooldownDays() > 0) {
  102. $blockedByCategory = PushNotificationLog::whereIn('user_id', $userIds)
  103. ->where('target', $notification->target()->value)
  104. ->where('category', $notification->category()->value)
  105. ->where('sent_at', '>=', now()->subDays($notification->categoryCooldownDays()))
  106. ->pluck('user_id')
  107. ->unique();
  108. }
  109. $blockedByNotification = PushNotificationLog::whereIn('user_id', $userIds)
  110. ->where('label', $notification->label())
  111. ->where('sent_at', '>=', now()->subDays($notification->notificationCooldownDays()))
  112. ->pluck('user_id')
  113. ->unique();
  114. $blocked = $blockedByCategory->merge($blockedByNotification)->unique();
  115. return $users->whereNotIn('id', $blocked)->values();
  116. }
  117. }