Aprende a enviar correos electrónicos con el ESP32 usando un servidor SMTP. Te mostraremos cómo enviar un correo simple con HTML o texto plano y cómo enviar archivos adjuntos como imágenes y archivos .txt. La placa ESP32 se programará usando Arduino IDE y la librería ReadyMail.
En este tutorial cubrimos los siguientes temas: enviar correo con el ESP32 (HTML y texto plano) y enviar correos con adjuntos (imagen y archivo .txt).
Introducción a los servidores SMTP
SMTP significa Simple Mail Transfer Protocol (Protocolo Simple de Transferencia de Correo), y es un estándar de Internet para la transmisión de correo electrónico. Para enviar correos usando un ESP32, necesitas conectarlo a un servidor SMTP.
La librería ReadyMail
Para enviar correos con el ESP32, usaremos la librería ReadyMail. Esta librería permite al ESP32 enviar y recibir correos con o sin adjuntos a través de servidores SMTP e IMAP. En este tutorial, usaremos SMTP para enviar un correo con y sin adjuntos. Como ejemplo, enviaremos una imagen (.png) y un archivo de texto (.txt). Los archivos enviados por correo pueden guardarse en el sistema de archivos del ESP32 (SPIFFS, LittleFS) o en una tarjeta microSD (no cubierto en este tutorial).
Instalar la librería ReadyMail
Antes de proceder con este tutorial, necesitas instalar la librería ReadyMail. Ve a Programa > Incluir Librería > Gestionar Librerías y busca ReadyMail. Instala la librería ReadyMail de Mobizt.
Correo del remitente: crea una cuenta nueva
Recomendamos crear una cuenta de correo nueva para enviar los correos a tu dirección de correo personal principal. No uses tu correo personal principal para enviar correos vía ESP32. Si algo sale mal en tu código o, por error, haces demasiadas peticiones, puedes ser baneado o tener tu cuenta temporalmente deshabilitada.
Usaremos una cuenta de Gmail recién creada para enviar los correos, pero puedes usar cualquier otro proveedor de correo. El correo del receptor puede ser tu correo personal sin ningún problema.
Crear una cuenta de correo remitente
Crea una nueva cuenta de correo para enviar correos con el ESP32. Si quieres usar una cuenta de Gmail, ve al enlace de creación de cuentas de Google para crear una nueva.
Crear una contraseña de aplicación (App Password)
Necesitas crear una contraseña de aplicación para que el ESP32 pueda enviar correos usando tu cuenta de Gmail. Una App Password es un código de acceso de 16 dígitos que da permiso a una aplicación o dispositivo menos seguro para acceder a tu cuenta de Google.
Una contraseña de aplicación solo se puede usar con cuentas que tengan la verificación en dos pasos activada. Sigue estos pasos:
Abre tu cuenta de Google. En el panel de búsqueda, selecciona Seguridad. Bajo “Iniciar sesión en Google”, selecciona Verificación en dos pasos > Empezar. Sigue los pasos en pantalla.
Después de habilitar la verificación en dos pasos, puedes crear una contraseña de aplicación. Abre tu cuenta de Google. En el panel de búsqueda, busca Contraseñas de aplicaciones. Abre el menú de Contraseñas de aplicaciones. Dale un nombre a la contraseña de aplicación, por ejemplo ESP. Después, pulsa en Crear.
Aparecerá una ventana con una contraseña que usarás con el ESP32 para enviar correos. Guarda esa contraseña (aunque diga que no necesitarás recordarla) porque la necesitarás más tarde.
Si estás usando otro proveedor de correo, comprueba cómo crear una contraseña de aplicación. Deberías poder encontrar las instrucciones con una búsqueda rápida en Google: “tu_proveedor_de_correo + crear contraseña de aplicación”.
Configuración del servidor SMTP de Gmail
Para enviar correos con el ESP32, también necesitas conocer la configuración del servidor SMTP de tu proveedor de correo.
Si estás usando una cuenta de Gmail, estos son los detalles del servidor SMTP:
Servidor SMTP: smtp.gmail.com. Usuario SMTP: tu dirección completa de Gmail. Contraseña SMTP: tu contraseña de aplicación. Puerto SMTP (TLS): 587. Puerto SMTP (SSL): 465. TLS/SSL requerido: sí.
Configuración del servidor SMTP de Outlook
Para cuentas de Outlook, esta es la configuración del servidor SMTP:
Servidor SMTP: smtp.office365.com. Usuario SMTP: tu dirección completa de correo Outlook. Contraseña SMTP: tu contraseña de Outlook. Puerto SMTP: 587. TLS/SSL requerido: sí.
Configuración del servidor SMTP de Live o Hotmail
Para cuentas de Live o Hotmail, esta es la configuración del servidor SMTP:
Servidor SMTP: smtp.live.com. Usuario SMTP: tu dirección completa de Live/Hotmail. Contraseña SMTP: tu contraseña de Windows Live Hotmail. Puerto SMTP: 587. TLS/SSL requerido: sí.
Si estás usando otro proveedor de correo, necesitas buscar la configuración de su servidor SMTP. Ahora tienes todo listo para empezar a enviar correos con tu ESP32.
Enviar un correo con HTML o texto plano con el ESP32
El siguiente código envía un correo vía servidor SMTP con HTML o texto plano. Con fines de demostración, el ESP32 envía un correo una vez cuando arranca. Después, deberías ser capaz de modificar el código e integrarlo en tus propios proyectos.
No subas el código todavía. Necesitas insertar tus credenciales de red, así como configurar el correo del remitente, los detalles del servidor SMTP, el destinatario y el mensaje.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Detalles completos del proyecto en: https://RandomNerdTutorials.com/esp32-send-email-smtp-server-arduino-ide/
Basado en el ejemplo proporcionado por la librería ReadyMail: https://github.com/mobizt/ReadyMail/
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#define ENABLE_SMTP
#define ENABLE_DEBUG
#include <ReadyMail.h>
// REEMPLAZA CON LAS CREDENCIALES DE TU RED
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Configuración del remitente SMTP (GMAIL)
// Cambia si usas un proveedor diferente
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465
// Correo del remitente, contraseña de aplicación y nombre
#define AUTHOR_EMAIL "SENDER_EMAIL@XXX.com"
#define AUTHOR_APP_PASS "EMAIL_APP_PASSWORD"
#define AUTHOR_NAME "ESP32"
// Correo del destinatario
#define RECIPIENT_EMAIL "RECIPIENTE_EMAIL@XXXX.com"
#define RECIPIENT_NAME "RECIPIENT_NAME"
WiFiClientSecure ssl_client;
SMTPClient smtp(ssl_client);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
ssl_client.setInsecure();
auto statusCallback = [](SMTPStatus status) {
Serial.println(status.text);
};
smtp.connect(SMTP_HOST, SMTP_PORT, statusCallback);
if (smtp.isConnected()) {
smtp.authenticate(AUTHOR_EMAIL, AUTHOR_APP_PASS, readymail_auth_password);
SMTPMessage msg;
msg.headers.add(rfc822_from, String(AUTHOR_NAME) + " <" + AUTHOR_EMAIL + ">");
msg.headers.add(rfc822_to, String(RECIPIENT_NAME) + " <" + RECIPIENT_EMAIL + ">");
msg.headers.add(rfc822_subject, "Hello from the ESP32");
//msg.text.body("This is a plain text message.");
msg.html.body("<html><body><h1>Hello!</h1></body></html>");
// Establece la hora de configuración NTP
/* Para horas al este del Meridiano Principal usa 0-12
Para horas al oeste del Meridiano Principal añade 12 al offset.
Ej. American/Denver GMT sería -6. 6 + 12 = 18 */
const int gmtOffset_sec = 0; // offset de tiempo en segundos
const int daylightOffset_sec = 0; // offset de horario de verano en segundos
configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
// Establece el timestamp del correo
while (time(nullptr) < 100000) delay(100);
msg.timestamp = time(nullptr);
smtp.send(msg);
}
}
void loop() {
}
Cómo funciona el código paso a paso
Este código está adaptado de un ejemplo proporcionado por la librería. Veamos las partes relevantes que necesitas o puedes necesitar cambiar.
Primero, incluye las librerías requeridas. De la librería ReadyMail, usaremos SMTP para enviar los correos, y habilitaremos las funciones de depuración para comprobar el estado de envío del correo. Por eso incluimos las siguientes líneas:
#define ENABLE_SMTP
#define ENABLE_DEBUG
Después, inserta tus credenciales de red en las siguientes líneas. Inserta la configuración de tu servidor SMTP. Si estás usando una cuenta de Gmail para enviar los correos, esta es la configuración: servidor smtp.gmail.com y puerto 465.
Inserta las credenciales de inicio de sesión del correo remitente (correo completo y contraseña de aplicación que creaste antes, no la contraseña del correo, es la APP PASSWORD) y el nombre del remitente. Inserta el correo del destinatario y su nombre.
Se crea un WiFiClientSecure para comunicarse con el servidor SMTP.
En el setup(), se inicializa el Monitor Serie y se conecta el ESP32 a Wi-Fi.
Se crea una función llamada statusCallback que recibe SMTPStatus y lo imprime en el Monitor Serie. Básicamente, esto imprimirá el estado de los distintos pasos necesarios para enviar el correo.
Después, se conecta al host SMTP y se autentica. Se crea un mensaje SMTP (SMTPMessage) llamado msg. Se añaden las cabeceras del correo al mensaje: nombre y correo del autor, nombre y correo del destinatario, y asunto del correo.
Después, se establece el cuerpo del correo. Puedes enviar texto plano con msg.text.body() o enviar texto HTML con msg.html.body(). Usa cada método de uno en uno. Después, se configura el timestamp del correo usando un servidor NTP. Ajusta el offset GMT y el horario de verano si es necesario.
Finalmente, se envía el correo. Es tan simple como smtp.send(msg). Con fines de demostración y prueba, enviamos el correo una vez en el setup(), y el loop() está vacío.
Demostración
Sube el código a tu ESP32. Después de subir, abre el Monitor Serie a 115200 baudios. Pulsa el botón Reset del ESP32. Si todo va como se espera, deberías obtener un mensaje similar en el Monitor Serie indicando que el correo se envió con éxito.
Comprueba tu cuenta de correo. Deberías haber recibido un correo de tu placa ESP32. Si has habilitado el mensaje de texto plano, el correo se verá como un correo sencillo. Si has enviado HTML, se verá con el formato HTML.
Enviar adjuntos por correo con el ESP32
En esta sección, te mostraremos cómo enviar adjuntos en tus correos enviados por el ESP32. Te mostraremos cómo enviar archivos .txt o imágenes. Esto puede ser útil para enviar un archivo .txt con lecturas de sensores de las últimas horas o para enviar una foto capturada por un ESP32-CAM.
Para este tutorial, los archivos a enviar deben estar guardados en el sistema de archivos del ESP32 (LittleFS).
Subir archivos a LittleFS
Para enviar archivos por correo, estos deben estar guardados en el sistema de archivos del ESP32 o en una tarjeta microSD. Subiremos una imagen y un archivo .txt al sistema de archivos LittleFS del ESP32 usando el plugin ESP32 Filesystem Uploader para Arduino IDE. Sigue el tutorial correspondiente para instalar el plugin si aún no lo tienes instalado.
Crea un nuevo sketch de Arduino y guárdalo. Ve a Programa > Mostrar carpeta del sketch. Dentro de la carpeta del sketch de Arduino, crea una carpeta llamada data. Mueve un archivo .png y un archivo .txt a tu carpeta data.
Nota: con el código por defecto, tus archivos deben llamarse
image.pngytext_file.txt. Alternativamente, puedes modificar el código para importar archivos con un nombre diferente.
Tu estructura de carpetas debería verse así: una carpeta principal del sketch, con una subcarpeta data que contiene image.png y text_file.txt. Después de mover los archivos a la carpeta data, necesitas subirlos a tu placa. En Arduino IDE, pulsa [Ctrl] + [Shift] + [P] en Windows o [⌘] + [Shift] + [P] en macOS para abrir la paleta de comandos. Busca el comando Upload LittleFS to Pico/ESP8266/ESP32 y púlsalo. Deberías obtener un mensaje de éxito en la ventana de depuración. Si los archivos se subieron correctamente, pasa a la siguiente sección.
Nota: si empiezas a ver muchos puntos
….___…..____siendo impresos en la ventana de depuración, necesitas mantener pulsado el botón BOOT del ESP32 para que los archivos se suban.
Código para enviar adjuntos
El siguiente código envía un correo con un archivo .txt y una imagen adjunta. Antes de subir el código, asegúrate de insertar la configuración de tu correo remitente y el correo del destinatario.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Detalles completos del proyecto en: https://RandomNerdTutorials.com/esp32-send-email-smtp-server-arduino-ide/
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <FS.h>
#include <LittleFS.h>
#define ENABLE_SMTP // Permite la clase SMTP y los datos
#define ENABLE_DEBUG // Permite la depuración
#define ENABLE_FS // Permite la integración con el sistema de archivos
#define MY_FS LittleFS
#include <ReadyMail.h>
// REEMPLAZA CON LAS CREDENCIALES DE TU RED
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Configuración del remitente SMTP (GMAIL)
// Cambia si usas un proveedor diferente
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465
// Correo del remitente, contraseña de aplicación y nombre
#define AUTHOR_EMAIL "SENDER_EMAIL@XXX.com"
#define AUTHOR_APP_PASS "EMAIL_APP_PASSWORD"
#define AUTHOR_NAME "ESP32"
// Correo del destinatario
#define RECIPIENT_EMAIL "RECIPIENTE_EMAIL@XXXX.com"
#define RECIPIENT_NAME "RECIPIENT_NAME"
WiFiClientSecure ssl_client;
SMTPClient smtp(ssl_client);
// Crea un objeto archivo
File myFile;
void fileCb(File &file, const char *filename, readymail_file_operating_mode mode) {
switch (mode) {
case readymail_file_mode_open_read:
myFile = MY_FS.open(filename, FILE_OPEN_MODE_READ);
break;
case readymail_file_mode_open_write:
myFile = MY_FS.open(filename, FILE_OPEN_MODE_WRITE);
break;
case readymail_file_mode_open_append:
myFile = MY_FS.open(filename, FILE_OPEN_MODE_APPEND);
break;
case readymail_file_mode_remove:
MY_FS.remove(filename);
break;
default:
break;
}
// Esto es requerido por la librería para obtener el objeto archivo
// que usa en sus procesos de lectura/escritura.
file = myFile;
}
void initLittleFS() {
if (!MY_FS.begin(true)){
Serial.println("LittleFS Mount Failed");
return;
}
}
// Para más información, consulta http://bit.ly/474niML
void smtpCb(SMTPStatus status){
if (status.progress.available)
ReadyMail.printf("ReadyMail[smtp][%d] Uploading file %s, %d %% completed\n", status.state,
status.progress.filename.c_str(), status.progress.value);
else
ReadyMail.printf("ReadyMail[smtp][%d]%s\n", status.state, status.text.c_str());
}
void addFileAttachment(SMTPMessage &msg, const String &filename, const String &mime, const String &name, FileCallback cb, const String &filepath, const String &encoding = "", const String &cid = "") {
Attachment attachment;
attachment.filename = filename;
attachment.mime = mime;
attachment.name = name;
// La disposición de contenido inline.
// Debe coincidir con el cid del src de la imagen en el cuerpo HTML
attachment.content_id = cid;
attachment.attach_file.callback = cb;
attachment.attach_file.path = filepath;
// Especifica solo cuando el contenido ya está codificado.
attachment.content_encoding = encoding;
msg.attachments.add(attachment, cid.length() > 0 ? attach_type_inline : attach_type_attachment);
}
void setup() {
Serial.begin(115200);
Serial.println();
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
initLittleFS();
// Si la verificación del certificado SSL del servidor fue ignorada para este WiFiClientSecure del ESP32.
// Para verificar el CA raíz o el certificado SSL del servidor,
// consulta la documentación de tu cliente SSL.
ssl_client.setInsecure();
smtp.connect(SMTP_HOST, SMTP_PORT, smtpCb);
if (!smtp.isConnected())
return;
smtp.authenticate(AUTHOR_EMAIL, AUTHOR_APP_PASS, readymail_auth_password);
if (!smtp.isAuthenticated())
return;
SMTPMessage msg;
msg.headers.add(rfc822_from, String(AUTHOR_NAME) + " <" + AUTHOR_EMAIL + ">");
msg.headers.add(rfc822_to, String(RECIPIENT_NAME) + " <" + RECIPIENT_EMAIL + ">");
msg.headers.add(rfc822_subject, "ESP32 Attachments");
String bodyText = "Hello! See attachments";
msg.text.body(bodyText);
msg.html.body("<html><body><div style=\"color:#cc0066;\">" + bodyText + "</div></body></html>");
// Establece la hora de configuración NTP
/* Para horas al este del Meridiano Principal usa 0-12
Para horas al oeste del Meridiano Principal añade 12 al offset.
Ej. American/Denver GMT sería -6. 6 + 12 = 18 */
const int gmtOffset_sec = 0; // offset de tiempo en segundos
const int daylightOffset_sec = 0; // offset de horario de verano en segundos
configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
// Establece el timestamp del correo
while (time(nullptr) < 100000) delay(100);
msg.timestamp = time(nullptr);
addFileAttachment(msg, "image.png", "image/png", "image.png", fileCb, "/image.png");
addFileAttachment(msg, "text_file.txt", "text/plain", "text_file.txt", fileCb, "/text_file.txt");
Serial.print("Sending email");
smtp.send(msg);
}
void loop(){
}
Cómo funciona el código de adjuntos paso a paso
Este código es muy similar al anterior, así que solo veremos las partes relevantes para enviar adjuntos guardados en el sistema de archivos del ESP32.
Necesitamos incluir las librerías FS y LittleFS para manejar archivos con el ESP32. Se habilita la integración con el sistema de archivos y se establece tu tipo de sistema de archivos (puede ser SPIFFS, LittleFS o SD).
Necesitas crear un objeto File y una función de callback que se llame cuando se cree el adjunto. Usamos la función fileCb() creada en uno de los ejemplos de la librería. También necesitamos inicializar el sistema de archivos, lo hacemos en la función initLittleFS().
Necesitas crear una función de callback que se ejecutará al enviar el correo. Usamos la misma que en uno de los ejemplos de la librería, la función smtpCb() que informa del progreso del proceso.
La función addFileAttachment() contiene todos los pasos necesarios para crear y añadir un adjunto a tu mensaje de correo. Aquí tienes una lista de los parámetros que necesitas pasar a la función y qué significan:
SMTPMessage &msg: el objeto mensaje de correo donde añadiremos el adjunto. const String &filename: el nombre del archivo que verá el destinatario. const String &mime: el tipo MIME del archivo. Por ejemplo: image/png, text/plain, etc. const String &name: el nombre para mostrar del adjunto. FileCallback cb: la función de callback que se llamará cuando añadamos el adjunto. const String &filepath: la ruta del archivo en el sistema de archivos. const String &encoding = "": déjalo vacío, a menos que el contenido ya esté codificado. const String &cid = "": este es el ID de contenido para adjuntos inline que se usan para incrustar imágenes en el cuerpo de mensajes HTML.
En el setup(), se inicializa el Monitor Serie, se conecta a Wi-Fi y se inicializa el sistema de archivos LittleFS. Después, para añadir un adjunto a nuestro mensaje, llamamos a la función addFileAttachment() con los parámetros correctos. Estamos enviando un archivo de imagen llamado image.png (guardado en el sistema de archivos LittleFS) y también un archivo de texto text_file.txt guardado también en LittleFS.
Finalmente, solo necesitas enviar el mensaje como hiciste con el ejemplo anterior, usando el método send().
Demostración
Después de subir el código, abre el Monitor Serie a 115200 baudios y pulsa el botón EN/RESET integrado en la placa. Si todo va bien, deberías obtener un mensaje similar en el Monitor Serie indicando que el correo se envió con éxito.
Comprueba la dirección de correo del destinatario. Deberías tener un nuevo correo con dos adjuntos.
Conclusión: lo que has aprendido
En este tutorial, has aprendido cómo enviar correos con el ESP32 usando un servidor SMTP. Para que este método funcione, el ESP32 debe tener acceso a internet.
Si no quieres usar un servidor SMTP, también puedes escribir un script en PHP para enviar notificaciones por correo con la placa ESP32 o ESP8266.
Has aprendido cómo enviar un correo simple con texto y con adjuntos. Cuando usas adjuntos, estos deben estar guardados en el sistema de archivos del ESP32 (LittleFS) o en una tarjeta microSD (no cubierto en este tutorial).
Los ejemplos presentados muestran cómo enviar un solo correo cuando el ESP32 arranca. La idea es modificar el código e incluirlo en tus propios proyectos. Por ejemplo, puede ser útil para enviar un archivo .txt con las lecturas de sensores, enviar una foto capturada con el ESP32-CAM, usar deep sleep para despertar tu placa cada hora y enviar un correo con datos, etc.
Enviar correos desde el ESP32 es una de esas capacidades que convierten un proyecto de aficionado en un sistema profesional. Combínalo con deep sleep para notificaciones periódicas, con sensores para alertas automáticas, o con ESP32-CAM para enviar imágenes. Las posibilidades son prácticamente ilimitadas.
Descubre más desde CIBERED
Suscríbete y recibe las últimas entradas en tu correo electrónico.
