src/Aqarmap/Bundle/MainBundle/EventListener/BouncedEmailListener.php line 27

  1. <?php
  2. namespace Aqarmap\Bundle\MainBundle\EventListener;
  3. use Aqarmap\Bundle\MainBundle\Event\SNSNotificationsEvent;
  4. use Aqarmap\Bundle\NotificationBundle\Model\SESNotificationData;
  5. use Aqarmap\Bundle\UserBundle\Entity\User;
  6. use Aqarmap\Bundle\UserBundle\Services\UserManager;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. /**
  10. * Bounced Email Listener
  11. * This listener handles bounced and complained emails by globally unsubscribing affected users.
  12. */
  13. class BouncedEmailListener implements EventSubscriberInterface
  14. {
  15. public function __construct(private readonly EntityManagerInterface $em, private readonly UserManager $userManager)
  16. {
  17. }
  18. public function handleBouncedEmail(SNSNotificationsEvent $event): void
  19. {
  20. /** @var SESNotificationData $message */
  21. $message = $event->getMessage();
  22. if (preg_match('/bounce/i', (string) $message->getEventType())) {
  23. if (preg_match('/permanent/i', $message->getBounce()->getBounceType())) {
  24. foreach ($message->getBounce()->getBouncedRecipients() as $recipient) {
  25. $email = $recipient['emailAddress'] ?? null;
  26. if (!$email) {
  27. continue;
  28. }
  29. /** @var User $user */
  30. $user = $this->em->getRepository(User::class)->findOneBy(['emailCanonical' => $email]);
  31. if ($user) {
  32. $user->setHasEmail(false);
  33. $this->userManager->globalUnsubscribe($user, false);
  34. }
  35. }
  36. $this->em->flush();
  37. }
  38. }
  39. }
  40. public function globalUnsubscribe(SNSNotificationsEvent $event): void
  41. {
  42. $message = $event->getMessage();
  43. foreach ($message->getMail()->getDestination() as $email) {
  44. /** @var User $user */
  45. $user = $this->em->getRepository(User::class)->findOneBy(['emailCanonical' => $email]);
  46. if ($user) {
  47. $this->userManager->globalUnsubscribe($user);
  48. }
  49. }
  50. }
  51. public static function getSubscribedEvents(): array
  52. {
  53. return [
  54. SNSNotificationsEvent::SNS_NOTIFICATION_BOUNCE => ['handleBouncedEmail'],
  55. SNSNotificationsEvent::SNS_NOTIFICATION_COMPLAINT => ['globalUnsubscribe'],
  56. ];
  57. }
  58. }