Sending mail with an ESP8266 can be handy for a variety of things. I use it to occasionally have a remote ESP8266 send me a message it is still ok and functioning.
It is possible to have the ESP8266 directly access your mail server (such as Gmail, Hotmail, Outlook) and send a message through that, but many mailservers will refuse mail that is being sent from a different domain (your ip) than the mailserver’s.
In those cases is therefore safer to use a third party service like smtp2go.com. As long as you stay below a certain limit of emails, one can get a free account.
I will show how to work with both.
Using SMTP2go
After signing up for smtp2go, you will need to choose a user id and password for your smtp log in. You thus have two sets of id and password: one for your user account and one for the mails you send.
The latter, you need to encode in base 64 to use from your ESP8266. You can do that with an online encoder.
As there is no need to re-invent the wheel, I used this program as a basis and reworked that to my needs, but as your needs might be different from mine, I will just give a general example.
In order to send something more useful than ‘Hello World’, we are going to send the supply voltage and the chip ID. In real life I do not send the suply voltage as that is not so useful, but I send the battery voltage. But to keep it simple in this example we will stick to the supply voltage, which we get with ESP.getVcc()
.
The program is like this: (NOTE: the code might be badly formatted by wordpress, make sure you copy it completely)
#include <ESP8266WiFi.h> // the ESP8266WiFi.h lib const char* SSID = "YourSSID"; const char* PASS = "YourPW"; char server[] = "mail.smtpcorp.com"; ADC_MODE(ADC_VCC); WiFiClient client; void setup() { Serial.begin(115200); delay(10); Serial.println(""); Serial.println(""); Serial.print("Connecting To "); Serial.println(SSID); WiFi.begin(SSID, PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi Connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); byte ret = sendEmail(); } void loop() { } byte sendEmail() { byte thisByte = 0; byte respCode; if (client.connect(server, 2525) == 1) { Serial.println(F("connected")); } else { Serial.println(F("connection failed")); return 0; } if (!eRcv()) return 0; Serial.println(F("Sending EHLO")); client.println("EHLO www.example.com"); if (!eRcv()) return 0; Serial.println(F("Sending auth login")); client.println("auth login"); if (!eRcv()) return 0; Serial.println(F("Sending User")); // Change to your base64, ASCII encoded user client.println("ZV83MTAwMEBnbWFljC5jb31="); // SMTP UserID if (!eRcv()) return 0; Serial.println(F("Sending Password")); // change to your base64, ASCII encoded password client.println("X5pqVU9vYlJjY7Bq");// SMTP Passw if (!eRcv()) return 0; Serial.println(F("Sending From")); // change to your email address (sender) client.println(F("MAIL From: yrmail@gmail.com"));// not important if (!eRcv()) return 0; // change to recipient address Serial.println(F("Sending To")); client.println(F("RCPT To: receiver@gmail.com")); if (!eRcv()) return 0; Serial.println(F("Sending DATA")); client.println(F("DATA")); if (!eRcv()) return 0; Serial.println(F("Sending email")); // change to recipient address client.println(F("To: receiver@gmail.com")); // change to your address client.println(F("From: sender@gmail.com")); client.println(F("Subject: Emails from ESp8266\r\n")); client.print(F("Power is: ")); client.print(ESP.getVcc()); client.println(F("mV")); client.print(F("Device Chip ID: ")); client.println(ESP.getChipId()); Serial.print(F("Voltage is: ")); Serial.print(ESP.getVcc()); client.println(F(".")); if (!eRcv()) return 0; Serial.println(F("Sending QUIT")); client.println(F("QUIT")); if (!eRcv()) return 0; client.stop(); Serial.println(F("disconnected")); return 1; } byte eRcv() { byte respCode; byte thisByte; int loopCount = 0; while (!client.available()) { delay(1); loopCount++; // if nothing received for 10 seconds, timeout if (loopCount > 10000) { client.stop(); Serial.println(F("\r\nTimeout")); return 0; } } respCode = client.peek(); while (client.available()) { thisByte = client.read(); Serial.write(thisByte); } if (respCode >= '4') { // efail(); return 0; } return 1; }
In the example I use “gmail” but ofcourse this can be any other mailservice>
In the program you will also see a line with “yrmail@gmail.com"));// not important
“. I may be wrong but it is not that important what that says. It is the identity under which your mails are grouped in the smpt2go dashboard. Maybe it is easiest to make that equal to the sender address, but it isnot important for the functioning of the program.
The strings that are send are rather flexible. Instead ofclient.println(F("Subject: Emails from ESp8266\r\n"));
On can also do:client.print(F("Subject: "));
if (condition == met)
client.println(F(PREDEFINED_MESSAGE));
Using Google, Hotmail, Outlook, Yahoo mailservers directly
If you prefer to not use an intermediate mail server, it is possible to use a mailserver such as your gmail or Hotmail or any other. That is easiest done with the ESP_Mail_Client library. The HTML Example is a good basis to start with.
For Gmail use the following settings:
- SMTP Server: smtp.gmail.com
- SMTP username: Complete Gmail address
- SMTP password: Your Gmail password
- SMTP port (TLS): 587
- SMTP port (SSL): 465
- SMTP TLS/SSL required: yes
- SMTP Server: smtp.live.com
- SMTP Username: Complete Live/Hotmail email address
- SMTP Password: Your Windows Live Hotmail password
- SMTP Port: 587
- SMTP TLS/SSL Required: Yes
- SMTP Server: smtp.office365.com
- SMTP Username: Complete Outlook email address
- SMTP Password: Your Outlook password
- SMTP Port: 587
- SMTP TLS/SSL Required: Yes
SMTP server: smtp.mail.yahoo.com
SMTP username: Your full Yahoo email address (including @yahoo.com)
SMTP password: Your Yahoo Mail password
SMTP port: 465 or 587
SMTP TLS/SSL Required: Yes
/** * This example will send the Email in * the html version. * * * Created by K. Suwatchai (Mobizt) * * Email: suwatchai@outlook.com * * Github: https://github.com/mobizt/ESP-Mail-Client * * Copyright (c) 2021 mobizt * */ //To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 #include <Arduino.h> #if defined(ESP32) #include <WiFi.h> #elif defined(ESP8266) #include <ESP8266WiFi.h> #endif #include <ESP_Mail_Client.h> #define WIFI_SSID "################" #define WIFI_PASSWORD "################" /** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc * and use the app password as password with your yahoo mail account to login. * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en */ #define SMTP_HOST "################" /** The smtp port e.g. * 25 or esp_mail_smtp_port_25 * 465 or esp_mail_smtp_port_465 * 587 or esp_mail_smtp_port_587 */ #define SMTP_PORT 25 /* The log in credentials */ #define AUTHOR_EMAIL "################" #define AUTHOR_PASSWORD "################" /* The SMTP Session object used for Email sending */ SMTPSession smtp; /* Callback function to get the Email sending status */ void smtpCallback(SMTP_Status status); void setup() { Serial.begin(115200); #if defined(ARDUINO_ARCH_SAMD) while (!Serial) ; Serial.println(); Serial.println("**** Custom built WiFiNINA firmware need to be installed.****\nTo install firmware, read the instruction here, https://github.com/mobizt/ESP-Mail-Client#install-custom-built-wifinina-firmware"); #endif Serial.println(); Serial.print("Connecting to AP"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(200); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println(); /** Enable the debug via Serial port * none debug or 0 * basic debug or 1 */ smtp.debug(1); /* Set the callback function to get the sending results */ smtp.callback(smtpCallback); /* Declare the session config data */ ESP_Mail_Session session; /** ######################################################## * Some properties of SMTPSession data and parameters pass to * SMTP_Message class accept the pointer to constant char * i.e. const char*. * * You may assign a string literal to that properties or function * like below example. * * session.login.user_domain = "mydomain.net"; * session.login.user_domain = String("mydomain.net").c_str(); * * or * * String doman = "mydomain.net"; * session.login.user_domain = domain.c_str(); * * And * * String name = "Jack " + String("dawson"); * String email = "jack_dawson" + String(123) + "@mail.com"; * * message.addRecipient(name.c_str(), email.c_str()); * * message.addHeader(String("Message-ID: <abcde.fghij@gmail.com>").c_str()); * * or * * String header = "Message-ID: <abcde.fghij@gmail.com>"; * message.addHeader(header.c_str()); * * ########################################################### */ /* Set the session config */ session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD; session.login.user_domain = "mydomain.net"; /* Declare the message class */ SMTP_Message message; /* Set the message headers */ message.sender.name = "ESP Mail"; message.sender.email = AUTHOR_EMAIL; message.subject = "Test sending html Email"; message.addRecipient("Admin", "####@#####_dot_com"); String htmlMsg = "<p>This is the <span style=\"color:#ff0000;\">html text</span> message.</p><p>The message was sent via ESP device.</p>"; message.html.content = htmlMsg.c_str(); /** The html text message character set e.g. * us-ascii * utf-8 * utf-7 * The default value is utf-8 */ message.html.charSet = "us-ascii"; /** The content transfer encoding e.g. * enc_7bit or "7bit" (not encoded) * enc_qp or "quoted-printable" (encoded) * enc_base64 or "base64" (encoded) * enc_binary or "binary" (not encoded) * enc_8bit or "8bit" (not encoded) * The default value is "7bit" */ message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; /** The message priority * esp_mail_smtp_priority_high or 1 * esp_mail_smtp_priority_normal or 3 * esp_mail_smtp_priority_low or 5 * The default value is esp_mail_smtp_priority_low */ message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; /** The Delivery Status Notifications e.g. * esp_mail_smtp_notify_never * esp_mail_smtp_notify_success * esp_mail_smtp_notify_failure * esp_mail_smtp_notify_delay * The default value is esp_mail_smtp_notify_never */ message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; /* Set the custom message header */ message.addHeader("Message-ID: <abcde.fghij@gmail.com>"); /* Connect to server with the session config */ if (!smtp.connect(&session)) return; /* Start sending Email and close the session */ if (!MailClient.sendMail(&smtp, &message)) Serial.println("Error sending Email, " + smtp.errorReason()); ESP_MAIL_PRINTF("Free Heap: %d\n", MailClient.getFreeHeap()); } void loop() { } /* Callback function to get the Email sending status */ void smtpCallback(SMTP_Status status) { /* Print the current status */ Serial.println(status.info()); /* Print the sending result */ if (status.success()) { Serial.println("----------------"); ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount()); ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++) { /* Get the result item */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt); ESP_MAIL_PRINTF("Message No: %d\n", i + 1); ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients); ESP_MAIL_PRINTF("Subject: %s\n", result.subject); } Serial.println("----------------\n"); } }