Sending mail with an ESP8266

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.
Though it is possible to have the ESP8266 directly access your mail server and send a message through that, that is usually not a good idea as many mailservers will refuse mail that is being sent from a different domain (your ip) than the mailserver’s.
it is therefore safer to use a service like smtp2go.com. As long as you stay below a certain limit of emails, one can get a free account.

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 of
client.println(F("Subject: Emails from ESp8266\r\n"));
On can also do:
client.print(F("Subject: "));
if (condition == met)
client.println(F(PREDEFINED_MESSAGE));

Advertisements

4 thoughts on “Sending mail with an ESP8266

  1. Nice! A few remarks:
    You can also use gmail as your outbound relay server. However, you better not do this if you don’t have two step authentication enabled (which you should!). You can (and must) then create a separate password for services like smtp. It actually works very good.

    The mailto field is not important for sending the mail but some filters do use it. For example, the relay from one.com allows you to only use the domain of you account. Things like bill.gates@microsoft.com might also trigger filters, as might using your own address, but the system knowing for sure it didn’t come from inside.

    For your loggers I would personally choose something like B5HuZhDn@mailinator.com.

  2. Thanks Jeroen, you are right and actually have done that in the past (with visual basic and also IIS I think), and refer to that in the beginning, but found that several receiving mailservers apparently didnt accept such incoming mails, as they didnt see the correct maildomainas originator.
    Though it is an extra step, SMTP2GO is easier to implement for the average user who just wants to send a mail without having to mess too much with smtp settings. I must admit for me it was a step as my slightly anal retentive character finds direct use of my google mailserver the more ‘correct’ way to go

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s