Queue Job not saving to Tenant database and not using Tenant SMTP

287 Views Asked by At

I have a multi-tenant setup which allows each tenant to save their own SMTP information in a settings table. The job being saved right now is being sent to the system database instead of the tenant. This is causing an issue as a Service Provider is setup to configure the mail configuration on boot() to each of the provided values in the database. With the worker running the email job does send but uses the stored system SMTP values instead of the tenants - which I assume is just because it's looking in the same database as the current job's connection.

Service Provider

class TenantEmail extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
        Config::set('mail.host', setting('admin.email_host'));
        Config::set('mail.port', setting('admin.email_port'));
        Config::set('mail.encryption', setting('admin.email_encrypt'));
        Config::set('mail.username', setting('admin.email_username'));
        Config::set('mail.password', setting('admin.email_password'));
    }
}

SendEmail Job

Looking over the documentation on Hyn is looks like I can force set the tenant website Id during the dispatch but that didn't make a difference.

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $user;
    public $sub;
    public $content;
    public $unsubscribeUrl;
    public $replyAddress;
    public $website_id;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($row, $subject, $message, $unsubscribeUrl, $replyTo,int $website_id)
    {
        //
        $this->user = $row;
        $this->sub = $subject;
        $this->content = $message;
        $this->unsubscribeUrl = $unsubscribeUrl;
        $this->replyAddress = $replyTo;
        $this->website_id = $website_id;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
        $email = new ConnectEmail($this->user, $this->sub, $this->content, $this->unsubscribeUrl, $this->replyAddress);
        Mail::to($this->user->email_address, $this->user->name)->send($email);
    }
}
1

There are 1 best solutions below

0
On BEST ANSWER

Not the cleanest approach perhaps but I was able to solve this by passing the SMTP information in my email controller when I dispatch the job.

$smtp = [
   'host' => setting('admin.email_host'),
   'port' => setting('admin.email_port'),
   'encryption' => setting('admin.email_encrypt'),
   'username' => setting('admin.email_username'),
   'password' => setting('admin.email_password')
 ];
 $emailJob = (new SendEmail($row, $subject, $message, $unsubscribeUrl, $replyTo, $websiteId, $smtp));
 dispatch($emailJob)->delay($scheduleSend);

Then in my SendEmail job I just include the $smtp in the ConnectEmail and pass that over to the mailable, which in the init construct I just add in:

if(!empty($smtp)){
   Config::set('mail.host', $smtp['host']);
   Config::set('mail.port', $smtp['port']);
   Config::set('mail.encryption', $smtp['encryption']);
   Config::set('mail.username', $smtp['username']);
   Config::set('mail.password', $smtp['password']);
}

This then queues up and sends the job using the dynamic SMTP information without a problem.