#Set Postmark token dynamically on queued emails

2 messages · Page 1 of 1 (latest)

dawn island
#

Context
When a user (tenant) signs up on my app, a new Postmark server is spun up via API, and a Postmark API token is saved for each tenant.

Problem
I need to inject the tenant's API token on each mail that they send, in order to hit the Postmark API with that specific token.

If I send an email with a sync queue, doing a simple \Config::set('services.postmark.token', $company->postmark_api_token); is fine, but as soon as I use an "async" queue driver (eg. redis or database) the email manager picks up the site-wide token that's in the .env file.

What I tried so far
I tried to workaround this by setting the config in the mailable constructor, but it seems like the worker would still pick the site-wide configuration.

I also tried to create a new MailManager with a new email transport using the tenant's token, but that also didn't do the trick (it errors out claiming that there were no X-Postmark-Token headers in the request, despite me being able to inspect the injected config and the API key was there ...)

class MyEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public function __construct(
        public string $emailSubject,
        public string $emailBody,
        public Authenticatable|User $fromUser,
    )
    {
        $company = $this->fromUser->company;
        
        // Mail::fake() in tests will fail without the check, as it doesn't have a `createSymfonyTransport()` method
        if (app()->environment('production')) {
            $customConfiguration = \Mail::createSymfonyTransport([
                'transport' => 'postmark',
                'token' => $company->postmark_api_token,
            ]);

            \Mail::setSymfonyTransport($customConfiguration);
        }
    }
dawn island