Documentation
Documentation, Reference Materials, and Tutorials for Leo 2FA
Send OTP via SMS and/or WhatsApp messages using Twilio
To enable Leo 2FA to send OTPs via SMS and/or WhatsApp using your Twilio account, you need to provide the recipient’s phone number in the prefix+number format.
For example, if the recipient’s phone number is 123456 and the area code is +39, you should provide Leo 2FA with the number formatted as: +39123456.
You can achieve this by adding the following PHP code to the functions.php file of your currently active WordPress theme:
function my_own_get_recipient_number($twilio_phone_number, $user_id) {
$prefix = get_phone_number_prefix_by_user_id($user_id);
$phone_number = get_phone_number_by_user_id($user_id);
$twilio_phone_number = $prefix.$phone_number;
return $twilio_phone_number;
}
// For WhatsApp
add_filter("leo_2fa_whatsapp_recipient_number","my_own_get_recipient_number", 10, 2);
// For SMS
add_filter("leo_2fa_sms_recipient_number","my_own_get_recipient_number", 10, 2);
Just replace get_phone_number_prefix_by_user_id($user_id); and get_phone_number_by_user_id($user_id); with your custom functions to retrieve the number prefix and the phone number for the user with ID $user_id.
Woocommerce example
function my_own_get_recipient_number($twilio_phone_number, $user_id) {
try {
$customer = new WC_Customer( $user_id );
}
catch (Exception $e) {
return $twilio_phone_number;
}
$prefix = "+39"; // Default prefix
$phone_number = $customer->get_billing_phone(); // Billing phone
$twilio_phone_number = $prefix.$phone_number;
return $twilio_phone_number;
}
// For WhatsApp
add_filter("leo_2fa_whatsapp_recipient_number", "my_own_get_recipient_number", 10, 2);
// For SMS
add_filter("leo_2fa_sms_recipient_number", "my_own_get_recipient_number", 10, 2);
Send the OTPs using a custom gateway
You have the flexibility to use your own custom method for delivering OTPs to your users.
For example, you can send SMS messages through your custom provider integration or use HTTP requests to connect with services like Zapier, among other options.
To do this, add the following PHP code to the functions.php file of your currently active WordPress theme:
add_filter("leo_2fa_send_otp_custom_integration", function($otp_sent, $otp, $user_id, $user_data, $user_session_token) {
if( send_otp_using_my_custom_provider_integration($otp, $user_id) === true )
$otp_send = true;
return $otp_send;
}, 10, 5);
It is essential to return true upon a successful OTP transmission and false in case of an error. By default, the variable $otp_sent is set to false.
Hooks reference
Hooks in WordPress enable you to modify or add functionality without altering core files. They are extensively used throughout WordPress and Leo 2FA, and are very useful for developers.
There are two types of hooks: actions and filters.
- Action Hooks allow you to insert custom code at specific points (wherever the hook is triggered).
- Filter Hooks allow you to manipulate and return a variable passed through the hook.
Below is a list of action and filter hooks available in Leo 2FA. Refer to the source code for detailed information on supported parameters and usage.
Common hooks
add_filter("leo_2fa_skip_2fa", function($skip_2fa, $user_id, $user_data) {
// Set $skip_2fa on true to skip the 2FA for the current user
return $skip_2fa;
}, 50, 3);
add_filter("leo_2fa_skip_send_otp_via_email", function($skip_send, $email_address) {
// Set $skip_send on true to stop sending the OTP via email to the email address $email_address
return $skip_send;
}, 10, 2);
add_filter("leo_2fa_email_subject", function($email_subject) {
// You can use tags like {{blog_name}} and {{otp_code}}
return "My custom email subject";
}, 10, 1);
add_filter("leo_2fa_email_body", function($email_body) {
// You can use tags like {{blog_name}} - {{logo_url}} - {{blog_url} - {{otp_code}}
return "My custom email body";
}, 10, 1);
add_filter("leo_2fa_email_headers", function($email_headers) {
return $email_headers;
}, 10, 1);
add_filter("leo_2fa_form_loading_icon_url", function($loading_icon_url) {
return $loading_icon_url;
}, 10, 1);
add_filter("leo_2fa_sms_content", function($sms_content) {
return "My custom SMS content (Pro function)";
}, 10, 1);
add_filter("leo_2fa_whatsapp_message_content", function($message_content) {
return "My custom WhatsApp message content (Pro function)";
}, 10, 1);
add_action("leo_2fa_before_otp_sending", function($user_id, $user_data) {
// Add here the code to execute before sending the OTP to user
}, 10, 2);
add_action("leo_2fa_after_otp_sending", function($user_id, $user_data, $otp_sent) {
// Add here the code to execute after the OTP has been sent to user. If $otp_sent is true, the OTP has been sent successfully.
}, 10, 3);
add_action("leo_2fa_email_skipped", function($otp, $email_address, $expiration_minutes) {
// Add here the code to execute if the sending of OTP is blocked by the filter leo_2fa_skip_send_otp_via_email.
// The $expiration_minutes variable contains the OTP expiration time (Pro function)
}, 10, 3);
add_action("leo_2fa_before_email_sending", function($otp, $email_address, $expiration_minutes) {
// Add here the code to execute before to send the OTP via email
}, 10, 3);
add_action("leo_2fa_email_sent", function($otp, $email_address, $expiration_minutes) {
// Add here the code to execute after the OTP has been sent via email
}, 10, 3);
add_action("leo_2fa_after_email_sending", function($otp, $email_address, $expiration_minutes, $otp_sent) {
// Add here the code to execute after the OTP has been sent via email
}, 10, 4);
add_action("leo_2fa_invalid_otp", function($user_id, $otp) {
// Add here the code to execute on invalid OTP
}, 10, 2);
add_action("leo_2fa_valid_otp", function($user_id, $otp) {
// Add here the code to execute on valid OTP
}, 10, 2);
2FA page - Visual hooks
do_action('leo_2fa_form_before_container');
do_action('leo_2fa_form_before_title');
do_action('leo_2fa_form_before_form');
do_action('leo_2fa_form_after_form');
do_action('leo_2fa_form_after_logout_link');
do_action('leo_2fa_form_after_container');
add_filters( 'leo_2fa_form_title', function($title) {
return "My custom title";
});
add_filters( 'leo_2fa_form_subtitle', function($subtitle) {
return "My custom subtitle";
});
add_filters( 'leo_2fa_form_submit', function($submit_value) {
return "My custom submit button value";
});