WooCommerce’s background email feature

WooCommerce has the option to defer/background-send its emails instead of sending them while processing the action the visitor has taken. This can have a few benefits for customers visiting your store:

  • If their actions on the store are crashing when sending emails (such as the “new account” email), deferring the emails can let the customer continue with their order.
  • The site may be more responsive because less work is being performed for each action the customer takes.

However, the background email functionality is newer and less-tested.

The current default (as of this writing in July of 2019) is to send the emails immediately. You may come across other pages mentioning the deferred emails as being the default, but that’s because the default has been changed twice.

Enabling deferred emails

Adding this code to your functions.php (or a plugin file) will cause emails to be sent in a background task:

add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );

Or use this code to ensure the default behavior (sending emails during the processing of the user’s request) in case it’s been changed by other code:

add_filter( 'woocommerce_defer_transactional_emails', '__return_false', PHP_INT_MAX );

Disabling sending of the deferred/background email

I originally thought the woocommerce_allow_send_queued_transactional_email hook would be useful for temporarily disabling queued mail sending while troubleshooting. But as far as I can tell from digging into the code, the email task will be considered “completed” whether or not it’s allowed to be sent by the filter. However, if that’s useful in some way, you can turn off the sending with:

add_filter( 'woocommerce_allow_send_queued_transactional_email', '__return_false' );

How it works behind the scenes

High-level

WooCommerce uses the WP Background Processing library to manage queuing and running the background emails. WC_Email acts as a middleman for the following notifications, forwarding them to their “real” versions which have a “_notification” suffix:

  • woocommerce_created_customer
  • woocommerce_low_stock
  • woocommerce_new_customer_note
  • woocommerce_no_stock
  • woocommerce_order_fully_refunded
  • woocommerce_order_partially_refunded
  • woocommerce_order_status_cancelled_to_completed
  • woocommerce_order_status_cancelled_to_on-hold
  • woocommerce_order_status_cancelled_to_processing
  • woocommerce_order_status_completed
  • woocommerce_order_status_failed_to_completed
  • woocommerce_order_status_failed_to_on-hold
  • woocommerce_order_status_failed_to_processing
  • woocommerce_order_status_on-hold_to_cancelled
  • woocommerce_order_status_on-hold_to_failed
  • woocommerce_order_status_on-hold_to_processing
  • woocommerce_order_status_pending_to_completed
  • woocommerce_order_status_pending_to_failed
  • woocommerce_order_status_pending_to_on-hold
  • woocommerce_order_status_pending_to_processing
  • woocommerce_order_status_processing_to_cancelled
  • woocommerce_product_on_backorder

If a custom email needs other notifications, the woocommerce_email_actions filter can be used to append to the array.

The details

WC_Emails::init_transactional_emails hooks the above email-triggering actions with queue_transactional_email for background emailing or send_transactional_email for immediate emailing. queue_transactional_email uses an instance of WC_Background_Emailer to queue the hook and its arguments for later execution by WP-Cron. When it’s later executed, it calls back into WC_Emails::send_queued_transactional_email. If the woocommerce_allow_send_queued_transactional_email filter (true by default) allows it, the hook appended with “_notification” is executed, allowing the email to be sent. There doesn’t appear to be any conditional logic allowing it to retry later, so I don’t think woocommerce_allow_send_queued_transactional_email is an effective way of temporarily disabling email you want to send later.

You’ve made it to the end of the article…

…which is a stunning feat. As a reward, here are 3 randomly-generated emojis that will surely tell a compelling story:

Leave a Comment

Your email address will not be published. Required fields are marked *