Streaming live at 10am (PST)

Confirmation email to client via Webflow form and custom PHP

Hello,

The request is not new… :slight_smile:

how to send confirmation email to user after submiting a Webflow form.

I do have a Zapier setup that does exactly that, but it is really expensive (50$ a month) and quite complex… had to setup a mailbox parser (which is an overkill already) to extract webflow fields etc…

Despite extensive research on the forum, I haven’t found a complete solution in regards to the implementation of a basic PHP script inspired by a promising post by @cyberdave

<?php

$name = $_POST['name'];
$email = $_POST['email'];  
$subject = $_POST['subject'];
$message = $_POST['message'];
$to = "recipient@your-server.com";
$headers = 'From: '.$email."\r\n" .
        'Reply-To: '.$email."\r\n"
        'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers, "From: " . $name);

header('Location: contact_thankyou.html');

?>

I did search on the internet how to setup a webserver but coulnd not really find a A to Z step by step process… Has anyone had experience with it, a suggestions in regards to where to rent a webserver in order to host and run a simple PHP mailing script back to the Webflow user ?

Thank you :wink:

PS
I also found that link but it doesn’t really explain how to implement the PHP script with the external webserver.

Well, it seems I have answered my question myslef. Namecheap offers PHP server too. I will experiment and share my result if I’m successfull :slight_smile:

1 Like

Hello :slightly_smiling_face:

So I successfully registered a domain name with Namecheap.
Unfortunatelly, it is not yet working.

I successfully linked the domain name to my webflow project:
https://www.further.design/

I create a subdomain name and hosted my PHP script here:
http://mail.further.design/mailscript.php

The script is really basic and inspired from w3schools :

<?php
$to = "anthony.salamin@gmail.com";
$subject = "confirmation";
$message = $_POST["message"];
$email = $_POST["email"];
$headers = "From: " . $email;

mail($to,$subject,$message,$headers);
header("Location: https://www.further.design/thanks");
?>

I set the action of my webflow’s form to the url mentioned above (http://mail.further.design/mailscript.php) and the method to POST but when hi hit submit on the published website, the only thing happening is a redirect to my “thank you” page as declared in the header of my php file.

My question is:
Does someone knows, what am I doing wrong ?

Here is my Read-only link

I think you might want to consider usebasin.com. One account and you can manage form to mail services for oodles of webflow sites. Each form has its own logic allowing in spam filtering, honeypot, and ReCaptcha per form.

If you want a script that covers all the bases look at PHPMailer.

1 Like

@webdev you were right !
PHPmailer seems to offer all the flexibility I need !

It took me a while and a lot of trial and error but I got my first auto-confirmation email from a Webflow form via a custom action PHP script hosted on namecheap Stellar hosting server ! :smiling_face_with_three_hearts:

One “last” question: :japanese_ogre:
Is it possible to ALSO execute the default webflow form action AFTER the custom one mentioned below ? The idea is that the client receives an email confirmation from the custom PHP action, then the owner of the website get to see its form section update in his general setting via the default Webflow action. That would be a big help for a lot of us I guess !

Here is the PHP

<?php

// Import PHPMailer classes into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// load the PHPmailer class files directly
require '/home/XXXX/public_html/PHPMailer-master/src/Exception.php';
require '/home/XXXX/public_html//PHPMailer-master/src/PHPMailer.php';
require '/home/XXXX/public_html/PHPMailer-master/src/SMTP.php';

// Instantiation and passing `true` enables exceptions for debug
$mail = new PHPMailer(false);

try {
    // variables
    $from = 'XXXX@gmail.com';
    $to = $_POST['email'];
    $message = $_POST['message'];

    // PHPmailer setup
    $mail = new PHPMailer();
    // $mail->SMTPDebug = SMTP::DEBUG_SERVER; // dev only for debug
    $mail->CharSet = 'UTF-8';
    $mail->isSMTP();
    $mail->SMTPAuth = true;
    $mail->Host = 'smtp.gmail.com';
    $mail->Port = 587;
    $mail->Username = $from;
    $mail->Password = 'XXXX';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;

    // recipients
    $mail->setFrom($from);
    $mail->addAddress($to);

    // content
    $mail->Subject = 'confirmation';
    $mail->isHTML(false);
    $mail->Body = $message;

    $mail->send();
    header("Location: https://www.further.design/thanks");
    // echo 'Message has been sent'; // dev only
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
?>

PS
Here are the security settings I had to tweak for Gmail to accept namecheap server to send email on its behalf:


Yes, but you would need to handle the posts via Ajax.

1 Like

Interesting !

So something like a click listener on the submit button which would prevent the default send behaviour, then execute an AJAX function with the custom action url, followed by the Webflow action ? I couldn’t find documentation in regards to the standard Webflow form action (what url is that) is there any link I could have a look at ? I checked the Webflow developer API but could not find any reference to the default form’s action.

I

Just use a default click event on the on-page form after the Ajax success in your script. Look at the Ajax code in this post on my blog, tweak it for your need.

1 Like

Thanks @webdev !

I had a closer look to the AJAX function used, unfortunately I’m not familiar with jQuery and would like to use only my Strella hosting server with my PHP file since I know those two already work well together. I did try to understand what is going on with your AJAX script but did not fully understand how the data was being transfered.

However, I found on MDN a nice article about FormData that we can bound to the form’s contentent and send via an AJAX post request. I tweaked the script a bit and came up with something like:

// 🥑 on DOM loaded
document.addEventListener("DOMContentLoaded", event => {
  let form = document.getElementById("form");
  form.addEventListener("submit", event => {
    event.preventDefault();
    alert("💡 prevent default");
    // handle AJAX post
    sendAJAXdata();
    alert("💡 AJAX reqest sent");
    // finaly submit default Webflow
    form.submit();
    alert("💡 webflow default action sent");
  });
});

// 🧠 AJAX magic
function sendAJAXdata() {
  let form = document.getElementById("form"),
    formData = new FormData(form),
    request = new XMLHttpRequest();

  let method = "POST",
    action = "https://mail.further.design/mailer_v3.php";

  // Define what happens on successful data submission
  request.addEventListener("load", event => {
    // alert(event.target.responseText);
    alert("success");
  });

  // Define what happens in case of error
  request.addEventListener("error", event => {
    alert("error 🤬");
    // log the content of formData
    for (let pair of formData.entries()) {
      console.log(`${pair[0]} , ${pair[1]}`);
    }
  });

  // Set up the request
  request.open(method, action);
  // The data provided by the user
  request.send(formData);
  
} // end sendAJAXdata()
  1. Here is the codepen I developed.
  2. Here is the webflow read-only link implementation.

At the moment, I don’t understand why the script doesn’t send the form data to my PHP action script but throw the error alert instead. :face_with_raised_eyebrow:

So I’ve tweaked the code a little bit more, and now receive an error 405 after the script has finished running.

The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response status code indicates that the request method is known by the server but is not supported by the target resource.

Any idea where this might be coming from ?

EDIT

I now do receive the Webflow default action email ! :partying_face:
However, the first custom PHP action via AJAX request seems not to go through.:cry:

(The custom PHP script worked perfectly fine when I entered its url directly into the webflow designer panel, my guess is my AJAX code might be missing something)

If the webflow site is on SSL, then the script (form action) needs to be on an SSL endpoint as well. Fix that and circle back.

1 Like

Awesome !
That did the trick @webdev

My custom AJAX request now works and do receive an email from my gmail account (as setuped in my PHP script) instead of the default Weblow form email.

However, I’d still like Webflow to run its default form action after the AJAX request completed which is why I setup the form.submit(); satetement after the AJAX request but still, it seems it doesn’t trigger or get this 405 error message which I don’t really understand.

Here a screen recording should someone have time to watch :slight_smile:

EDIT:

The form actually sometimes send the two messages, but not always ! Please see screenshot below of one of my test where first the custom PHP action was triggered, then the Webflow default action resulting in two email which is exactly what I need, but it doesn’t always work(!)

The Webflow action doesn’t always work, only the custom PHP action is always triggered and 100% send email. Not sure why Webflow seems to be so picky :slight_smile: ?

I thought I could try using async function and promises but still no luck, only the custom action request is being sent while the webflow action request remains ignored.

Here is the codepen to have a look at.

// 🥑 on DOM loaded
document.addEventListener("DOMContentLoaded", event => {
  const form = document.getElementById("form");
  form.addEventListener("submit", event => {
    event.preventDefault();
    alert("prevented default");

    // 🧠 async AJAX promise
    async function sendAJAXdata() {
      const formData = new FormData(form),
        request = new XMLHttpRequest(),
        method = "POST",
        action = "https://mail.further.design/mailer_v3.php";

      // Set up + send the request
      request.open(method, action);
      request.send(formData);
      
      // checking request status
      let state = request.readyState;
      switch (state) {
          case 0: alert("request unsent"); break;
          case 1: alert("request opened"); break;
          case 2: alert("requeest sent & headers received"); break;
          case 3: alert("request loading"); break;
          case 4: alert("request done 🥳"); break;
          default: alert("state unavailable");
      } // end switch()
    } // end sendAJAXdata()

    // 🧠 if the promise is resolved
    sendAJAXdata().then(function() {
      // send webflow default action
      form.submit();
      alert("webflow action sent 🥳");
    }); // end then()
    
  }); // end click listener
}); // end DOM listener

I did some more research on the forums and saw a post from @cyberdave mentioning it would not be possible to call the default Webflow action after an AJAX call. Is that info still actual ? It is pretty weird because 1 out of 10, both my AJAX action and Webflow action are triggered.

I made it ! :partying_face:

I read an interesting article on medium explaining that the open() method takes normaly two parameters (method and action) but COULD also take a third one (boolean) which makes the send() method return only when the response is received if set to false.

I have now setup the request as such:
request.open(method, action, false);

Here is the HTML structure

<form id="form" action="(webflow default)">
  <input type="text" name="name" value="">
  <input type="email" name="email" value="">
  <input type="submit" value="submit">
</form>

Here is the full AJAX function

// 🥑 on DOM loaded
document.addEventListener("DOMContentLoaded", event => {
  const form = document.getElementById("form");
  form.addEventListener("submit", event => {
    event.preventDefault();

    // 🧠 async AJAX promise
    async function sendAJAXdata() {
      const formData = new FormData(form),
        request = new XMLHttpRequest(),
        method = "POST",
        action = "https://XXXX.php";

      // set up + send the request
      request.open(method, action, false);
      request.send(formData);
      console.log(request.readyState);

    } // end sendAJAXdata()

    // 🧠 if the promise is resolved
    sendAJAXdata().then( () => {
      // send webflow default action
      form.submit();
    }); // end then()
    
  }); // end click listener
}); // end DOM listener

Here is the PHP action

<?php

// Import PHPMailer classes into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// load the PHPmailer class files directly
require '/home/XXXX/public_html/PHPMailer-master/src/Exception.php';
require '/home/XXXX/public_html//PHPMailer-master/src/PHPMailer.php';
require '/home/XXXX/public_html/PHPMailer-master/src/SMTP.php';

// Instantiation and passing `true` enables exceptions for debug
$mail = new PHPMailer(false);

try {
    // variables
    $from = 'XXXX@gmail.com';
    $to = $_POST['email'];
    $message = $_POST['message'];

    // PHPmailer setup
    $mail = new PHPMailer();
    // $mail->SMTPDebug = SMTP::DEBUG_SERVER; // dev only for debug
    $mail->CharSet = 'UTF-8';
    $mail->isSMTP();
    $mail->SMTPAuth = true;
    $mail->Host = 'smtp.gmail.com';
    $mail->Port = 587;
    $mail->Username = $from;
    $mail->Password = 'XXXX';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;

    // recipients
    $mail->setFrom($from);
    $mail->addAddress($to);

    // content
    $mail->Subject = 'confirmation';
    $mail->isHTML(false);
    $mail->Body = $message;

    $mail->send();
    header("Location: https://www.XXXX/thanks");
    // echo 'Message has been sent'; // dev only
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
?>

I hope this can help someone in the future !
Thanks @webdev for having me set on the right track ! :cowboy_hat_face:

2 Likes