reCAPTCHA v3 Email Form Script

ReCAPTCHA v3 is the most effective spam filter available at Google's reCAPTCHA v3 Site. This comment form uses HTML5, PHP, Javascript and CSS programming. The form requires 3 files, comment1.php, comment2.php and comment.css. The latter must be placed in a subdirectory called css unless you change the "action" method in the "form line"

How does it work?

The PHP file comment1.php is the POST form sent to comment2.php for processing. The processing first checks the validity of the form fields through HTML5. Google then checks using reCAPTCHA v3. The filter accepts messages with a score equal to or greater than 0.5. If successful an email is sent to the recipient from the local_mail address.

How do I configure it?

Copy and paste or download the files comment1.php, comment2.php and comment.css. Place the css file in a subdirectory called "css." Open the comment1.php file and enter the four required entries for the form to work.

  • site_key: Enter the reCAPTCHA v3 site key
  • secret_key: Enter the reCAPTCHA v3 secret key
  • local_email: A local email address on the server !important
  • recipient: The email address receiving the form results
  • theme stuff: Set font-size, color, background in the other configuration parameters

tab

comment.css


<style type="text/css">

.grecaptcha-badge {
  visibility: collapse !important;
}
.wrap {
  font-size: 20px;
  margin: 0 auto;
  padding: 0;
  max-width: 800px;
  text-align: center;
  border-radius: .3em;
}

.hed,
.format {
  text-align: center;
  margin: 0 auto 0 auto;
  max-width: 800px;
}

.format {
  border: 1px solid #eee;
  border-radius: 0 0 .3em .3em;
  background-color: #f2f2f2;
  padding: 1.5em 2em;
}

.hed {
  background-color: #0069ed;
  border-radius: .3em .3em 0 0;
  padding: 1em 0;
}

.hed h1,
.hed h2,
.hed p {
  color: #f2f2f2;
  margin: 0;
  padding: .5em 0;
  font-family: arial, sans-serif;
}

.hed h2,
.hed p {
  padding: 0 0 .5em 0;
  line-height: 1.1;
}

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

input[type=text],
input[type=email],
select,
textarea {
  font-family: arial, sans-serif;
  width: 100%;
  padding: .85em;
  border: 1px solid #ccc;
  border-radius: .25em;
  resize: vertical;
  font-size: 80%;
}

input[type=text]:focus,
input[type=email]:focus,
select:focus,
textarea:focus {
  outline: none !important;
  border: 1px solid red;
  box-shadow: 1px 1px 10px inset #ccc;
}

label {
  padding: 0 0 0 .75em;
  display: inline-block;
  float: left;
  font-family: arial, sans-serif;
}

input[type=submit]:hover {
  background-color: #45a049;
}

.col-25 {
  float: left;
  width: 25%;
  margin-top: .33em;
  line-height: 2;
}

.col-75 {
  float: left;
  width: 75%;
  margin-top: .33em;
}


/* Clear floats after the columns */

.row:after {
  content: "";
  display: table;
  clear: both;
}

#myBtn {
  margin: .5em auto 0 auto;
}

button {
  border-radius: .3em;
  display: inline-block;
  border: none;
  padding: .75em 1.5em;
  margin: 0 auto;
  text-decoration: none;
  background: #0069ed;
  color: #f2f2f2;
  font-family: sans-serif;
  font-size: 1.25em;
  cursor: pointer;
  text-align: center;
  transition: background 250ms ease-in-out, transform 150ms ease;
  -webkit-appearance: none;
  -moz-appearance: none;
}

button:hover,
button:focus {
  background: #0053ba;
}

button:focus {
  outline: 1px solid #000;
  outline-offset: -4px;
}

button:active {
  transform: scale(0.99);
}

table {
  border-collapse: collapse;
  border-spacing: 0;
  width: 100%;
  background-color: #fff;
}

th,
td {
  text-align: left;
  padding: .5em;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}


/* Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */

@media screen and (max-width: 567px) {
  .col-25,
  .col-75,
  input[type=submit] {
    width: 100%;
    margin: 0;
  }
  #myBtn {
    font-size: 16px;
  }
  .format {
    margin: 0;
    padding: .25em;
  }
  .hed h1 {
    line-height: 1.25em;
  }
}

@media screen and (max-width: 240px) {
  #myBtn {
    font-size: 14px;
  }
  .format {
    margin: 0;
    padding: .25em;
    line-height: 1em;
  }
  .hed h1 {
    line-height: 1.1em;
    padding: .25em 0;
  }
}

</style>

tab

comment1.php

 
<?php
  //   #### FIRST RUN #### //
  // Configuration Area - CONSTANT arrays Work as of PHP 7
  // site_key and secret_key are for google reCAPTCHA v3.
  // Theme //
   !defined('CONFIG') && define('CONFIG', array(
      "site_key"=>"",
      "secret_key"=>"",
      "local_email"=>"local_mail@domain.tld",
      "recipient"=>"recipient@domain.tld",
      "font_size"=>"16px",
      "header_background"=>"#3B5998",
      "button_background"=>"#3B5998",
      "form_text_color"=>"#3B5998",
      "form_background_color"=>"#DFE3EE",
      "header_text_color"=>"#DFE3EE",
      "button_text_color"=>"#DFE3EE",
      "button_background_hover"=>"#2a4785"
  )); 
  ?>
<!DOCTYPE html>  
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="description" content="Form Page">
    <meta name="keywords" content="contact form, comments, message">
    <meta name="author" content="David Geier">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Title -->
    <title>Comment Form</title>
    <!-- Favicon -->
    <link rel="icon" href="img/favicon.ico">
    <link rel="stylesheet" href="css/comment.css">
    <!-- reCAPTCHA v3 initial communication with google using site key -->
    <!-- #### FIRST RUN #### -->
    <script src="https://www.google.com/recaptcha/api.js?render=<?php echo CONFIG['site_key'] ?>"></script>
    <script>
      grecaptcha.ready(function () {
          grecaptcha.execute('<?php echo CONFIG['site_key'] ?>', { action: 'homepage' }).then(function (token) {
              var recaptchaResponse = document.getElementById('recaptchaResponse');
              recaptchaResponse.value = token;
          });
      });
    </script>
    <?php
      // Create a custom configuration style script on the fly using PHP //
      // #### FIRST RUN #### //
      echo   "<style type='text/css'>\n";
      echo "  .format { \n   background-color:" . CONFIG['form_background_color'] .";\n";
      echo "    color:" . CONFIG['form_text_color'] . ";\n";
      echo "  }\n";
      echo "  .hed  { \n   background-color: " . CONFIG['header_background'] . ";\n";
      echo "  }\n";
      echo "  .hed h1, .hed h2, .hed p { \n   color: " . CONFIG['header_text_color'] . ";\n";
      echo "  }\n";
      echo "  button { \n";
      echo "    background:" . CONFIG['button_background'] . ";\n";
      echo "    color:" . CONFIG['button_text_color'] . ";\n";
      echo "  }\n";
      echo "  .wrap { \n";
      echo "    font-size:" . CONFIG['font_size'] . ";\n";
      echo "  }\n";
      echo "  tr:nth-child(even) { \n";
      echo "    background-color:" . CONFIG['form_background_color'] . ";\n";
      echo "  }\n";
      echo "  button:hover, button:focus {\n";
      echo "    background:" . CONFIG['button_background_hover'] . ";\n";
      echo "  }\n";
      echo "  input[type=text]:focus, input[type=email]:focus, select:focus, textarea:focus {\n";
      echo "    border: 1px solid " . CONFIG['header_background'] . ";\n";
      echo "</style>\n";
      ?>
  </head>
  <body>
    <!-- #### FIRST RUN #### -->
    <!-- Only create the DIVs if form has not POSTed -->
    <?php if ($_SERVER['REQUEST_METHOD'] != 'POST') { ?>
    <div class="wrap">
      <div class="hed">
        <h1>Comment Form</h1>
      </div>
      <?php } ?>
      <div class="format">
        <!-- ##### Contact Area Start ##### -->
        <form action="https://thehelppage.com/comment2.php" title="emailForm" id="emailForm" method="post" name="emailForm">
          <div class="row">
            <div class="col-25"><label for="fname">First Name</label></div>
            <div class="col-75">
              <input class="form-control error" label="FirstName" type="text" id="fname" name="fname" placeholder="Your first name" required value="<?php echo $fname; ?>" <?php if (isset($fname))  echo " readonly";?> >
            </div>
          </div>
          <div class="row">
            <div class="col-25"><label for="lname">Last Name</label></div>
            <div class="col-75">
              <input class="form-control error" label="LastName" type="text" id="lname" name="lname" placeholder="Your last name.." required value=<?php echo $lname; ?> <?php if (isset($fname))  echo " readonly";?>>
            </div>
          </div>
          <div class="row">
            <div class="col-25"><label for="email">Email</label></div>
            <div class="col-75">
              <input class="form-control error" id="email" label="Email" name="email" placeholder="Your email address" required type="email" value=<?php echo $email; ?> <?php if (isset($fname))  echo " readonly";?>>
            </div>
          </div>
          <div class="row">
            <div class="col-25"><label for="subject">Subject</label></div>
            <div class="col-75">
              <input class="form-control error" label="Subject" type="text"  id="subject" name="subject" placeholder=" - Optional - " value = <?php echo $subject; ?> <?php if (isset($fname))  echo " readonly";?>>
            </div>
          </div>
          <div>
            <div class="row">
              <div class="col-25"><label for="comment">Comments</label></div>
              <textarea class="form control error" style="height:180px" id="comment" label="Comment" name="message" placeholder="Write something..." type="text" required  <?php if (isset($fname))  echo " readonly";?>><?php echo $message; ?></textarea>
            </div>
          </div>
          <?php    if ($_SERVER['REQUEST_METHOD'] == 'POST') { ?>
          <!-- <button class="btn" id="myBtn" href="#" onclick="location.href = document.referrer; return false;">Back</button> -->
          <?php } ?>
          <?php if ($_SERVER['REQUEST_METHOD'] != 'POST') { ?>
          <div class="row" style="text-align: center">
            <button class="btn" id="myBtn" name="submit" type="submit" value="Submit">Send Message</button>
          </div>
          <input id="recaptchaResponse" name="recaptcha_response" type="hidden">
          <?php 
            foreach(CONFIG as $key => $value)
            {
            echo '<input type="hidden" name="' . $key . '" value="'. $value . '">';
            }
            }
            ?> 
        </form>
        <!-- ##### Contact Area End ##### -->
      </div>
    </div>
  </body>
</html>
tab

comment2.php

 
<?php
  // #### SECOND RUN #### //
  
  // Clean the POST input data //
  function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
  } 
  ?>
<!DOCTYPE HTML>  
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="description" content="Form Page">
    <meta name="keywords" content="contact form, comments, message">
    <meta name="author" content="David Geier">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Title -->
    <title>Comment Form</title>
    <!-- Favicon -->
    <link rel="icon" href="./img/favicon.ico">
    <?php 
      include('css/comment.css'); 
      ?>
    <?php
      // Create a custom configuration style script on the fly using PHP //
      // #### SECOND RUN #### //
      echo   "<style type='text/css'>\n";
      echo "  .format { \n   background-color:" . $_POST['form_background_color'] .";\n";
      echo "    color:" . $_POST['form_text_color'] . ";\n";
      echo "  }\n";
      echo "  .hed  { \n   background-color: " . $_POST['header_background'] . ";\n";
      echo "  }\n";
      echo "  .hed h1, .hed h2, .hed p { \n   color: " . $_POST['header_text_color'] . ";\n";
      echo "  }\n";
      echo "  button { \n";
      echo "    background:" . $_POST['button_background'] . ";\n";
      echo "    color:" . $_POST['button_text_color'] . ";\n";
      echo "  }\n";
      echo "  tr:nth-child(even) { \n";
      echo "    background-color:" . $_POST['form_background_color'] . ";\n";
      echo "  }\n";
      echo "  .wrap { \n";
      echo "    font-size:" . $_POST['font_size'] . ";\n";
      echo "  }\n";
      echo "  button:hover, button:focus {\n";
      echo "    background:" . $_POST['button_background_hover'] . ";\n";
      echo "  }\n";
      echo "  input[type=text]:focus, input[type=email]:focus, select:focus, textarea:focus {\n";
      echo "    border: 1px solid " . $_POST['header_background'] . ";\n";
      echo "</style>\n";
      ?>
  </head>
  <body>
    <?php
      // #### SECOND RUN #### //
      
      // Get the ip address  //
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
      
          // Get IP address // 
          if(!empty($_SERVER['HTTP_CLIENT_IP'])){
              //ip from share internet
              $ip = $_SERVER['HTTP_CLIENT_IP'];
          }elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
              //ip pass from proxy
              $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
          }else{
              $ip = $_SERVER['REMOTE_ADDR'];
          }
      
      // Use ip to discover IP info at ipinfo.io via json // 
      $details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
      $city = $details->city;
      $region = $details->region;
      $country = $details->country;
      $postal = $details->postal;
      $phone = $details->phone;
      $org = $details->org;
      $hostname = $details->hostname;
      }
      
      // SECOND RUN  SUCCESS! //
      
      // Return result info and email if form was successful //  
      if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['recaptcha_response'])) {
      
          // Build POST request: //
          $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
          $recaptcha_response = $_POST['recaptcha_response'];
      
          // Make and decode POST request for Google reCAPTCHA v3: //
          $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $_POST['secret_key'] . '&response=' . $recaptcha_response);
          $recaptcha = json_decode($recaptcha);
      
          // Check for validity and send email //
          $rca = $recaptcha->score;
          if ($rca >= 0.5) {
              $local_email=$_POST['local_email'];
              $recipient=$_POST['recipient'];
              $cur_date = date("F j, Y, g:i a");
      
              // Verified - send email
              $to      = $recipient;
              // define variables and set to empty values
              $lname = $fname = $email = $subject = $message = "";
              if (!empty($_POST["fname"])) {
                  $fname = test_input($_POST["fname"]);
                }
              if (!empty($_POST["lname"])) {
                  $lname = test_input($_POST["lname"]);
                }
              if (!empty($_POST["email"])) {
                  $email = test_input($_POST["email"]);
                }
              if (!empty($_POST["subject"])) { 
                  $subject = test_input($_POST["subject"]);
                } else {
                  $subject = "Mail from: " . $email; 
                }
              if (!empty($_POST['message'])) {
                $message .= "From:                " . $fname . " " . $lname . " <" . $email . ">\r\n";
                $message .= "Subject:           " . $subject . "\r\n";
                $message .= "Date:                " .  date("F j, Y, g:i a") . "\r\n";
                $message .= "Location:         " . $city . ", " . $region . " " . $country . " " . $postal . "\r\n";
                $message .= "IP address:      " . $ip . "\r\n";
                $message .= "Host name:      " .  $hostname . "\r\n";
                $message .= "Area code:     " . $phone . "\r\n";
                $message .= "Organization:  " . $org . "\r\n";
                $message .= "reCAPTCHA:     " . $rca . "\r\n";
                $message .= "Message: \r\n";
                $message .= test_input($_POST['message']) . "\r\n";
                } 
                $headers = 'From: ' . $local_email . "\r\n" .
                'Reply-To: ' . $email . "\r\n" .
                'X-Mailer: PHP/' . phpversion();
      
                mail($to, $subject, $message, $headers);
          }
      }
      
      // #### SECOND RUN #### //
      
      // Display results to screen //
      if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
      ?>
    <div class="wrap">
    <div class="hed ">
      <?php
        if ($rca >= 0.5) {
          echo '<h1>Thank You ' . $fname . ' ' . $lname . '</h1>';
          echo '<p> We will get back to you as soon as possible</p>';
        }  else {
          echo '<h1>Sorry, something went wrong.</h1>';
          exit("<h2>Check configuration</h2>");
        }
          echo '</div>';
        ?>
      <div class="format" style="overflow-x:auto">
        <table>
          <tr>
            <td>Date:</td>
            <td><?php echo date(DATE_RFC822) ?></td>
          </tr>
          <tr>
            <td>From:</td>
            <td><?php echo $fname . " " . $lname ?></td>
          </tr>
          <tr>
            <td>Email:</td>
            <td><?php echo $email ?></td>
          </tr>
        </table>
      </div>
    </div>
    </section>
    <?php } ?>
  </body>
</html>
?>