After having issues with Google reCAPTCHA v2 and a custom WordPress implementation, I started coding an optimized version using the invisible version of Google reCAPTCHA v3.
Based on the post ID variable, I have added several extra fields to the form (not shown here).
Optionally, there’s a handy [cf8]
shortcode.
I have named this form feature CF8.
Prerequisites
The prerequisites for this contact form are, obviously, a Google reCAPTCHA v3 (the invisible one). Create one here.
The WordPress Function:
/**
* CF8: Quick contact form with Google reCAPTCHA v3
*
* @return HTML string
*/
function wppd_cf8() {
global $post;
$postId = $post->ID;
$emailTo = 'email@example.com';
$out = '';
$out = '<form id="cf8-form" method="post">
<p>
<input type="hidden" name="contact_to" id="contact-to" value="' . $emailTo . '" readonly>
<input type="hidden" name="contact_id" id="contact-id" value="' . $postId . '">
<input type="text" name="contact_name" id="contact-name" placeholder="Full Name *">
<input type="email" name="contact_email" id="contact-email" placeholder="Email *">
<input type="text" name="contact_phone" id="contact-phone" placeholder="Phone">
<textarea name="contact_notes" id="contact-notes" rows="3" placeholder="Your Enquiry *"></textarea>
</p>
<p>
<input type="submit" name="cf8_send" id="cf8-send" value="Send" data-ip="1.2.3.4">
</p>
<div id="cf8-response"></div>
</form>';
return $out;
}
add_shortcode('cf8', 'wppd_cf8');
The WordPress Action
function wppd_action_cf8() {
$to = filter_input(INPUT_POST, 'to', FILTER_VALIDATE_EMAIL);
$pid = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$phone = filter_input(INPUT_POST, 'phone', FILTER_SANITIZE_STRING);
$notes = filter_input(INPUT_POST, 'notes', FILTER_SANITIZE_STRING);
$captcha = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);
if (!$captcha) {
echo '<h2>Please check the the captcha form.</h2>';
exit;
}
$secretKey = "BAXtnHN2u5rGtplZ4n5gBAXtnHN2u5rGtplZ4n5g";
$ip = $_SERVER['REMOTE_ADDR'];
$url = 'https://www.google.com/recaptcha/api/siteverify';
$data = [
'secret' => $secretKey,
'response' => $captcha
];
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseKeys = json_decode($response,true);
header('Content-type: application/json');
if ($responseKeys["success"] && $responseKeys["score"] >= 0.5) {
$body = '<h3>A new quick contact has been sent from <a href="' . get_permalink($pid) . '">' . get_the_title($pid) . '</a>!</h3>
<p>Contact details:</p>
<p>
<b>Name:</b> ' . $name . '<br>
<b>Email:</b> ' . $email . '<br>
<b>Telephone:</b> ' . $phone . '<br><br>
<b>Sent From:</b> <a href="' . get_permalink($pid) . '">' . get_the_title($pid) . '</a><br>
<b>Post ID:</b> ' . $pid . '<br><br>
<b>Notes:</b> ' . $notes . '
</p>
<p>
<small>Email sent to ' . $to . ' on ' . date('Y-m-d, H:i') . '</small><br>
<small>Google reCAPTCHA score: ' . $responseKeys['score'] . '</small>
</p>';
$headers[] = "Content-Type: text/html;";
$subjectLine = 'CF8 Contact Request - ' . get_the_title($pid);
wp_mail($to, 'CF8 Contact Request', $body, $headers);
// Return response
echo json_encode([
'success' => 'true',
'score' => $responseKeys["score"]
]);
} else {
echo json_encode([
'success' => 'false',
'score' => $responseKeys["score"]
]);
}
wp_die();
}
add_action('wp_ajax_wppd_action_cf8', 'wppd_action_cf8');
add_action('wp_ajax_nopriv_wppd_action_cf8', 'wppd_action_cf8');
The CSS
#cf8-response {
font-size: 14px;
}
The JavaScript
document.addEventListener('DOMContentLoaded', () => {
/**
* CF8: Quick contact form with Google reCAPTCHA v3
*/
if (document.getElementById('cf8-form')) {
document.getElementById('cf8-form').addEventListener('submit', (event) => {
event.preventDefault();
document.getElementById('cf8-response').innerHTML = 'Sending...';
let to = jQuery("#contact-to").val(),
id = jQuery("#contact-id").val(),
reference = jQuery("#contact-reference").val(),
name = jQuery("#contact-name").val(),
email = jQuery("#contact-email").val(),
phone = jQuery("#contact-phone").val(),
notes = jQuery("#contact-notes").val();
if (name !== '' && email !== '' && phone !== '' && notes !== '') {
grecaptcha.ready(() => {
grecaptcha.execute("cy08Qu0dkGIsCDBaXKf1cy08Qu0dkGIsCDBaXKf1", {
action: "create_comment"
}).then((token) => {
document.getElementById('cf8-form').insertAdjacentHTML('afterBegin', '<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
let request = new XMLHttpRequest(),
requestString = '';
requestString += '&to=' + to;
requestString += '&id=' + id;
requestString += '&reference=' + reference;
requestString += '&name=' + name;
requestString += '&email=' + email;
requestString += '&phone=' + phone;
requestString += '¬es=' + notes;
requestString += '&token=' + token;
request.open('POST', ajaxVar.ajaxUrl, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.onload = () => {
response = JSON.parse(request.response);
if (response.success) {
document.getElementById("cf8-response").innerHTML = "Email sent successfully!";
} else {
document.getElementById("cf8-response").innerHTML = "An error has occured!";
}
};
request.send('action=wppd_action_cf8' + requestString);
});;
});
} else {
document.getElementById("cf8-response").innerHTML = "An error has occured!";
}
});
}
});
And that is all!
Make sure you create a custom plugin or integrate it into your existing plugin. Dumping the code in functions.php
is always a bad idea.
Use SpeedFactor to track your website. It’s simple and reliable.
See how real people experience the speed of your website. Then find (and fix) your web performance problems.
Get Started