Skip to content
Advertisement

How to also send BCC to specific address during development with Symfony Mailer?

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?

Advertisement

Answer

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 SymfonyComponentEventDispatcherEventSubscriberInterface;
use SymfonyComponentMailerEventMessageEvent;
use SymfonyComponentMimeMessage;

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:
  AppEventDispatcherManipulateBcc:
    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.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement