- ๐จ๐ญSwitzerland ayalon
@gilbertdelyon
You created a lot of threads and issues on Drupal.org regarding this topic. Several module maintainers helped you.Unfortunately, you did not share your solution and the code of your custom module which could help others. This is a bit sad.
Maybe you can rethink this and share your code?
Thanks in advance.
- ๐ฎ๐ณIndia agudivad
@gilbertdelyon,
It is good to know that you are able to achieve it with custom module. Request you to help us by sharing it.
Regards
Ajaykumar Gudivada - ๐ซ๐ทFrance gilbertdelyon
Sorry, I am only a poor old (very old!) part time hobyist self made developper and I did not have in mind that my poor skills could help confirmed coders!
In addition I have been very busy these monthes without any time for Drupal.
So, let me explain how it works in my very humble module:
Please notice that this custom module is taylor made for my needs, so you will see hereunder only some abstracts in regard with mailing:1 - Queueing:
Drupal queing is very simple to use (you only have to google a bit!):
Somewhere in your code you will prepare the data that will be used for your mailng and then, thanks to the above function you will queue this data. Then it will be used at next CRON ./** * Somewhere in you module * for example in a custom service * */ /** * Queueing function * $notifdata is an array that will include all the resqted stuff for mail processing (subject, content, to, from,...) * Each item of the array is for ONE email * */ protected function queueing($notifdata){ $queue = \Drupal::queue('my_queue_name'); $queue->createQueue(); foreach ($notifdata as $item => $value){ $queue->createItem($value); //One queue item per email }//end foreach }//end function
Cannot be more simple!
2 - Unqueueing:
Unqueing can be made in different ways:
- Old fashion by way of ahook_cron()
function
- New fashion by way of a queueWorker.
As I am an old guy I will use the old fashion.So, here is the
hook_cron()
function inmy_module.module
file/** * Implements hook_cron() * This function will send email at each crom * */ function mycustommodule_cron() { //My queue $myqueue = \Drupal::queue('my_queue_name'); // Number of queue items to be sent at each cron // (You have to set this value somewhere in you module config) $nbitems = mycustommodule_settings()["maxiItemsPerCron"]; //Items processing for ($i=0; $i<($nbitems); $i++){ // Test if items to be processed from the queue // $queue->claimItem() returns only one item from the queue if ($queue_item = $myqueue->claimItem()) { //Extract data from item $notifdata = $queue_item->data; //Send Email (using a custom service ) $notif = \Drupal::service('my_custom_service'); $sendnotif = $notif->sendnotif2users($notifdata); // sendnotif2users() method is now trigered //Delete item if success if($sendnotif){ $myqueue->deleteItem($queue_item); }//fin if }//fin if }//fin for }//end function
3 - Sending the emails
In my custom module, heach time an item will be unqueued inhook_cron()
the sendnotif2users() method (frommy_custom_service
) will be triggered.
You can also simply use a function. IMHO services is the best way./** * In my_custom_service file * */ namespace Drupal\node2notifs\NotifServices; use Drupal\Core; //Complรฉments pour envoi mails avec SymfonyMailer use Symfony\Component\Mailer\Transport; use Symfony\Component\Mailer\Mailer; use Symfony\Component\Mime\Email; /** * This function will mainly process the email content and trigger the sending process (one email per target adress) * */ public function sendnotif2users($notifdata) { // Prossessing the email content $this->mailcontents($notifdata); // mailcontents() to be coded as as per your needs // Targets $targets = ["name1@domain1","name2@domain2","name3@domain3","name4@domain4", ];// array of all target email adresses //Sending loop foreach($targets as $item => $to){ $this->to = $to; $this->sendEmail();//here we send an email only ONE email }//fin foreach return TRUE; //This will allow queue item delete in hook_cron() }//fin public function
4 - And finally the mail is sent via SymfonyMailer
Of course you have to install Symfony Mailer and use the relative classes in your service (see heareabove)/** * This function will send the email with help of SymfonyMailer * */ public function sendEmail() { $email = (new Email()) ->from( \Drupal::config('system.site')->get('mail')) ->to($this->to) //->cc('cc@example.com') //->bcc('bcc@example.com') //->replyTo('replyto@example.com') //->priority(Email::PRIORITY_HIGH) ->subject($this->subject) ->text( $this->plaintextbodybuilder() ) ->html( $this->htmlbodybuilder() ); $transport = Transport::fromDsn('sendmail://default'); $mailer = new Mailer($transport); $mailer->send($email); }//fin function
Please forgive some possible mistakes, I am only a poor hobbyist.
I hope this can help - ๐ฎ๐ณIndia agudivad
Thank you so much! @gilbertdelyon for sharing these details.
- ๐ฆ๐บAustralia dpi Perth, Australia
Symfony Mailer has inbuilt support for Messenger with precisely this feature: https://symfony.com/doc/current/mailer.html#sending-messages-async
I'm presently working on Symfony Messenger integration, which is effectively Emails to Queues suggested by this issue.
See โจ Add Symfony Messenger support for async messsages (emails as queues) Active
As of this writing, Messenger integration is in active development; not ready for public consumption yet. Though it works great locally!
- ๐ฌ๐งUnited Kingdom adamps
Great thanks @dpi. We now have two issues for the same thing, so let's close one as a duplicate.
- Status changed to Closed: duplicate
about 1 year ago 7:32pm 15 October 2023 - ๐ฆ๐บAustralia dpi Perth, Australia
Despite this issue being older I'm going to close as a dupe as suggested.
I think the solution is different enough to support this.
I think there could ultimately be multiple solutions implemented. If a different proposal and solution is devised then this issue could be reopened.
- ๐ซ๐ทFrance gilbertdelyon
#13 โจ Queue emails to send in background Closed: duplicate
Sounds good. I am impatiently waiting for the next release!