Link to home
Start Free TrialLog in
Avatar of worthyking1
worthyking1Flag for United States of America

asked on

Woocommerce: How to dynamically replace default new order email notification sender FROM address with customer's email address??

I am trying to modify the Woo Commerce new_order (admin) email notification function to change the default FROM address to the customer's name & email address.  You would think this would be simple and yet I have wasted many hours to no avail.

Essentially, all I need to do is hook into the woocommerce_email_from_address filter and replace the $from_address value with the customer's email address, however I cannot figure out how to access the $order object during this hook in order to get the $order->get_billing_email() value and assign it to $from_address in the filter.

I have tried many things, including an action hook on woocommerce_new_order, getting the customer details there and then saving them to a global variable (also tried setting them into a cookie), but still when my woocommerce_email_from_address filter fires the $from_address returned value is always blank.

This is the current (non-working) version of what I have in my child theme functions.php file:

add_action( 'woocommerce_new_order', 'get_the_customer_details', 10, 1 );

function get_the_customer_details( $order_id ) {
    
     // Get an instance of the WC_Order object
     $order = wc_get_order( $order_id );

     global $rhpname, $rhpcustomeremail;

    $rhpname = $order->get_billing_first_name().' '.$order->get_billing_last_name();
    $rhpcustomeremail = $order->get_billing_email();
    if(empty($rhpcustomeremail))    { $rhpcustomeremail = 'support@mydomain.com'; }
    	
    setcookie("rhpname", $rhpname, time() + (360), "/"); // 86400 = 1 day
    setcookie("rhpcustomeremail", $rhpcustomeremail, time() + (360), "/"); // 86400 = 1 day

}

// Change sender name
add_filter( 'woocommerce_email_from_name', function( $from_name, $wc_email ){
    if( $wc_email->id == 'new_order' ) 
    {
        $cookie_name = "rhpname";
        if(!isset($_COOKIE[$cookie_name])) {
            $from_name = $_COOKIE[$cookie_name];
        } else {
            $from_name = 'RHP WooCommerce Store';
        }
        
    }
    return $from_name;
}, 11, 2 );

// Change sender adress
add_filter( 'woocommerce_email_from_address', function( $from_email, $wc_email ){
    if( $wc_email->id == 'new_order' )
    {
        $cookie_name = "rhpcustomeremail";
        if(!isset($_COOKIE[$cookie_name])) {
            $from_email = $_COOKIE[$cookie_name];
        } else {
            $from_email = 'support@mydomain.com';
        }
        
    }   
    return $from_email;
}, 11, 2 );

Open in new window

Avatar of David Favor
David Favor
Flag of United States of America image

If I understand what you're describing, if you're successful this may break all admin email.

Also this will make all your mail 100% non-deliverable. Here's why...

If someone, foo@flarg.com places an order + you rewrite the From address to foo@flarg.com + send an email...

Your mail sending IP will be absent from the flarg.com DNS SPF record, so all your mail sent in this way will be 100% SPAM + nearly 100% undelivered (bounced or blocked or dropped or spammed).

Be very careful when you break SMTP message envelops, as seemingly minor changes make you a spammer + if you send enough SPAM over a short period, you'll end up on an RBL, so all mail sent by your domain and/or sending IPs can become blacklisted.
Avatar of worthyking1

ASKER

@DavidFavor

We are not concerned with this deliverability aspect because these new order emails are ONLY going to our own company mail server, and we are expecting them to come in with a "spoofed" FROM header, so have accounted for that on our spam filtering end of things.

The only purpose for needing to do this is so that the order notification emails are automatically linked to the customer record in our in-house CRM when the order notification email arrives.

ALL other email sending from Woo and WP will remain unchanged and thus won't have any spam implications. This is purely a specific use-case only for new order email notifications sent to us.
Agree with David on this. Most servers are configured to NOT send emails out if they're not from a 'known' host - i.e. your own domain name. Regardless of whether you've set up Spam filtering or not is somewhat moot - the email will never get sent, so it will never hit your mail server and therefore never even see the spam filter.

Generally, this is why a server sending emails will set the FROM address to something lke no-reply@yourdomain.com and the REPLY-TO address to customer@theirdomain.com - this way it can be safely sent from the Server, and easily replied to by the receiver.
@Chris

Actually, the emails DO get sent from our Woo server. I have tested this many times and the emails do arrive IF I manually set a From address, for example:

// Change sender adress
add_filter( 'woocommerce_email_from_address', function( $from_email, $wc_email ){
    if( $wc_email->id == 'new_order' )
    {
            $from_email = 'foo@test.com';
        }
    return $from_email;
}, 11, 2 );

The above code works and sends us the new order email "From" foo@test.com, and our spam filtering allows it into the sales orders inbox without a hitch.

HOWEVER, my problem is figuring out HOW to get the $order->get_billing_email() value into the $from_email return value.

That's the only issue we have and the reason for this question.  I appreciate your comments & concerns regarding spam and mail deliverability, however those are not relevant to us in this one unique scenario.
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@Chris

Dude, you rock!  I knew the answer was simple but it was like digging for a needle in a haystack with the Woo documentation.

It works perfectly. I just added a couple little tweaks to check for empty values (the owner insists on NOT requiring customers enter an email address), but otherwise your code was perfect as-is.

You are a life saver! Thanks again!!

p.s. How did you find out the $wc_email parameter passed the object property etc.? Is there a reference guide you use or a code stack tracer plugin or something?
Good stuff - glad you got it sorted.

Figured it out with a bit or digging in the docs and by debugging a live 'add order' process (debug in VS code with a break point on the function - you get to see the full details of what's passed in and can see that the 'order' property was an instance of WC_Order).