Send a custom email with a dynamic subject and recipient in Woocommerce - php

In Woocommerce, I have been able to create custom meta box with a button, which send an email, using Send a custom email when WooCommerce checkout button is pressed existing answer code. It displays the following metabox:
So when I click the button it sends an email, which works just fine.
My question:
How I can customize that code to send custom email as I need to send "Subject" only (with order id and payment total) to email address, which should be in format: mobilenumber#domain.com (so it will be send to SMS gateway and delivered as SMS on a mobile device)?
For example:
Email address: 123456789#smsgateway.com
subject: Your order {order_id} has been done. Total: {order_total}. Thank you

Updated
The first function is optional and will display a required checkout field for the mobile phone.
The second function code display a metabox in woocommerce admin order edit pages with a custom button that will trigger the action. When pressed it will send custom email to the SMS gateway with:
a specific dynamic subject containing the order number and the total amount
a specific email address made of the customer mobile phone and a specific SMS gateway domain name like 'smsgateway.com'.
Note: When using wp_mail() function, the message is mandatory (if there is no message or an empty one, the email is not sent).
The code:
// 1. Add mandatory billing phone field (and save the field value in the order)
add_filter( 'woocommerce_billing_fields', 'add_billing_mobile_phone_field', 20, 1 );
function add_billing_mobile_phone_field( $billing_fields ) {
$billing_fields['billing_mobile_phone'] = array(
'type' => 'text',
'label' => __("Mobile phone", "woocommerce") ,
'class' => array('form-row-wide'),
'required' => true,
'clear' => true,
);
return $billing_fields;
}
// 2. Send a specific custom email to a SMS gateway from a meta box
// Add a metabox
add_action( 'add_meta_boxes', 'order_metabox_email_to_sms' );
function order_metabox_email_to_sms() {
add_meta_box( 'sms_notification',
__( 'SMS notification', "woocommerce" ),
'order_metabox_content_email_to_sms',
'shop_order', 'side', 'high' );
}
// Metabox content: Button and SMS processing script
function order_metabox_content_email_to_sms(){
global $pagenow;
if( $pagenow != 'post.php' || get_post_type($_GET['post']) != 'shop_order' )
return; // Exit
if ( ! ( isset($_GET['post']) && $_GET['post'] > 0 ) )
return; // Exit
$order_id = $_GET['post'];
$is_sent = get_post_meta( $order_id, '_sms_email_sent', true );
// Sending SMS
if ( isset($_GET['send_sms']) && $_GET['send_sms'] && ! $is_sent ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Using the billing mobile phone if it exist, or the billing phone if not.
if( $mobile_phone = $order->get_meta( '_billing_mobile_phone' ) ) {
$phone = $mobile_phone;
} else {
$phone = $order->get_billing_phone();
}
// Email address: Customer mobile phone + # + sms domain
$send_to = $phone . '#' . 'smsgateway.com';
// Subject with the order ID and the order total amount
$subject = sprintf(
__("Your order number %d with a total of %s is being processed. Thank you.", "woocommerce"),
$order_id, html_entity_decode( strip_tags( wc_price( $order->get_total() ) ) )
);
// Message: It is required (we just add the order number to it).
$message = $order_id;
// Sending this custom email
$trigger_send = wp_mail( $send_to, $subject, $message );
// Displaying the result
if( $trigger_send ) {
$result = '<span style="color:green;">' ;
$result .= __( "The SMS is being processed by the gateway." );
// On email sent with success, Mark this email as sent in the Order meta data (To avoid repetitions)
update_post_meta( $order_id, '_sms_email_sent', $trigger_send );
} else {
$result = '<span style="color:red;">' ;
$result .= __( "Sorry, but the SMS is not processed." );
}
$result .= '</span>';
}
// Displaying the button
$href = '?post=' . $order_id . '&action=edit&send_sms=1';
$send_text = isset($is_sent) && $is_sent ? '<em><small style="float:right;"> ('. __("Already sent") . ')</small></em>' : '';
echo '<p>' . __( "Send SMS" ) . ''.$send_text.'</p>';
// Displaying a feed back on send
echo isset($result) ? '<p><small>' . $result . '</small></p>' : false;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
The four possibilities within this metabox:
Once the SMS is sent once, the feature becomes inactive, to avoid any repetitions.

Related

Send an email notification to customer when a specific coupon code is applied in WooCommerce

I am trying to send an email to the customer after he has used a specific promo code 'FREECLASS' while checking out.
What I do is send the customer a code 'FREECLASS' after signing up. I want the customer to get an additional custom message after he uses that code.
Based on Send an email notification when a specific coupon code is applied in WooCommerce answer code, this is what I have done up until now but it is not working.
add_action( 'woocommerce_applied_coupon', 'custom_email_on_applied_coupon', 10, 1 );
function custom_email_on_applied_coupon( $coupon_code ){
if( $coupon_code == 'FREECLASS' ){
// Get user billing email
global $user_login;
$user = get_user_by('login', $user_login );
$email = $user->billing_email;
$to = "$email"; // Recipient
$subject = sprintf( __('Coupon "%s" has been applied'), $coupon_code );
$content = sprintf( __('The coupon code "%s" has been applied'), $coupon_code );
wp_mail( $to, $subject, $content );
}
}
This is my first WooCommerce project so some help would be really appreciated.
There is no need to use global variables, via $user_id you can get the WC_Customer instance Object and then the billing email address
wp_mail() - Sends an email, similar to PHP’s mail function
So you get:
function action_woocommerce_applied_coupon( $coupon_code ) {
// NOT logged in, return
if ( ! is_user_logged_in() ) return;
// Compare
if ( $coupon_code == 'freeclass' ) {
// Get user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object
$customer = New WC_Customer( $user_id );
// Billing email
$email = $customer->get_billing_email();
// NOT empty
if ( ! empty ( $email ) ) {
// Recipient
$to = $email;
$subject = sprintf( __('Coupon "%s" has been applied', 'woocommerce' ), $coupon_code );
$content = sprintf( __('The coupon code "%s" has been applied by a customer', 'woocommerce' ), $coupon_code );
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $content, $headers );
}
}
}
add_action( 'woocommerce_applied_coupon', 'action_woocommerce_applied_coupon', 10, 1 );

Send custom WooCommerce mail with user credentials after order with certain product

I am trying to send a custom WooCommerce mail with user credentials after an order with certain product. To explain further: Someone buys a product
I have to check if the order contains a certain product id
I have to check if the customer is registered as a user already, if not it should create a user
Then it should send a custom mail with those credentials to the customer
I am struggling to get the following code to work. Especially I dont know how I can add my custom email-message with the credentials and a custom login link. Do you know a solution?
add_action( 'woocommerce_thankyou', 'check_order_product_id' );
function check_order_product_id( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
$order_email = $order->billing_email;
//create custom mail
function get_custom_email_html( $order, $heading = false, $mailer ) {
$template = 'emails/my-custom-email-i-want-to-send.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => false,
'plain_text' => false,
'email' => $mailer
) );
}
// load the mailer class
$mailer = WC()->mailer();
//format the email
$recipient = $order_email;
$subject = __("Deine Login-Daten für Geomap", 'theme_name');
$content = get_custom_email_html( $order, $subject, $mailer );
$headers = "Content-Type: text/html\r\n";
//send the email through wordpress
$mailer->send( $recipient, $subject, $content, $headers );
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
function email_exists( $order_email ) {
$user = get_user_by( 'email', $order_email );
if ( $user ) {
return $wp_new_user_notification_email;
}
else {
// random password with 12 chars
$random_password = wp_generate_password();
// create new user with email as username & newly created pw
$user_id = wp_create_user( $order_email, $random_password, $order_email );
return $wp_new_user_notification_email;
}
}
}
}
}
Because you mentioned low barrier to entry being very important...
I'd recommend linking to your thank you page and having the registration link there too. You can use SSO (Google/Amazon/etc.) options so that users don't need to register directly through WordPress.
I'm assuming the product ID has some kind of activation code? You can send that, encrypted, as a parameter to the registration page so that it's registered in their session. Once logged in, you have attached their activation code to the user account, and you're done.
Steps:
Customer buys
If they have an account: send them the link, and they're done.
If they don't:
a. Send them an email with a link with the encrypted activation code.
b. They will have to register (through SSO or through WordPress directly).
c. Once registered, you attach their product to their user account, and redirect them to the page they care about.
Hey for the question "how I can add my custom email-message with the credentials and a custom login link",
In your code, there is this line
$template = 'emails/my-custom-email-i-want-to-send.php';
you could add the credentials there, you may pass other arguments as the second parameter of this functionwc_get_template_html
second, the code order will not work for what you are trying to achieve
in this line, you are sending the email
$mailer->send( $recipient, $subject, $content, $headers );
And after that, there is a foreach loop for all the items in the order and creates a function looking if the user exists.
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
function email_exists( $order_email ) {
This function is not been called.
I will suggest to take out that function from the foreach loop and call it inside if your goal is to check only if the product XYZ exists
and all of it before the email
function check_order_product_id( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
$order_email = $order->billing_email;
//create custom mail
function get_custom_email_html( $order, $heading = false, $mailer ) {
$template = 'emails/my-custom-email-i-want-to-send.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => false,
'plain_text' => false,
'email' => $mailer
) );
}
function send_custom_email($order_email, $order){
// load the mailer class
$mailer = WC()->mailer();
//format the email
$recipient = $order_email;
$subject = __("Deine Login-Daten für Geomap", 'theme_name');
$content = get_custom_email_html( $order, $subject, $mailer );
$headers = "Content-Type: text/html\r\n";
//send the email through wordpress
$mailer->send( $recipient, $subject, $content, $headers );
}
function email_exists( $order_email ) {
$user = get_user_by( 'email', $order_email );
if ( $user ) {
send_custom_email($order_email, $order);
//not sure where this variable was comming from
return $wp_new_user_notification_email;
}
else {
// random password with 12 chars
$random_password = wp_generate_password();
// create new user with email as username & newly created pw
$user_id = wp_create_user( $order_email, $random_password, $order_email );
//not sure where this variable was comming from
return $wp_new_user_notification_email;
}
}
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
email_exists( $order_email );
}
}
}
Now as a conclusion, WP_user class doesn't give access to the password for security reasons, and they don't send it by email, you should not either is a very bad practice.
I will suggest you create the account and let WP send the default email and then you send another email with the link to your custom page, but not with the credentials.
That way they will receive two emails one secure and one with the special conditions.

Get customer data just before order-received in WooCommerce

In WooCommerce, I have a script that I am running when my webshop get a new order. This script sends an SMS to me but I would like to send it to the customer as well.
The script is running using a custom function script, just before the Order-received page with information about the order.
How do I get automatic information from the order about the name and phone number the user used?
Reading this: How to get WooCommerce order details post, does not help me, I can get the information I need and the order page fails when I try...
my code today is like this:
add_action( 'template_redirect', 'wc_custom_redirect_after_purchase' );
function wc_custom_redirect_after_purchase() {
global $wp;
if ( is_checkout() && ! empty( $wp->query_vars['order-received'] ) ) {
// Query args
$query21 = http_build_query(array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => 'NEW ORDER',
'recipients.0.msisdn' => 4511111111,
));
// Send it
$result21 = file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query21);
// exit;
}
}
What do I need is to get the firstname included in the message.
I would like something like:
$firstname = $order_billing_first_name = $order_data['billing']['first_name'];
$phone = $order_billing_phone = $order_data['billing']['phone'];
But nothing seems to works for me.
Instead you could try to use a custom function hooked in woocommerce_thankyou action hook:
add_action( 'woocommerce_thankyou', 'wc_custom_sending_sms_after_purchase', 20, 1 );
function wc_custom_sending_sms_after_purchase( $order_id ) {
if ( ! $order_id ) return;
// Avoid SMS to be sent twice
$sms_new_order_sent = get_post_meta( $order_id, '_sms_new_order_sent', true );
if( 'yes' == $sms_new_order_sent ) return;
// Get the user complete name and billing phone
$user_complete_name = get_post_meta( $order_id, '_billing_first_name', true ) . ' ';
$user_complete_name .= get_post_meta( $order_id, '_billing_last_name', true );
$user_phone = get_post_meta( $order_id, '_billing_phone', true );
// 1st Query args (to the admin)
$query1 = http_build_query( array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => 'NEW ORDER',
'recipients.0.msisdn' => 4511111111
) );
// 2nd Query args (to the customer)
$query2 = http_build_query( array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => "Hello $user_complete_name. This is your new order confirmation",
'recipients.0.msisdn' => intval($user_phone)
) );
// Send both SMS
file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query1);
file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query2);
// Update (avoiding SMS to be sent twice)
update_post_meta( $order_id, '_sms_new_order_sent', 'yes' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested on WooCommerce 3+…
Related SMS answer:
Sending an SMS for specific email notifications and order statuses

Woocommerce email notification

When my order changed its status from pending to proccessing no emails are trigger. I checked the plugin code
public function __construct() {
$this->id = 'customer_processing_order';
$this->title = __( 'Processing order', 'woocommerce' );
$this->description = __( 'This is an order notification sent to the customer after payment containing order details.', 'woocommerce' );
$this->heading = __( 'Thank you for your order', 'woocommerce' );
$this->subject = __( 'Your {blogname} order receipt from {order_date}', 'woocommerce' );
$this->template_html = 'emails/customer-processing-order.php';
$this->template_plain = 'emails/plain/customer-processing-order.php';
// Triggers for this email
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
// Call parent constructor
parent::__construct();
}
public function trigger( $order_id ) {
if ( $order_id ) {
$this->object = wc_get_order( $order_id );
$this->recipient = $this->object->billing_email;
$this->find['order-date'] = '{order_date}';
$this->find['order-number'] = '{order_number}';
$this->replace['order-date'] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
$this->replace['order-number'] = $this->object->get_order_number();
}
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
wp_mail( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
I put a test mail in function to check this trigger function called or not . but in either it doesn't work. but other emails like forgot password, no stock email notifications are working fine only order status change mails are not working Sorry for my bad english.
Thanks in advance for your help.
If you change the status manually, I'm not sure an email should be sent. But you can rather use the "Order Actions" on the right side to choose to send that email.
That will be a good test as well, choose the "New Order" to send the correct email. and wait for it.
If this doesn't help, recheck you email settings under WooCommerce and make sure the correct email is set under "New Order".

add email notification to the admin of new user (WP Approve User Plugin)

I'm using the Wordpress plugin 'WP Approve User' (https://wordpress.org/plugins/wp-approve-user/). The plugins allows a dashboard toggle to 'approve or deny' new users that sign-up for the blog; it also allows a custom email notification to be sent per 'Approval or Denial' or users..
The problem is.. and seems like a core feature for such a plugin; I would like the site admin to get a simple email notification 'New User' has signed-up and is awaiting approval.
The plugins PHP file is too large to paste here. But below is a snippet and the github link, any help would be appreciated! I simply would like to just write an an additional email notification of new-user inquiry to go to site admins email address (email address as originally intended by Wordpress > settings > general > email address..)
https://github.com/wp-plugins/wp-approve-user/blob/master/wp-approve-user.php
The plugin already sends emails to users that are approved or denied. I simply would like a notification to admin so they know to login and check there is a new user inquiry.
public function wp_authenticate_user( $userdata ) {
if ( ! is_wp_error( $userdata ) AND ! get_user_meta( $userdata->ID, 'wp-approve-user', true ) AND $userdata->user_email != get_bloginfo( 'admin_email' ) ) {
$userdata = new WP_Error(
'wpau_confirmation_error',
__( '<strong>ERROR:</strong> Your account has to be confirmed by an administrator before you can login.', 'wp-approve-user' )
);
}
return $userdata;
}
If (for some strange reason) the default new user notification does not execute, you can hook into user_register, which fires immediately after a new user is registered.
add_action( 'user_register', 'so27450945_user_register', 10, 1 );
function so27450945_user_register( $user_id )
{
$user = get_user_by( 'id', $user_id );
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
$message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
$message .= sprintf( __( 'Username: %s'), $user->user_login ) . "\r\n\r\n";
$message .= sprintf( __( 'E-mail: %s'), $user->user_email ) . "\r\n";
#wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] New User Registration' ), $blogname ), $message);
}

Categories