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);
}
}