cms icon indicating copy to clipboard operation
cms copied to clipboard

Send Form Emails in a separate Job

Open okaufmann opened this issue 3 years ago • 6 comments

Hi @jasonvarga

We are using many Statamic Forms in a big project. The service we use to send mails is unfortunately very unstable. In the latest version, Statamic sends all E-Mails in a loop by the SendEmails Job.

$this->emailConfigs($this->submission)->each(function ($config) {
    Mail::send(new Email($this->submission, $config, $this->site));
});        

https://github.com/statamic/cms/blob/3.3/src/Forms/SendEmails.php#L29

This is a problem because of the following reasons:

  • When a Form has multiple Email configs to send and a single mail fails, the other may not be sent.
  • We cannot add any Laravel Job configs like retries or backoff to handle this behaviour.

This PR removes the queuability fromSendEmails and only sends Emails in a new job SendEmail. Further it adds a new config value in the forms namespace to customize the job that is used to send that single mail.

This solves the problems mentioned, as we now can create a new custom SendEmail job class like the following:

<?php

namespace App\Notifications;

use Statamic\Contracts\Forms\Submission;
use Statamic\Forms\SendEmail;
use Statamic\Sites\Site;

class SendStatamicEmail extends SendEmail
{
    public $tries = 3;

    public function __construct(Submission $submission, Site $site, $config)
    {
        parent::__construct($submission, $site, $config);

        $this->queue = 'emails';
    }

    public function backoff()
    {
        return [5, 10, 30];
    }
}

And set it in the config:

<?php

return [
    'send_mail_job' => \App\Notifications\SendStatamicEmail::class,
];

I also thought about config values to set the queue properties from the forms config file but as this will probably not be done much this would blow up the config file unnecessarily.

If you have a better Idea, I'm open to change this PR to match your requirements.

okaufmann avatar Aug 09 '22 14:08 okaufmann

In the latest version, Statamic sends E-Mails all in SendEmails in a loop.

I assume you saw my recent PR. Just to clarify, it's always looped through the email configs and sent the emails in a loop. That was nothing new.

This is a good PR though, thanks!

jasonvarga avatar Aug 09 '22 14:08 jasonvarga

Yes, that was a reason, that I created a PR as the Email sending is now covered by the tests (I will solve the failing tests now).

okaufmann avatar Aug 09 '22 14:08 okaufmann

Now the tests are green.

I needed to add another method to get the jobs and be able to call handle on them. Otherwise, dispatch would be called and the tests would be more complex.

What do you think?

okaufmann avatar Aug 09 '22 16:08 okaufmann

I can't push changes to your branch. Can you apply this?

https://gist.github.com/jasonvarga/20c8f6ceff5d1fa0c70f97de449e363c

It changes the SendEmails test to check that the mutiple jobs are dispatched, and adds a new test to check that the single email is sent.

jasonvarga avatar Aug 09 '22 16:08 jasonvarga

I've applied your patch and mentioned you as Co-Author. Thank you for helping me out!

okaufmann avatar Aug 09 '22 18:08 okaufmann

If there is anything else I need to do for this PR, please let me know.

okaufmann avatar Aug 10 '22 14:08 okaufmann

Closing in favor of #6481 - Thanks!

jasonvarga avatar Aug 11 '22 14:08 jasonvarga

We cannot find out, why we can't permit you to push to this PR... But thanks for the merge 🎉

okaufmann avatar Aug 12 '22 12:08 okaufmann

It's something to do with the repo being on an organization account. When it's a personal fork I never have trouble pushing. Never worked it out. 🤷

jasonvarga avatar Aug 12 '22 14:08 jasonvarga

Ah! Next time I'll use my personal fork then. Thank you 👌 Have a great weekend 🎉

okaufmann avatar Aug 12 '22 15:08 okaufmann