Bootstrap contact form with ReCaptcha

The second thing is, I’m attempting to set up and get working a Bootstrap contact form with ReCaptcha

https://jonbake.com/blog/2015/03/22/a-better-contact-form.html

I’ve unzipped and uploaded here

https://cleardirectionhypnotherapy.co.uk/bootstrap3-contact-form-master/index.html

There is a help guide included in the zip file that explains how to get the form working, but I’m struggling with it.

I have visited Google and generated a pair of keys - site key and secret key.

According to the help guide:

"The Site Key must be entered into the [Contact Form HTML] in the place of the text your_site_key.

<div class="form-group">
              <div class="g-recaptcha" data-sitekey="your_site_key"></div>
              <span class="help-block" style="display: none;">Please check that you are not a robot.</span>
            </div>

This seems simple enough, and I would enter my site key as in the example below

<div class="form-group">
              <div class="g-recaptcha" data-sitekey="HERE"></div>
              <span class="help-block" style="display: none;">Please check that you are not a robot.</span>
            </div>

To be continued . . .

It then goes on to say how (and this is the part I’m not sure about):

Configuration values to the contact form are passed in via Environment Variables.

The following variables need to be defined:

| Name
| Description
| FEEDBACK_HOSTNAME | Host name for SMTP server

| FEEDBACK_EMAIL | Email address to authenticate to SMTP server with
| FEEDBACK_PASSWORD | Password to authenticate to SMTP server with
| FEEDBACK_ENCRYPTION | If specified will use encryption. Valid values: TLS or SSL
| RECAPTCHA_SECRET_KEY | reCAPTCHA secret key.

| FEEDBACK_SKIP_AUTH | Optional If specified, will not authenticate with email/password |

Environment variables can be specified in a variety of ways.
For example, if using Apache (and mod_env is enabled), they can be specified in
.htaccess:

SetEnv FEEDBACK_HOSTNAME smtp.gmail.com
SetEnv FEEDBACK_EMAIL me@gmail.com
SetEnv FEEDBACK_PASSWORD my!password!
SetEnv 
FEEDBACK_ENCRYPTION TLS
SetEnv RECAPTCHA_SECRET_KEY 7823skdgjksd828sjdgkn

Tip: Environment Variables are used in [Sendmail.php]
(https://github.com/jonmbake/bootstrap3-contact-form/blob/master/library/sendmail.php). If you don’t want to use Environment Variables,
you can edit sendmail.php, replacing calls to #getenv with the corresponding configuration value like in this [Example Gist]
(https://gist.github.com/jonmbake/0e5b175a72ad9ba64167).

Variables can be defined in .htaccess or directly in the sendmail.php

I have very limited knowledge of .htaccess and wouldn’t know what to write to make this work, so I’m falling back to the sendmail.php

I’ve got my server hostname (is this what’s meant by Host name for SMTP server?)

I’ve got the email address I’d like mail sent to from the form, and the password I set for this email address when I created it.

I’ve also got details from my webhost about TLS SSL and post numbers.

So, when I look at the code for the sendmail.php posted below, is it correct to add my secret key here: => getenv(‘RECAPTCHA_SECRET_KEY’),

$captcha_post_data = http_build_query(array(‘secret’ => getenv(‘RECAPTCHA_SECRET_KEY’), ‘response’ => $_POST[“g-recaptcha-response”]));

and should it be entered exactly where it says RECAPTCHA_SECRET_KEY and while preserving the brackets and apostropies, or losing the brackets and apostropies?

As for host name for SMTP server, email address to send the mail, email password, I would enter these in the following block here, again with or without the brackets and colons?:

$mail->Host = getEnv(‘FEEDBACK_HOSTNAME’);

$mail->Username = getenv(‘FEEDBACK_EMAIL’);

$mail->Password = getenv(‘FEEDBACK_PASSWORD’);

and further down

$mail->Sender = getenv(‘FEEDBACK_EMAIL’);

$mail->setFrom($_POST[‘email’], $_POST[‘name’]);

$mail->addAddress(getenv(‘FEEDBACK_EMAIL’));

here is the complete sendmail.php

<?php
  /**
   * Sets error header and json error message response.
   *
   * @param  String $messsage error message of response
   * @return void
   */
  function errorResponse ($messsage) {
    header('HTTP/1.1 500 Internal Server Error');
    die(json_encode(array('message' => $messsage)));
  }

  /**
   * Pulls posted values for all fields in $fields_req array.
   * If a required field does not have a value, an error response is given.
   */
  function constructMessageBody () {
    $fields_req =  array("name" => true, "email" => true, "message" => true);
    $message_body = "";
    foreach ($fields_req as $name => $required) {
      $postedValue = $_POST[$name];
      if ($required && empty($postedValue)) {
        errorResponse("$name is empty.");
      } else {
        $message_body .= ucfirst($name) . ":  " . $postedValue . "\n";
      }
    }
    return $message_body;
  }

  header('Content-type: application/json');

  //do Captcha check, make sure the submitter is not a robot:)...
  $captcha_url = 'https://www.google.com/recaptcha/api/siteverify';
  $captcha_header = 'Content-type: application/x-www-form-urlencoded';
  $captcha_post_data = http_build_query(array('secret' => getenv('RECAPTCHA_SECRET_KEY'), 'response' => $_POST["g-recaptcha-response"]));
  // prefer cURL over #file_get_contents...
  if (function_exists('curl_init')) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $captcha_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array($captcha_header));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $captcha_post_data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = json_decode(curl_exec($ch));
    curl_close($ch);
  } else {
    $opts = array('http' =>
      array(
        'method'  => 'POST',
        'header'  => $captcha_header,
        'content' => $captcha_post_data
      )
    );
    $context  = stream_context_create($opts);
    $result = json_decode(file_get_contents($captcha_url, false, $context, -1, 40000));
  }


  if (!$result->success) {
    errorResponse('reCAPTCHA checked failed! Error codes: ' . join(', ', $result->{"error-codes"}));
  }
  //attempt to send email
  $messageBody = constructMessageBody();
  require './vender/php_mailer/PHPMailerAutoload.php';
  $mail = new PHPMailer;
  $mail->CharSet = 'UTF-8';
  $mail->isSMTP();
  $mail->Host = getEnv('FEEDBACK_HOSTNAME');
  if (!getenv('FEEDBACK_SKIP_AUTH')) {
    $mail->SMTPAuth = true;
    $mail->Username = getenv('FEEDBACK_EMAIL');
    $mail->Password = getenv('FEEDBACK_PASSWORD');
  }
  if (getenv('FEEDBACK_ENCRYPTION') == 'TLS') {
    $mail->SMTPSecure = 'tls';
    $mail->Port = 587;
  } elseif (getenv('FEEDBACK_ENCRYPTION') == 'SSL') {
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
  }

  $mail->Sender = getenv('FEEDBACK_EMAIL');
  $mail->setFrom($_POST['email'], $_POST['name']);
  $mail->addAddress(getenv('FEEDBACK_EMAIL'));

  $mail->Subject = $_POST['reason'];
  $mail->Body  = $messageBody;


  //try to send the message
  if($mail->send()) {
    echo json_encode(array('message' => 'Your message was successfully submitted.'));
  } else {
    errorResponse('An unexpected error occured while attempting to send the email: ' . $mail->ErrorInfo);
  }
?>

If you can offer any advice I’d be very grateful.

Replying to my own post. After a lot of experimentation, I failed to get the Jon Bake contact form working and sought out other options instead. I’m sure that the Jon Bake contact form works just fine for those with more knowledge of coding than me, but setting it up correctly was beyond my level of understanding.

After some Googling, I came upon this:

https://bootstrapious.com/p/how-to-build-a-working-bootstrap-contact-form

Getting this form set up and working with a site key and secret key is a very simple and straightforward matter indeed and I’d recommend it to anyone who is struggling to get their contact form with recaptcha working successfully.

After downloading and unpacking the zip file there are 2 versions of the form included, index.html and index-bootstrap3.html

Here is the HTML for the first form (the second form is similar) and you will need to enter your site key between the " " here: <div class="g-recaptcha" data-sitekey="enter_your_site_key_here"

<html>

<head>
    <title>Contact Form Tutorial by Bootstrapious.com</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    <link href='https://fonts.googleapis.com/css?family=Lato:300,400,500' rel='stylesheet' type='text/css'>
    <link href='custom.css' rel='stylesheet' type='text/css'>
</head>

<body>

    <div class="container">

        <div class="row">

            <div class="col-xl-8 offset-xl-2">

                <h1>Contact form Tutorial from
                    <a href="http://bootstrapious.com">Bootstrapious.com</a>
                </h1>

                <p class="lead">This is a demo for our tutorial dedicated to crafting working Bootstrap contact form with PHP and AJAX background.
                    At this part, we will add Google's ReCaptcha too.</p>


                <form id="contact-form" method="post" action="contact.php" role="form">

                    <div class="messages"></div>

                    <div class="controls">
                        <div class="row">
                            <div class="col-lg-6">
                                <div class="form-group">
                                    <label for="form_name">Firstname *</label>
                                    <input id="form_name" type="text" name="name" class="form-control" placeholder="Please enter your firstname *" required="required"
                                        data-error="Firstname is required.">
                                    <div class="help-block with-errors"></div>
                                </div>
                            </div>
                            <div class="col-lg-6">
                                <div class="form-group">
                                    <label for="form_lastname">Lastname *</label>
                                    <input id="form_lastname" type="text" name="surname" class="form-control" placeholder="Please enter your lastname *" required="required"
                                        data-error="Lastname is required.">
                                    <div class="help-block with-errors"></div>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-lg-6">
                                <div class="form-group">
                                    <label for="form_email">Email *</label>
                                    <input id="form_email" type="email" name="email" class="form-control" placeholder="Please enter your email *" required="required"
                                        data-error="Valid email is required.">
                                    <div class="help-block with-errors"></div>
                                </div>
                            </div>
                            <div class="col-lg-6">
                                <div class="form-group">
                                    <label for="form_phone">Phone</label>
                                    <input id="form_phone" type="tel" name="phone" class="form-control" placeholder="Please enter your phone">
                                    <div class="help-block with-errors"></div>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="form_message">Message *</label>
                            <textarea id="form_message" name="message" class="form-control" placeholder="Message for me *" rows="4" required="required"
                                data-error="Please, leave us a message."></textarea>
                            <div class="help-block with-errors"></div>
                        </div>


                        <div class="form-group">
                            <div class="g-recaptcha" data-sitekey="enter_your_site_key_here" data-callback="verifyRecaptchaCallback" data-expired-callback="expiredRecaptchaCallback"></div>
                            <input class="form-control d-none" data-recaptcha="true" required data-error="Please complete the Captcha">
                            <div class="help-block with-errors"></div>
                        </div>


                        <input type="submit" class="btn btn-success btn-send" value="Send message">

                        <p class="text-muted">
                            <strong>*</strong> These fields are required. Contact form template by
                            <a href="https://bootstrapious.com/p/bootstrap-recaptcha" target="_blank">Bootstrapious</a>.
                        </p>

                    </div>

                </form>

            </div>
            <!-- /.8 -->

        </div>
        <!-- /.row-->

    </div>
    <!-- /.container-->

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    <script src='https://www.google.com/recaptcha/api.js'></script>
    <script src="validator.js"></script>
    <script src="contact.js"></script>
</body>

</html>

Next, you’ll need to open contact.php and add your secret key between the ’ ’ here:

// ReCaptch Secret
$recaptchaSecret = 'enter_your_secret_key_here';

Here is the full contact.php script:

<?php
// require ReCaptcha class
require('recaptcha-master/src/autoload.php');

// configure
// an email address that will be in the From field of the email.
$from = 'Demo contact form <admin@myemailaddress.com>';

// an email address that will receive the email with the output of the form
$sendTo = 'Demo contact form <admin@myemailaddress.com>';

// subject of the email
$subject = 'New message from contact form';

// form field names and their translations.
// array variable name => Text to appear in the email
$fields = array('name' => 'Name', 'surname' => 'Surname', 'phone' => 'Phone', 'email' => 'Email', 'message' => 'Message');

// message that will be displayed when everything is OK :)
$okMessage = 'Contact form successfully submitted. Thank you, I will get back to you soon!';

// If something goes wrong, we will display this message.
$errorMessage = 'There was an error while submitting the form. Please try again later';

// ReCaptch Secret
$recaptchaSecret = 'enter_your_secret_key_here';

// let's do the sending

// if you are not debugging and don't need error reporting, turn this off by error_reporting(0);
error_reporting(E_ALL & ~E_NOTICE);

try {
    if (!empty($_POST)) {

        // validate the ReCaptcha, if something is wrong, we throw an Exception,
        // i.e. code stops executing and goes to catch() block
        
        if (!isset($_POST['g-recaptcha-response'])) {
            throw new \Exception('ReCaptcha is not set.');
        }

        // do not forget to enter your secret key from https://www.google.com/recaptcha/admin
        
        $recaptcha = new \ReCaptcha\ReCaptcha($recaptchaSecret, new \ReCaptcha\RequestMethod\CurlPost());
        
        // we validate the ReCaptcha field together with the user's IP address
        
        $response = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

        if (!$response->isSuccess()) {
            throw new \Exception('ReCaptcha was not validated.');
        }
        
        // everything went well, we can compose the message, as usually
        
        $emailText = "You have a new message from your contact form\n=============================\n";

        foreach ($_POST as $key => $value) {
            // If the field exists in the $fields array, include it in the email
            if (isset($fields[$key])) {
                $emailText .= "$fields[$key]: $value\n";
            }
        }
    
        // All the neccessary headers for the email.
        $headers = array('Content-Type: text/plain; charset="UTF-8";',
            'From: ' . $from,
            'Reply-To: ' . $from,
            'Return-Path: ' . $from,
        );
        
        // Send email
        mail($sendTo, $subject, $emailText, implode("\n", $headers));

        $responseArray = array('type' => 'success', 'message' => $okMessage);
    }
} catch (\Exception $e) {
    $responseArray = array('type' => 'danger', 'message' => $e->getMessage());
}

if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    $encoded = json_encode($responseArray);

    header('Content-Type: application/json');

    echo $encoded;
} else {
    echo $responseArray['message'];
}

All that’s now left to do is add the email address you’d like mail from the form to be sent.

I added my email address at the top of contact.php in 2 places here:

// configure
// an email address that will be in the From field of the email.
$from = 'Demo contact form <admin@myemailaddress.com>';

// an email address that will receive the email with the output of the form
$sendTo = 'Demo contact form <admin@myemailaddress.com>';

After doing all of this I uploaded the entire ‘recatcha’ folder I’d unpacked earlier including both of the forms, the contact.php, and several other files.

I filled out each of the forms and was delighted to discover that they send messages to my designated email address without any problems at all.

I hope this works for you too. :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.