domingo, 10 de septiembre de 2017

Enviar Email utilizando PHP, Javascript y reCAPTCHA

Si tenemos una página Web posiblemente queramos que los visitantes puedan enviarnos un mensaje de correo para comunicarse con nosotros. Una opción para tener esta característica es poner un enlace del tipo ajibiri@miweb.es para que el visitante haga clic sobre él y se abra su programa de correo. Otra opción es crear un formulario de correo que el visitante pueda rellenar y enviar desde la propia Web. Al menos hay dos razones para elegir la segunda opción. La primera es que no todo el mundo va a visitar tu página desde su casa, ya que puede estar utilizando el PC de otra persona, o el de un establecimiento público, por lo que no siempre va a tener disponible su programa de correo, lo que le obligará a copiar y pegar la dirección en algún portal de correo online. En definitiva, esa opción es la menos amigable. La otra razón para utilizar un formulario es evitar que los ya conocidos robots que se pasean por Internet lean y capten nuestra dirección de correo y la añadan a una lista, lo que provocará con toda seguridad que nos acabe llegando toda la basura del mundo mundial a la dirección de correo que hemos incluido en nuestra Web. Pero la opción del formulario tampoco va a evitar eso por si sola, ya que los robots también son capaces de leer el código fuente de los formularios para enviar uno o más correos de forma automática, por lo que deberemos utilizar una prueba para asegurarnos de que quien envía el correo es una persona y no un robot. En definitiva, deberemos añadir al formulario lo que comúnmente se conoce como CAPTCHA.

Creación del CAPTCHA


Los CAPTCHA se han ido convirtiendo en pruebas cada vez mas complejas a la misma vez que los robots han ido mejorando su tecnología para resolverlos (letras tachadas y/o giradas, operaciones matemáticas, etc). Al final se han convertido en algo, aunque necesario, bastante tedioso de manejar en cada formulario que debemos rellenar. Google dispone de uno llamado reCAPTCHA que habitualmente solo se conforma con que hagamos clic en un recuadro para verificar que no somos un robot. Lo primero que necesitaremos es crearlo en esta página (deberemos identificarnos utilizando una cuenta de Google).

Escribimos un texto identificativo en el primer cuadro de edición (opcional), seleccionamos el reCAPTCHA V2, añadimos la dirección del Sitio o Sitios (uno por línea) donde vamos a utilizarlo (los subdominios estarán incluidos), confirmamos que estamos de acuerdo con los términos del servicio y activamos los avisos en la última línea (opcional), lo que nos permitirá recibir alertas si se detecta algún tipo de problema en nuestro Sitio Web (como de configuración) o un tráfico sospechosamente abultado. Por último hacemos clic en el botón REGISTER para crear el CAPTCHA.



Una vez creado el CAPTCHA, obtenemos la clave del sitio y la clave secreta que necesitaremos para insertarlo en nuestro Sitio Web.



Formulario de envío


Para contener el formulario podemos crear una página HTML simple que llamaremos "email.php" con el siguiente código:

<!DOCTYPE html>
<html>
<head>
<title>Formulario de Email</title>
</head>
<body>
    <form name="eForm" method="POST" action="emailSend.php">
        <label>Nombre *</label><br/>
        <input type="text" id="nombre" name="nombre" required><br/><br/>
        <label>Pais</label><br/>
        <input type="text" id="pais" name="pais"><br/><br/>
        <label>Correo electrónico *</label><br/>
        <input type="text" id="email" name="email" required><br/><br/>
        <label>Asunto</label><br/>
        <input type="text" id="asunto" name="asunto"><br/><br/>
        <label>Mensaje *</label><br/>
        <textarea id="mensaje" name="mensaje" required></textarea><br/><br/>
        <div><button id="btSend" class="button" disabled>Enviar</button><br/><br/>
        * <label style="font-size:11px;">Campos obligatorios</label></div>
    </form>
</body>
</html>

Esta página enviará el formulario a una segunda página llamada "emailSend.php" que crearemos después. He marcado algunos campos con la propiedad "required" que impedirá el envío del formulario si están vacíos (serán campos obligatorios). Y ahora ¿como integramos el reCAPTCHA en el formulario?. Primero necesitamos añadir el script en javascript que proporciona google, y una función que comprobará que el CAPTCHA ha sido "resuelto" por el visitante (fíjate que de forma predeterminada el botón para enviar el formulario está desactivado). Añadimos el siguiente código entre las etiquetas <head> y </head> (el texto "hl=es" sirve para que se muestre el reCAPTCHA en espeñol, si tienes un Sitio Web en varios idiomas, aqui puedes ver la codificación de idiomas que puedes utilizar en vez de "es"):

<script src='https://www.google.com/recaptcha/api.js?hl=es'></script>
<script type="text/javascript">
function checkCaptcha(captchaRes) {
    if (captchaRes == "" || captchaRes == undefined || captchaRes.length == 0) {
        document.getElementById("btSend").disabled = true;
    } else {
        document.getElementById("btSend").disabled = false;
    }
}
</script>

Por último, añadimos el reCAPTCHA al formulario, para que se envíe también el resultado a "emailSend.php". Lo puedes colocar donde quieras que se vea, siempre que esté entre las etiquetas <form ...> y </form>. Yo lo he colocado justo antes del botón de envío (debes sustituir "CLAVE_DEL_SITIO" por la clave del sitio que has obtenido al crear el reCAPTCHA):

<div class="g-recaptcha" data-sitekey="CLAVE_DEL_SITIO" data-callback="checkCaptcha" data-expired-callback="checkCaptcha" style="float:left; margin-right:50px;"></div>

La función "checkCaptcha" que hemos creado antes será ejecutada cuando el visitante interactue con el reCAPTCHA (data-callback) y provocará que el botón para enviar el formulario se active. Si el reCAPTCHA está resuelto, pero el visitante deja pasar un tiempo sin enviar el formulario (alrededor de 2 minutos), el reCAPTCHA se reinicia automáticamente, por lo que la función "checkCaptcha" tambíén será ejecutada en ese momento para desactivar de nuevo el botón de envío del formulario (data-expired-callback). De esta manera, el envío solo se puede realizar si el reCAPTCHA está resuelto. La página "email.php" completa quedaría de la siguiente manera:

<!DOCTYPE html>
<html>
<head>
<title>Formulario de Email</title>
<script src='https://www.google.com/recaptcha/api.js?hl=es'></script>
<script type="text/javascript">
function checkCaptcha(captchaRes) {
    if (captchaRes == "" || captchaRes == undefined || captchaRes.length == 0) {
        document.getElementById("btSend").disabled = true;
    } else {
        document.getElementById("btSend").disabled = false;
    }
}
</script>
</head>
<body>
    <form name="eForm" method="POST" action="emailSend.php">
        <label>Nombre *</label><br/>
        <input type="text" id="nombre" name="nombre" required><br/><br/>
        <label>Pais</label><br/>
        <input type="text" id="pais" name="pais"><br/><br/>
        <label>Correo electrónico *</label><br/>
        <input type="text" id="email" name="email" required><br/><br/>
        <label>Asunto</label><br/>
        <input type="text" id="asunto" name="asunto"><br/><br/>
        <label>Mensaje *</label><br/>
        <textarea id="mensaje" name="mensaje" required></textarea><br/><br/>
        <div class="g-recaptcha" data-sitekey="CLAVE_DEL_SITIO" data-callback="checkCaptcha" data-expired-callback="checkCaptcha" style="float:left; margin-right:50px;"></div>
        <div><button id="btSend" class="button" disabled>Enviar</button><br/><br/>
        * <label style="font-size:11px;">Campos obligatorios</label></div>
    </form>
</body>
</html>

Página de envío del Email


Para integrar reCAPTCHA en la página de envío necesitaremos la librería "recaptchalib.php" para PHP que la gente de Google proporciona. La puedes descargar desde aquí y debes colocarla en la misma carpeta donde tengas la página "emailSend.php" que vamos a crear ahora. Esta página recojerá los datos del formulario y los enviará por correo electrónico.

Debes sustituir:

- "CLAVE_SECRETA" por la clave secreta obtenida al crear el reCAPTCHA.
- "MISITIOWEB.ES" por el nombre real de tu Sitio Web.
- "INFO@MISITIOWEB.ES" por la dirección real a la que quieres enviar el mensaje.

<!DOCTYPE html>
<html>
<head>
<title>Envío de Email</title>
</head>
<body>
<?PHP
include "recaptchalib.php";

$secret = "CLAVE_SECRETA";
$response = null;
$reCaptcha = new ReCaptcha($secret);

if ($_POST["g-recaptcha-response"]) {
    $response = $reCaptcha->verifyResponse(
        "MISITIOWEB.ES",
        $_POST["g-recaptcha-response"]
    );
}

if ($response != null && $response->success) {
    $email_to = "INFO@MISITIOWEB.ES";
    $email_subject = "Mensaje desde mi Web";
    if ($_POST["asunto"] != "") { $email_subject .= " - " . $_POST["asunto"]; }
    $email_message = "<p style='font-size:14px; font-family:Tahoma'>";
    $email_message .= "<b>Nombre:</b> " . $_POST["nombre"] . "<br /><br />";
    $email_message .= "<b>País:</b> " . $_POST["pais"] . "<br /><br />";
    $email_message .= "<b>Correo:</b> " . $_POST["email"] . "<br /><br />";
    $email_message .= "<b>Mensaje:</b><br />" . $_POST["mensaje"];
    $email_message .= "</p>";

    $email_message = nl2br($email_message);
    $email_message = wordwrap($email_message, 70, "\r\n");

    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
    $headers .= "From: " . $_POST["nombre"] . " <" . $_POST["email"] . ">\r\n";

    if (mail($email_to, $email_subject, $email_message, $headers)) {
        echo "El mensaje ha sido enviado con éxito.";
    } else {
        echo "Ha ocurrido un error durante el proceso de envío.";
    }
} else {
    echo "No ha sido posible comprobar la autenticidad del CAPTCHA";
}
?>
</body>
</html>

La librería "recaptchalib.php" es añadida al principio del código PHP para poder conectar con Google y comprobar la autenticidad de la respuesta del reCAPTCHA. Únicamente se enviará el mensaje si la respuesta es recibida desde el formulario de la página "email.php" y es auténtica, por lo tanto ningún robot podrá utilizar "emailSend.php". El mensaje es enviado en formato HTML y con codificación UTF8, por lo que no habrá problema con acentos y carácteres especiales.

Tan solo quedaría personalizar lo que se muestra cuando "el mensaje ha sido enviado con éxito", cuando "ha ocurrido un error durante el proceso de envío" y cuando "no ha sido posible comprobar la autenticidad del CAPTCHA".

También es posible realizar todo en la misma página (solo habría que crear "email.php") pero he creído que resultaba más clara la explicación separando el formulario y el envío del mensaje.

Con todo este trabajo, y quizás reCAPTCHA no sea tan infalible...

No hay comentarios:

Publicar un comentario