3

Symfony provides a way to send all emails to a specific email address during debugging and development but addressees in the BCC still receive the e-mail. This is very dangerous because you don't want to send out any emails from your local dev environment.

Is there a way to also deliver BCCs to a specific email address?

yivi
  • 42,438
  • 18
  • 116
  • 138
Sil
  • 1,120
  • 1
  • 9
  • 30

2 Answers2

4

I wouldn't discount having your own wrapper service for Mailer. I have to admit I usually do that, since more often than not I consider the sending of emails too close to the application concerns, and I may want more freedom and flexibility than simply coupling myself to the frameworks package, as good as it may be.

That being said, Symfony's method of changing the recipients does not work with Bcc, because Bcc is part of the message, while the listener that changes the recipients manipulates the envelope.

You could create your own EventListener to manipulate the bcc header:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Mime\Message;

class ManipulateBcc implements EventSubscriberInterface
{

    private bool $removeExisting;
    private array $forcedBcc;

    public function __construct(bool $removeExisting = false, array $forcedBcc = [])
    {
        $this->removeExisting = $removeExisting;
        $this->forcedBcc      = $forcedBcc;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            MessageEvent::class => ['onMessage', -224],
        ];
    }

    public function onMessage(MessageEvent $event): void
    {
        if ( ! $this->removeExisting) {
            return;
        }

        $message = $event->getMessage();
        if ( ! $message instanceof Message) {
            return;
        }
        $headers = $message->getHeaders();

        if ($headers->has('bcc')) {
            $headers->remove('bcc');
        }

        if ( ! empty($this->forcedBcc)) {
            $headers->addMailboxListHeader('bcc', $this->forcedBcc);
        }
    }
}

By default, this does nothing. With the default configuration the eventlistener will be run but since removeExisting will be false, the listener will return without doing anything.

To enable it, you could add the following to services_dev.yaml, so it's only enabled during development:

# config/services_dev.yaml

services:
  App\EventDispatcher\ManipulateBcc:
    autoconfigure: true
    arguments:
      $removeExisting: true
      $forcedBcc:
        - 'fake.email@mailinator.com'
        - 'even.faker@mailinator.com'

This was hastily written, and you cannot force BCCs without removing BCCs, which may be sufficient for many purposes but maybe not to your own. Use this as a starting point until it does what you need.

yivi
  • 42,438
  • 18
  • 116
  • 138
  • 1
    I was hoping for a config only solution but this seems to work just fine, thank you! – Sil Nov 23 '20 at 08:30
-1

The only way which I think of right now is to create your own wrapper service for the mailer and check the environment if it’s dev just remove the BCC... you don’t need them anyway.

Alexander Dimitrov
  • 944
  • 1
  • 6
  • 17