ESP8266 NodeMCU Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino)

In this tutorial, you’ll learn how to send emails with the ESP8266 NodeMCU board using an SMTP server. We’ll show how to send an email with raw text, HTML text, and how to send attachments like images and files (.txt). We’ll program the ESP8266 NodeMCU board with the Arduino core.

ESP8266 NodeMCU Send Emails using an SMTP Server HTML Text and Attachments Arduino IDE

Updated 25 June 2023

In this tutorial, we cover the following topics:

We have a similar tutorial for the ESP32 board: ESP32 Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino IDE)

Introducing SMTP Servers

SMTP means Simple Mail Transfer Protocol and it is an internet standard for email transmission. To send emails using an ESP8266, you need to connect it to an SMTP Server.

ESP-Mail-Client Library

To send emails with the ESP8266 NodeMCU board, we’ll use the ESP-Mail-Client library. This library allows the ESP8266 to send and receive emails with or without attachments via SMTP and IMAP servers. If you like this library and you’ll use it in your projects, consider supporting the developer’s work—see the library GitHub page.

In this tutorial, we’ll use SMTP to send an email with and without attachments. As an example, we’ll send an image (.png) and a text (.txt) file. The files to be sent via email can be saved in the ESP8266 Filesystem (SPIFFS or LittleFS) or in a microSD card (not covered in this tutorial).

Installing the ESP-Mail-Client Library

Before proceeding with this tutorial, you need to install the ESP-Mail-Client library.

Go to Sketch > Include Library > Manage Libraries and search for ESP Mail Client. Install the ESP Mail Client library by Mobizt.

Install ESP Mail Client Library Arduino IDE

Sender Email (New Account)

We recommend creating a new email account to send the emails to your main personal email address. Do not use your main personal email to send emails via ESP8266. If something goes wrong in your code or if you make too many requests by mistake, you can be banned or have your account temporarily disabled.

We’ll use a newly created Gmail.com account to send the emails, but you can use any other email provider. The receiver email can be your personal email without any problem.

Create a Sender Email Account

Create a new email account for sending emails with the ESP8266. If you want to use a Gmail account, go to this link to create a new one.

Gmail Create a new account

Create an App Password

You need to create an app password so that the ESP32 is able to send emails using your Gmail account. An App Password is a 16-digit passcode that gives a less secure app or device permission to access your Google Account. Learn more about sign-in with app passwords here.

An app password can only be used with accounts that have 2-step verification turned on.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select 2-Step Verification > Get started.
  4. Follow the on-screen steps.

After enabling 2-step verification, you can create an app password.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select App Passwords.
Create app password gmail
  1. In the Select app field, choose mail. For the device, select Other and give it a name, for example ESP32. Then, click on Generate. It will pop-up a window with a password that you’ll use with the ESP32 or ESP8266 to send emails. Save that password (even though it says you won’t need to remember it) because you’ll need it later.
Generated App password gmail

Now, you should have an app password that you’ll use on the ESP32 code to send the emails.

Gmail app password created for ESP8266 send emails

If you’re using another email provider, check how to create an app password. You should be able to find the instructions with a quick google search “your_email_provider + create app password”.

Gmail SMTP Server Settings

If you’re using a Gmail account, these are the SMTP Server details:

  • 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

Outlook SMTP Server Settings

For Outlook accounts, these are the SMTP Server settings:

  • SMTP Server: smtp.office365.com
  • SMTP Username: Complete Outlook email address
  • SMTP Password: Your Outlook password
  • SMTP Port: 587
  • SMTP TLS/SSL Required: Yes

Live or Hotmail SMTP Server Settings

For Live or Hotmail accounts, these are the SMTP Server settings:

  • 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

If you’re using another email provider, you need to search for its SMTP Server settings. Now, you have everything ready to start sending emails with your ESP8266.

In your Arduino IDE, you can go to File > Examples > ESP-Mail-Client and experiment with the examples provided—you need to insert your email details (sender and recipient accounts), the SMTP server settings, and your SSID and password.


Send an Email with HTML or Raw Text with ESP8266

The following code sends an email via SMTP Server with HTML or raw text. As an example, the ESP8266 sends an email once when it boots. Then, you should be able to modify the code and integrate it into your own projects.

Don’t upload the code yet, you need to make some modifications to make it work for you.

/*
  Rui Santos
  Complete project details at:
   - ESP32: https://RandomNerdTutorials.com/esp32-send-email-smtp-server-arduino-ide/
   - ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-send-email-smtp-server-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  Example adapted from: https://github.com/mobizt/ESP-Mail-Client
*/

#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <ESP_Mail_Client.h>

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

/* The sign in credentials */
#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_APP_PASS"

/* Recipient's email*/
#define RECIPIENT_EMAIL "[email protected]"

/* Declare the global used SMTPSession object for SMTP transport */
SMTPSession smtp;

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);

void setup(){
  Serial.begin(115200);
  Serial.println();
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  /*  Set the network reconnection option */
  MailClient.networkReconnect(true);

  /** Enable the debug via Serial port
   * 0 for no debugging
   * 1 for basic level debugging
   *
   * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h
   */
  smtp.debug(1);

  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

  /* Declare the Session_Config for user defined session credentials */
  Session_Config config;

  /* Set the session config */
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = "";

  /*
  Set the NTP config time
  For times east of the Prime Meridian use 0-12
  For times west of the Prime Meridian add 12 to the offset.
  Ex. American/Denver GMT would be -6. 6 + 12 = 18
  See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
  */
  config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
  config.time.gmt_offset = 3;
  config.time.day_light_offset = 0;

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = F("ESP");
  message.sender.email = AUTHOR_EMAIL;
  message.subject = F("ESP Test Email");
  message.addRecipient(F("Sara"), RECIPIENT_EMAIL);
    
  /*Send HTML message*/
  /*String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</h1><p>- Sent from ESP board</p></div>";
  message.html.content = htmlMsg.c_str();
  message.html.content = htmlMsg.c_str();
  message.text.charSet = "us-ascii";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

   
  //Send raw text message
  String textMsg = "Hello World! - Sent from ESP board";
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
  
  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;


  /* Connect to the server */
  if (!smtp.connect(&config)){
    ESP_MAIL_PRINTF("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    return;
  }

  if (!smtp.isLoggedIn()){
    Serial.println("\nNot yet logged in.");
  }
  else{
    if (smtp.isAuthenticated())
      Serial.println("\nSuccessfully logged in.");
    else
      Serial.println("\nConnected with no Auth.");
  }

  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message))
    ESP_MAIL_PRINTF("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());

}

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()){
    // ESP_MAIL_PRINTF used in the examples is for format printing via debug Serial port
    // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266.
    // In ESP8266 and ESP32, you can use Serial.printf directly.

    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failed: %d\n", status.failedCount());
    Serial.println("----------------\n");

    for (size_t i = 0; i < smtp.sendingResult.size(); i++)
    {
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);

      // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if
      // your device time was synched with NTP server.
      // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970.
      // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970)
      
      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str());
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients.c_str());
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
    }
    Serial.println("----------------\n");

    // You need to clear sending result as the memory usage will grow up.
    smtp.sendingResult.clear();
  }
}

View raw code

You need to insert your network credentials and set the sender email, SMTP Server details, recipient, and message.

How the Code Works

This code is adapted from an example provided by the library. The example is well commented so that you understand what each line of code does. Let’s just take a look at the relevant parts that you need or may need to change.

First, insert your network credentials in the following lines:

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

Insert your SMTP server settings. If you’re using a Gmail account to send the emails, these are the settings:

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

Insert the sender email sign in credentials (complete email and APP password you created previously)

#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_PASS"

Insert the recipient email:

#define RECIPIENT_EMAIL "[email protected]"

You may need to adjust the gmt_offset variable depending on your location so that the email is timestamped with the right time.

config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
config.time.gmt_offset = 3;
config.time.day_light_offset = 0;

Set the message headers in the following lines in the setup()—sender name, sender email, email subject, and the recipient name and email:

/* Set the message headers */
message.sender.name = "ESP";
message.sender.email = AUTHOR_EMAIL;
message.subject = "ESP Test Email";
message.addRecipient("Sara", RECIPIENT_EMAIL);

In the following lines, set the content of the message (raw text) in the textMsg variable:

//Send raw text message
String textMsg = "Hello World! - Sent from ESP board";
message.text.content = textMsg.c_str();
message.text.charSet = "us-ascii";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

If you want to send HTML text instead, uncomment the following lines— you should insert your HTML text in the htmlMsg variable.

/*Send HTML message*/
/*String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</h1><p>- Sent from ESP board</p></div>";
message.html.content = htmlMsg.c_str();
message.html.content = htmlMsg.c_str();
message.text.charSet = "us-ascii";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

Finally, the following lines send the message:

if (!MailClient.sendMail(&smtp, &message))
    Serial.println("Error sending Email, " + smtp.errorReason());

Demonstration

Upload the code to your ESP8266. After uploading, open the Serial Monitor at a baud rate of 115200.

If everything goes as expected you should get a similar message in the Serial Monitor.

ESP8266 NodeMCU Send Email Message Successfully Serial Monitor

Check your email account. You should have received an email from your ESP8266 board.

Email received from ESP8266 Board Gmail Account

If you set the option to send a message with HTML text, this is how the message looks like:

ESP8266 SMTP Server Send Email with Body HTML text format

If you’ve enabled the raw text message, this is the email that you should receive.

ESP8266 SMTP Server Send Email with Body raw text format

Send Attachments via Email with ESP8266 (Arduino IDE)

This section will show you how to send attachments in your emails sent by the ESP8266. We’ll show you how to send .txt files or pictures. This can be useful to send a .txt file with sensor readings from the past few hours or other applications.

You should save the files you want to send in the ESP8266 filesystem (SPIFFS or LittleFS). The default filesystem used by the library is LittleFS. You can also send attachments saved on a microSD card, but we’ll not cover this subject in this tutorial.

Upload files to LittleFS

To send files via email, you should save them in the ESP8266 filesystem. The library uses LittleFS by default. To upload files to the LittleFS using Arduino IDE, you need to install a Filesystem Uploader Plugin. Read the following tutorial to learn how to install and upload files to the ESP8266 filesystem:

If you’re using VS Code + PlatformIO, follow the next tutorial to learn how to upload files to LittleFS:

Create a new Arduino sketch and save it. Go to Sketch > Show Sketch folder. Inside the Arduino sketch folder, create a folder called data. Move a .png file and .txt file to your data folder.

Alternatively, you can click here to download the project folder.

Note: with the default code, your files must be named image.png and text_file.txt or you can modify the code to import files with a different name.

We’ll be sending these files:

Upload the files to filesystem to send as an email attachment

Your folder structure should look as follows (download project folder):

Send email attachments folder structure filesystem organizing files

After moving the files to the data folder, in your Arduino IDE, go to Tools > ESP8266 LittleFS Data Upload, and wait for the files to be uploaded.

ESP8266 Tools LittleFS Data Upload Arduino IDE

You should get a success message on the debugging window. If the files were successfully uploaded, move on to the next section.

LittleFS image uploaded

Code

The following code sends an email with a .txt file and a picture attached. Before uploading the code, make sure you insert your sender email settings as well as your recipient email.

/*
  Rui Santos
  Complete project details at:
   - ESP32: https://RandomNerdTutorials.com/esp32-send-email-smtp-server-arduino-ide/
   - ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-send-email-smtp-server-arduino/
   
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  Example adapted K. Suwatchai (Mobizt): 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 "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

#define SMTP_HOST "smtp.gmail.com"

/** 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 465

/* The sign in credentials */
#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_APP_PASS"

/* Recipient's email*/
#define RECIPIENT_EMAIL "[email protected]"

/* 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);
  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();

  // Init filesystem
  ESP_MAIL_DEFAULT_FLASH_FS.begin();

  /** 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 for user defined session credentials */
  Session_Config config;

  /* Set the session config */
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = "mydomain.net";
  
  /*
  Set the NTP config time
  For times east of the Prime Meridian use 0-12
  For times west of the Prime Meridian add 12 to the offset.
  Ex. American/Denver GMT would be -6. 6 + 12 = 18
  See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
  */
  config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
  config.time.gmt_offset = 3;
  config.time.day_light_offset = 0;

  /* Declare the message class */
  SMTP_Message message;

  /* Enable the chunked data transfer with pipelining for large message if server supported */
  message.enable.chunking = true;

  /* Set the message headers */
  message.sender.name = "ESP Mail";
  message.sender.email = AUTHOR_EMAIL;

  message.subject = F("Test sending Email with attachments and inline images from Flash");
  message.addRecipient(F("Sara"), RECIPIENT_EMAIL);

  /** Two alternative content versions are sending in this example e.g. plain text and html */
  String htmlMsg = "This message contains attachments: image and text file.";
  message.html.content = htmlMsg.c_str();
  message.html.charSet = "utf-8";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;

  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

  /* The attachment data item */
  SMTP_Attachment att;

  /** Set the attachment info e.g. 
   * file name, MIME type, file path, file storage type,
   * transfer encoding and content encoding
  */
  att.descr.filename = "image.png";
  att.descr.mime = "image/png"; //binary data
  att.file.path = "/image.png";
  att.file.storage_type = esp_mail_file_storage_type_flash;
  att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

  /* Add attachment to the message */
  message.addAttachment(att);

  message.resetAttachItem(att);
  att.descr.filename = "text_file.txt";
  att.descr.mime = "text/plain";
  att.file.path = "/text_file.txt";
  att.file.storage_type = esp_mail_file_storage_type_flash;
  att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

  /* Add attachment to the message */
  message.addAttachment(att);

  /* Connect to server with the session config */
  if (!smtp.connect(&config)){
    ESP_MAIL_PRINTF("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    return;
  }

  if (!smtp.isLoggedIn()){
    Serial.println("\nNot yet logged in.");
  }
  else{
    if (smtp.isAuthenticated())
      Serial.println("\nSuccessfully logged in.");
    else
      Serial.println("\nConnected with no Auth.");
  }

  /* Start sending the Email and close the session */
  if (!MailClient.sendMail(&smtp, &message, true))
    Serial.println("Error sending Email, " + smtp.errorReason());
}

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.c_str());
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
    }
    Serial.println("----------------\n");
    
    // You need to clear sending result as the memory usage will grow up.
    smtp.sendingResult.clear();
  }
}

View raw code

How the code works

This code is very similar to the previous one, so we’ll just take a look at the relevant parts to send attachments.

In the setup(), you initialize the filesystem using the ESP Mail Client library method. The default filesystem set in the library for the ESP32 is LittleFS (you can change the default in the library file ESP_Mail_FS.h).

// Init filesystem
ESP_MAIL_DEFAULT_FLASH_FS.begin();

You need to create an attachment as follows:

/* The attachment data item */
SMTP_Attachment att;

Then, add the attachment details: filename, MIME type, file path, file storage type, and transfer encoding. In the following lines, we’re sending the image file.

att.descr.filename = "image.png";
att.descr.mime = "image/png"; 
att.file.path = "/image.png";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

Finally, add the attachment to the message:

message.addAttachment(att);

If you want to send more attachments, you need to call the following line after adding the previous attachment:

message.resetAttachItem(att);

Then, enter the details of the other attachment (text file):

att.descr.filename = "text_file.txt";
att.descr.mime = "text/plain";
att.file.path = "/text_file.txt";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

And add this attachment to the message:

message.addAttachment(att);

If you want to send more attachments, you need to call the following line before adding the next attachment:

message.resetAttachItem(att);

Then, enter the details of the other attachment (text file):

att.descr.filename = "text_file.txt";
att.descr.mime = "text/plain";
att.file.path = "/text_file.txt";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

And add this attachment to the message:

message.addAttachment(att);

Finally, you just need to send the message as you did with the previous example:

if (!MailClient.sendMail(&smtp, &message, true))
  Serial.println("Error sending Email, " + smtp.errorReason());

Demonstration

After uploading the code, open the Serial Monitor at a baud rate of 115200. If everything goes as expected, you should get a similar message on the Serial Monitor.

ESP8266 NodeMCU Send Email Message Successfully Serial Monitor

If you go to your inbox, you should get the message with the two attachments:

Send Email with Attachments ESP8266 NodeMCU Gmail Account Arduino IDE

Wrapping Up

In this tutorial, you’ve learned how to send emails with the ESP8266 NodeMCU board using an SMTP Server. You’ve learned how to send HTM text, raw text, and attachments.

Now, the idea is to modify the code and include it in your own projects. For example, it can be useful to send a .txt file with the sensor readings of the last hour, notifications when motion is detected, and much more.

We hope you’ve found this tutorial interesting. We have a similar guide for the ESP32:

Learn more about the ESP8266 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

86 thoughts on “ESP8266 NodeMCU Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino)”

  1. Thank you so much for sharing this fantastic tutorial and for including step-by-step instructions on how to understand the concept and how the project works.

    Reply
  2. Hi Sara,
    It is beside the point, but what it is the correct address for forum.
    I want to find help for one of my problem or put a question
    Thank you
    Ion

    Reply
  3. I had a problem compiling the original version of this sketch with the following includes:
    #include <Arduino.h>
    #if defined(ESP32)
    #include <WiFi.h>
    #elif defined(ESP8266)
    #include <ESP8266WiFi.h>
    #include <FS.h>
    #include <SD.h>
    #endif
    #include <ESP_Mail_Client.h>

    I also got errors on all of my older sketches some of which have been in use since 2018. After a great deal of research I found the answer to the compiler error. (Unable to compile for this device.) All of the offending sketches had included the SD.h library. The solution is to simply rename a folder. Change this:
    C:\Users\\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266SdFat
    to this:
    C:\Users\\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\SdFat
    Remove the ESP8266 from the folder name for SdFat
    I was wary about renaming the folder so I made a copy and renamed that. Now all of my ESP8266 sketches compile without errors.

    Reply
  4. Sara,
    I have RCWL motion sensors that when triggered need to send a notification. The sensors use NRF24 on Arduino and send to and esp8266 (that collects from 5 NRF24) the signal and then thru wifi to Telegram. Works fine , but. I wanted to use email notifications. I could not figure out how to pass the sensors arguments, data[0] data[1] etc to the HTML email. The html email works with “text” just fine. Can you help?

    Reply
  5. Hi,
    I keep getting this error.
    C:\Users\Pertti\Documents\Arduino\libraries\ESP-Mail-Client-master\src/wcs/esp8266/ESP8266_WCS.h:34:29: fatal error: bearssl/bearssl.h: No such file or directory
    #include <bearssl/bearssl.h>
    What should I do?

    Reply
  6. I tried to use it but I can’t send mail .My error is: “set recipient failed”. I know that my mail address is active. Mail which I send uses raw txt. SMTP server is active and mailbox is ready to send mails. I’m using local webserver host (home.pl), port 587. What do I do wrong?

    Reply
      • Yea! I found it by myself. I disabled:
        message.priority and message.response.notify and now mails ESP can send to smtp server. I’ve noticed that, if ESP has no wifii connection, esp crashed. So I changed sketch to disable smtp sending when wifi is off.
        I changed String massage, to const PROGMEM char. It doesn’t use RAM. All smtp configuratios are stored in flash. Mail are sent only when esp started (info mail on my mailbox) and when temperature is lower than 0 degree Celcius(or higher than 30) to my family. So it happens one’s a day, maybe less. But it works.

        Reply
      • Yea! I found it by myself. I disabled:
        message.priority and message.response.notify and now mails ESP can send to smtp server. I’ve noticed that, if ESP has no wifii connection, esp crashed. So I changed sketch to disable smtp sending when wifi is off.
        I changed String massage, to const PROGMEM char. It doesn’t use RAM. All smtp configuratios are stored in flash. Mail are sent only when esp started (info mail on my mailbox) and when temperature is lower than 0 degree Celcius(or higher than 30) to my family. So it happens one’s a day, maybe less. But it works.

        Reply
  7. Hi Sara,

    I’m trying to use this sketch to monitor my house’s electrical system. If the mains power fails, I wish to be notified by email.
    The router and the Esp8266 are on UPS so that they continue to work in the event of a power failure.
    How do I call the routine for sending the email at the moment of a power failure ?
    I have tried this, but it doesn’t work:
    void loop(){
    int spanning = digitalRead (D1);
    if (spanning == LOW) {MailClient.sendMail(&smtp, &message);}
    Serial.println (spanning);
    }

    Reply
  8. Hi,
    This works great and I appreciate your instruction.
    I would like to insert a conditional statement controlling the actual sending of the mail.
    For instance, I would like the email sent when a sensor is activated.
    I tried inserting in several places, but was unable to get it to work.
    Can you help me out?
    Thanks in advance,
    Mike

    Reply
  9. I get this error every time. I’ve tried changing the recipient e-mail address, but it doesn’t matter. What’s going on?

    Sending message header…

    C: send message header
    < S: 250 2.1.0 Sender OK
    < S: 501 5.5.4 Invalid arguments
    Error, set recipient failed
    E: set recipient failed
    Error sending Email, set recipient failed

    Reply
  10. Boa noite, só uma duvida rápida. Já tentou fazer o envio do arquivo (TXT e foto) armazenado em um cartão SD, se tiver realizado essa programação, poderia dar uma dica de como puxar o arquivo do SD em vez de carregar o TXT guardado dentro do esp. Acredito que as atualizações feitas dentro da biblioteca não seriam validas para o uso no caso de SDcard.

    Reply
    • Boa tarde.
      Acho que é só trocar o modo de armazenamento de esp_mail_file_storage_type_flash para esp_mail_file_storage_type_sd.
      Sei que na altura experimentei, mas por qualquer motivo não consegui pôr a funcionar.
      Cumprimentos.
      Sara Santos

      Reply
  11. I have behavior I don’t understand. When I call:
    if (!MailClient.sendMail(&smtp, &message)) Serial.println(“Error sending Email, ” + smtp.errorReason());
    The first time I call it I get a single email sent, as expected.
    The second time I call it, it spawns two emails. The next time it sends 3 emails. and so on.
    Any idea why?

    Also what is “Sara” for in this line: message.addRecipient(“Sara”, RECIPIENT_EMAIL);
    I don’t see it anywhere in the received email.

    Thanks

    Reply
  12. Great tutorial. Regarding Gmails Less sure app, If I enable 2 step verification and replace my old regular Gmail password with the new APP PASSWORD as you described, then Gmail will continue to allow the esp8266 to send emails long after Gmail discontinues less secure apps…Right? Just want to make sure.

    Reply
  13. Yes, that is what I need. The program says, that it is sent, but I don’t receive any mails. I get a response
    13:17:15.020 -> Closing the session…
    13:17:15.020 -> > C: terminate the SMTP session
    13:17:15.020 ->
    13:17:15.020 -> Message sent successfully
    13:17:15.074 -> > C: Message sent successfully
    13:17:15.074 ->
    13:17:15.074 -> —————-
    13:17:15.074 -> Message sent success: 1
    13:17:15.074 -> Message sent failled: 0
    13:17:15.074 -> —————-
    13:17:15.074 ->
    13:17:15.074 -> Message No: 1
    13:17:15.074 -> Status: success
    13:17:15.074 -> Date/Time: 1970/1/1 0:0:6
    13:17:15.074 -> Recipient: ⸮R⸮?
    13:17:15.074 -> Subject: ⸮R⸮?
    13:17:15.074 -> —————-

    The recipient is somehow encrypted. And also the subject. But also in the sent-folder of gmail it can be seen as successful mail. Hmm!?!
    Do you have any idea what is going wrong?

    Reply
    • Hooray, I got the emails.
      It works fine, although I don’t know why the recipient and subject aren’t showing.

      Our IT department filtered out the mail – I received it one day later as “inbound quarantined emails”.

      Great software, thank you for the detailed explanation.

      Reply
  14. Hello Sara & Rui,

    I am trying to run your example sketch and it will not compile.
    It seems to be having a problem with the ESP_MAIL_PRINTF line stating:
    cannot pass objects of non-trivially-copyable type ‘class MB_String’ through ‘…’
    However, I’m not sure that error statement refers to the PRINTF.
    Here is the entire error message:
    Arduino: 1.8.19 (Windows Store 1.8.57.0) (Windows 10), Board: “NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new can abort), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v1.4 Higher Bandwidth, Disabled, None, Only Sketch, 115200”

    In file included from C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/wcs/esp8266/ESP8266_TCP_Client.h:47:0,
    from C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/wcs/ESP_TCP_Clients.h:33,
    from C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/ESP_Mail_Client.h:99,
    from C:\NodeMCU Projects\Examples\ESP8266_Email_Web_Server_Example\ESP8266_Email_Web_Server_Example.ino:20:
    C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/./wcs/base/TCP_Client_Base.h: In member function ‘int TCP_Client_Base::setTimestamp(time_t)’:
    C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/./wcs/base/TCP_Client_Base.h:160:24: error: variable ‘TCP_Client_Base::setTimestamp(time_t)::timeval tm’ has initializer but incomplete type
    struct timeval tm = {ts, 0}; // sec, us
    ^
    C:\Users\Glenn\Documents\Arduino\libraries\ESP_Mail_Client\src/./wcs/base/TCP_Client_Base.h:161:52: error: ‘settimeofday’ was not declared in this scope
    return settimeofday((const timeval *)&tm, 0);
    ^
    C:\NodeMCU Projects\Examples\ESP8266_Email_Web_Server_Example\ESP8266_Email_Web_Server_Example.ino: In function ‘void smtpCallback(SMTP_Status)’:

    ESP8266_Email_Web_Server_Example:139:59: error: cannot pass objects of non-trivially-copyable type ‘class MB_String’ through ‘…’

    ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);
    ^

    ESP8266_Email_Web_Server_Example:140:54: error: cannot pass objects of non-trivially-copyable type ‘class MB_String’ through ‘…’
    ESP_MAIL_PRINTF(“Subject: %s\n”, result.subject);
    ^
    Multiple libraries were found for “SD.h”
    Used: C:\Users\Glenn\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.6.3\libraries\SD
    Not used: C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\libraries\SD

    exit status 1
    cannot pass objects of non-trivially-copyable type ‘class MB_String’ through ‘…’

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    Can you provide any guidance as to what the problem might be?

    I have used your example code with no changes except the network credentials, sender email, SMTP Server details, recipient, and message.

    Thanks,
    Glenn

    Reply
  15. Great software. I enjoy all your tutorals. I got tripped up a little on the ESP8266 not compiling because I still had old SD and SDfat libraries in my libraries folder (it’s now in the core). This might be useful for other programmers trying to use this Email client.

    Reply
  16. Great job Sara
    If you don’t mind, I see the code need some adds
    1. you may need auto reconnect if WIFI disconnects.
    2. resend if not sent successfully.
    Thanks for your great effort.

    Reply
  17. SMTP server connected, wait for greeting…
    < S: 220 smtp.gmail.com ESMTP j15-20020a056a00234f00b0052542cbff9dsm10338142pfj.99 – gsmtp

    Sending greeting response…

    C: Send SMTP command, HELO
    < S: 250-smtp.gmail.com at your service, [172.89.###.###]
    < S: 250-SIZE 35882577
    < S: 250-8BITMIME
    < S: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
    < S: 250-ENHANCEDSTATUSCODES
    < S: 250-PIPELINING
    < S: 250-CHUNKING
    < S: 250 SMTPUTF8
    Logging in…
    C: Send SMTP command, AUTH PLAIN
    C: ####@gmail.com
    C: ####@gmail.com ****************
    < S: 535-5.7.8 Username and Password not accepted. Learn more at
    < S: 535 5.7.8 https://support.google.com/mail/?p=BadCredentials j15-20020a056a00234f00b0052542cbff9dsm10338124pfj.99 – gsmtp
    Error, authentication failed
    E: authentication failed

    Everything works until authentication, I have app password entered.
    What do I have wrong?

    Reply
  18. Gmail has removed “less secure apps”. I have used the 2 factor and app password but Gmail wont recognize me. Is there a fix?

    Reply
      • I am using app password. When I follow it in the serial window it gets as far as “user name and password not accepted”

        Reply
        • When I initially set this up I missed setting the Sender name to the APP name matching the APP key you are using for the password. It fixed my authentication.
          /* Set the message headers */
          message.sender.name = “ESP”;

          Reply
          • I am sorry, my understanding of the code is limited. What do I need to change or replace in the code?

          • I found the problem, I hope this helps someone else. When creating the app password in google mail if you delete the app password and create a second one you MUST log out and back in before you create the new password, otherwise gmail will not recognize the new password when used to log in.

          • To get another mail recipient; Add a second line with the second email. Change it to EMAIL_1 & EMAIL_2
            reference the 2 emails on the lines “message.addRecipient” use the same name reference of EMAIL_1 & EMAIL_2

            #define RECIPIENT_EMAIL_1 “[email protected]
            #define RECIPIENT_EMAIL_2 “[email protected]” ………….add this line

            message.addRecipient(“”, RECIPIENT_EMAIL_1);
            message.addRecipient(“”, RECIPIENT_EMAIL_2); ……….add this line

  19. Does anyone know how to add a time stamp on the email message? I want to add the time an event occurs and include it with the message sent.

    Reply
    • Any of my sensors/modules with the capability of emailing also run an ntp client, which I use to accurately include the time appended to the subject. I often email to an sms gateway which are notorious for delivering the message late. With the time in the message I know when the even occurred.

      Reply
  20. Hi Sarah, hi Rui,

    realy good tutorial but i have some trouble with authentication as follow. At first, we build up a new google-account with 2nd-factor-auth and app-password as shown in tutorial.

    Our code works fine an we got a connection to SMTP-Server (SMTP-Server connected) and got greeting response. On the other side if the programm try to login we’ve got the following error:

    Application secific password required.
    Error, authentication failed
    Invalid second factor

    For login we use Server-Hostname, Server Port-Nr, Sender-Email, Sender-Name, Sender-Password and Recipient-Name & Email.

    We think, that there is a missunderstood with the login data. Should we send the second-factor password (16-digit) or should we send the email-account-password in “sender-password”? This is different and we don’t understand the usage.

    Would eb nice to get some help and feedback from you.

    Reply
    • Hi.
      The sender password is the app password.
      App passwords are used when you need to login to your account using third-party software. For example, if something goes wrong, you can delete the app password in your account, and the third-party software won’t have access to your email.
      Regards,
      Sara

      Reply
      • Sara, I believe the sender name also has to be the app name matching the app password. This was you can create multiple app passwords and google can distinguish them

        Reply
        • Hi Marty.
          The field
          AUTHOR_EMAIL refers to the sender email
          And in the AUTHOR_PASSWORD field you use the app password.
          Regards,
          Sara

          Reply
          • Thank you, Sara.
            For clarification, I stand corrected. The sender_name is not needed to complete the authentication.

  21. Hi Sara and Rui,

    another very informative tutorial. However, we use the national language German and the message text can therefore not correctly transfer all German umlauts ä, ö ü.

    Is there a solution or adjustment in the source code for this? Possibly it is the encoding enc_7bit. What exactly needs to be adjusted here?

    Thank you for a suitable solution.

    Greetings,
    Manfred

    Reply
  22. Anyone been able to send sensor values in LOOP ? For example, send a new email when there is a change of state on a digital input, say, when a door is opened then later closed. Example code would be appreciated

    Reply
    • Yes I did, Here a snippet of code. I do not explain and delete all the context, you will find out what necessary:
      code in loop:
      if (send_testmail_flag == true){
      send_mail(devicename + ” Test from Sender “, “TEST MAIL \nIP-Address: “+ WiFi.localIP().toString()+ “\n\nsent from mySensor – SW-Version ” + SWVERSION);
      send_testmail_flag = false;

      }

      function send_mail:
      String smtp_server = “smtp.gmail.com”;
      String smtp_sender = “[email protected]”;
      String smtp_port = “587”;
      String smtp_user = “[email protected]”;
      String smtp_pwd = “asdfasdfsadfasdf”;

      String smtp_ssl_port = “465”;

      void send_mail(String mysubject, String mymessage){
      check_connection(); // reconnect if wireless connection lost
      last_email_time = millis();
      smtp.debug(1);

      smtp.callback(smtpCallback); /* Set the callback function to get the sending results /
      ESP_Mail_Session session; /
      Declare the session config data */

      /* Set the session config */
      #ifdef DBG_MAIL
      Serial.println("\n *** Using default Mailserver");
      #endif
      session.server.host_name = smtp_server;
      session.server.port = smtp_ssl_port.toInt();
      session.login.email = smtp_user;
      session.login.password = smtp_pwd;
      session.login.user_domain = "";

      /* Declare the message class */
      SMTP_Message message;

      /* Set the message headers */
      message.sender.name = “MySensor”;
      message.sender.email = smtp_user;
      message.subject = mysubject;
      message.addRecipient(“myTest”, mail_address);

      //Send raw text message
      String textMsg = mymessage;
      message.text.content = textMsg.c_str();
      message.text.charSet = “us-ascii”;
      message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

      message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
      message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

      /* Connect to server with the session config */
      if (!smtp.connect(&session))
      //Serial.println(“—- Mail connection not successful —-“);
      return;

      /* Start sending Email and close the session */
      if (!MailClient.sendMail(&smtp, &message))
      Serial.println(“Error sending Email, ” + smtp.errorReason());
      }

      Reply
  23. Hi Sarah, hi Rui,

    I replicated this in vscode using platformio but came up to the issue where it waits for the NTP server to synch up and fails due to not being able to connect.

    Reply
  24. Connecting to AP……………
    WiFi connected.
    IP address:
    10.223.98.254

    Connecting to SMTP server…

    C: ESP Mail Client v2.5.2
    C: Wait for NTP server time synching
    Error, NTP server time synching timed out
    E: NTP server time synching timed out
    C: Connect to SMTP server
    C: Host > smtp.gmail.com
    C: Port > 465
    Error, unable to connect to server
    E: unable to connect to server

    could it be that my could is just not connecting.
    thanks,
    Tenzin

    Reply
  25. If you want to use this code to send multiple email messages, maybe providing a regular update to a server or mobile phone, then you need to add the following line at the end of the callback routine to free up allocated memory after each message is sent.

    smtp.sendingResult.clear();

    Reply
  26. Hello Sara and Rui,

    I have seen a few examples of code where the last line of the – void smtpCallback(SMTP_Status status){ – routine includes smtp.sendingResult.clear(); with the explanation that the sending results needs to be cleared or else the memory usage will grow. Do you agree?

    Regards,

    Roger

    Reply
  27. What is the difference between ver. 2.7.2 and 2.7.9? I’m asking because newer than 2.7.2 version doesn’t work properly. A have message “unable to connect to server”(2.7.2 with the same sketch compiled, works fine). A changed ESP core to 3.1.1, 3.10, 3.0.2 and nothing. I’ve noticed that ver. 2.7.3 and newer uses more RAM. Why?

    Reply
  28. Hello, can anyone help me with the following error:
    (I did install the latest esp2866 library 3.1.0)

    In file included from c:\Users\askob\Documents\Arduino\libraries\ESP-Mail-Client-master\src/wcs/custom/Custom_TCP_Client.h:35:0,
    from c:\Users\askob\Documents\Arduino\libraries\ESP-Mail-Client-master\src/wcs/ESP_TCP_Clients.h:53,
    from c:\Users\askob\Documents\Arduino\libraries\ESP-Mail-Client-master\src/ESP_Mail_Client.h:92,
    from C:\Users\askob\AppData\Local\Temp.arduinoIDE-unsaved2023113-17360-2bq38.qm6lej\Send_HTML\Send_HTML.ino:29:
    c:\users\askob\documents\arduino\libraries\esp-mail-client-master\src\wcs\base\tcp_client_base.h:32:10: fatal error: sys/time.h: No such file or directory
    #include <sys/time.h>
    ^~~~~~~~~~~~
    compilation terminated.

    exit status 1

    Compilation error: exit status 1

    Reply
  29. Hi,
    keep getting an ” NTP sync timeout”, can someone give me a hint on where to start debugging?

    serial output:
    ……………………………..
    WiFi connected.
    IP address:
    10.0.0.32

    Connecting to SMTP server…

    C: ESP Mail Client v3.1.3
    C: wait for NTP server time synching

    Error, NTP server time synching timed out

    ! E: NTP server time synching timed out

    I can compile/run the NTP sample code shown in https://RandomNerdTutorials.com/esp32-date-time-ntp-client-server-arduino/ successfully. The ESP mail library code seems to be looking for time information from either pool.ntp.org, or time.nist.gov, both of which work in the ntp sample code. The only issue I have with that code is that lines like

    Serial.println(&timeinfo, “%A, %B %d %Y %H:%M:%S”)

    produce compile errors:
    C:\Users\steff\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266/Print.h:103:16: note: conversion of argument 2 would be ill-formed:
    ntp_sync:57:29: error: invalid conversion from ‘const char‘ to ‘int’ [-fpermissive]
    57 | Serial.println(&timeinfo, “%A, %B %d %Y %H:%M:%S”);
    | ^~~~~~~~~~~~~~~~~~~~~~~
    | |
    | const char

    In file included from C:\Users\steff\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266/Stream.h:27,
    from C:\Users\steff\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266/HardwareSerial.h:32,
    from C:\Users\steff\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266/Arduino.h:303,
    from sketch\ntp_sync.ino.cpp:1:

    Do I need to adjust (which?) preferences do avoid those?

    Thanks in advance for hints/help
    -Steffen

    Reply
    • upgrading to ESP-Mail-Client rev 3.1.9 (from 3.1.3) fixed the timeout hangup.
      I have not looked at what the updates were and if they are related, but now the code works as described.

      Reply
  30. Thanks for the excellent code and explanation. My project already has a simple Real Time Clock (RTC) module. Is there a way I can use its time components (hours minutes, seconds, month, day, year) to substitute for the step where the email being sent needs to “Wait for NTP server time synching”?

    Reply
  31. My project already syncs my ESP32 time, and its never off by even a full second. Will the ESP_Mail_Client library detect that my system time is already available and avoid delaying to wait for a new NTP timeSync? If not, is there a function I could call to tell it to use my system time and bypass the wait?

    Reply
  32. Dear Sara Santos
    we setup our NodeMCU ESP8266, when the NodeMCU booted it send email, how we can use it in void loop
    thank you

    Reply
  33. Hello Sara and Rui,

    As I wrote in earlier forum comment (DIY Cloud Weather Station with ESP32/ESP8266 (MySQL Database and PHP)) this tutorial page is awesome.
    Congratulation!

    I have a little problem with this page project: ESP8266 NodeMCU Send Emails…

    I’m using Lolin (Wemos) D1 R1 board (its a 8266 based board)
    This projec “DIY Cloud Weather Station with ESP32/ESP8266 (MySQL Database and PHP)” working fine on the board.
    But unfortunately the Email sending project is not works.

    This is the errormessage after the compiling:

    “In file included from C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SD\src/SD.h:25,
    from C:\Users\GT\Documents\Arduino\libraries\ESP_Mail_Client\src/ESP_Mail_FS.h:116,
    from C:\Users\GT\Documents\Arduino\libraries\ESP_Mail_Client\src/extras/RFC2047.h:12,
    from C:\Users\GT\Documents\Arduino\libraries\ESP_Mail_Client\src/ESP_Mail_Client.h:39,
    from C:\Users\GT\Documents\Arduino\ESP_Email_Sending_v01\ESP_Email_Sending_v01.ino:18:
    C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SDFS\src/SDFS.h: In member function ‘virtual int sdfs::SDFSFileImpl::availableForWrite()’:
    C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SDFS\src/SDFS.h:279:31: error: ‘using element_type = class File32’ {aka ‘class File32’} has no member named ‘availableSpaceForWrite’; did you mean ‘availableForWrite’?
    279 | return _opened ? _fd->availableSpaceForWrite() : 0;
    | ^~~~~~~~~~~~~~~~~~~~~~
    | availableForWrite
    Multiple libraries were found for “SPI.h”
    Used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SPI
    Multiple libraries were found for “SdFat.h”
    Used: C:\Users\GT\Documents\Arduino\libraries\SdFat
    Not used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\ESP8266SdFat
    Multiple libraries were found for “ESP8266WiFi.h”
    Used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\ESP8266WiFi
    Multiple libraries were found for “ESP_Mail_Client.h”
    Used: C:\Users\GT\Documents\Arduino\libraries\ESP_Mail_Client
    Multiple libraries were found for “LittleFS.h”
    Used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\LittleFS
    Multiple libraries were found for “SD.h”
    Used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SD
    Not used: C:\Program
    Multiple libraries were found for “SDFS.h”
    Used: C:\Users\GT\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\libraries\SDFS
    exit status 1
    Error compiling for board LOLIN(WeMos) D1 R1.

    Do you have any idea to solve tihs problem?

    Regards

    Tamas

    Reply
      • Thank you Sara your quick response 🙂
        I completly uninstalled the Arduino IDE and I switched to VS system.
        All thing is works fine.
        I can only repeat myself: this technical blog is awesome. ‘keep it up’
        (I’m a Technical IT Engineer with batchelor degree)

        Reply
  34. Hi Sara,

    Just one more thing.

    My ESP8266 code collects temperature and humidity values.
    The values are sending to a database.
    If the values are out of a tolerance zone, sending by e-mail.
    There is incremental hour step (2 hours / sending) in the e-mail date-time stamp

    Real time period
    18/08/2023 21:51 to 22:00

    E-mail Database

    # °C RH% Date Time Date Time
    1 27,6 64,5 18/08/2023 21:49 18/08/2023 21:51
    2 27,51 64,67 18/08/2023 23:49 18/08/2023 21:52
    3 27,4 64,93 19/08/2023 1:48 18/08/2023 21:53
    4 27,3 65,45 19/08/2023 3:48 18/08/2023 21:54
    5 27,24 65,46 19/08/2023 5:47 18/08/2023 21:55
    6 27,21 65,46 19/08/2023 7:47 18/08/2023 21:56
    7 27,17 65,67 19/08/2023 9:46 18/08/2023 21:57
    8 27,14 65,72 19/08/2023 11:46 18/08/2023 21:58
    9 27,14 65,78 19/08/2023 13:45 18/08/2023 21:59
    10 27,12 65,92 19/08/2023 15:45 18/08/2023 22:00

    etc.

    Here is the code detail:

    config.time.ntp_server = F(“pool.ntp.org,time.nist.gov”);
    config.time.gmt_offset = 2;
    config.time.day_light_offset = 0;

    How can I solve this issue?

    Regards Tamas

    Reply
  35. Hello Sara,
    this is a great tutorial, easy to follow.
    just wanted to know how to change the text message depending on different conditions.
    like for example:
    if (condition 1) {
    message 1;
    }
    else if (condition 2) {
    message 2;
    }

    I am sadly not that experienced in arduino programming, so i do not know what to do.
    please help me out.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.