• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Функция отправки email на ESP8266

Paul_B

Member
Вдруг, если кому надо компактная функция отправки сообщений через http по 25 порту. Такую услугу представляет sibnet.ru. Всякие яндексы и мэйл.ру давно сидят на TSL/SSL, отправка через WiFiclientSecurity вызывает переполнение памяти и в 99% перезагрузку модуля по 29 ошибке.
Естественно, сначала на sibnet.ru надо завести аккаунт, потом почтовый ящик (это не одно и то же!) и данные почтового ящика вставить в логин (smtpUser)/пароль(smtpPass) (логин - полный почтовый ящик с доменом)

Код:
/**************************************************************************/
#include <WiFiClient.h>
#include <base64.h>

// sibnet.ru дает возможность отправки почты без TSL/SSL
// для функции отправки почты внешние переменные:
uint16_t smtpPort = 25;
String smtpUser="mail@sibnet.ru", smtpHost="smtp.sibnet.ru", smtpPass="PASSWORD";
// раскоментируем NDEBUG, если нужна отладка
// #define NDEBUG

static String getLine(WiFiClient *mailclient) {
  String result;
  if (mailclient->connected())
    result = mailclient->readStringUntil('\n');
  #ifdef NDEBUG
    Serial.print(F("<<"));
    Serial.println(result);
  #endif
  return result;
}

void sendLine(WiFiClient *mailclient, const String& str) {
  #ifdef NDEBUG
    Serial.print(F(">>"));
    Serial.println(str);
  #endif
  if (mailclient->connected())
    mailclient->println(str);
}

String sendCommand(WiFiClient *mailclient, const String& str) {
  sendLine(mailclient, str);
  mailclient->flush();

  return getLine(mailclient);
}


bool sendMail(const char* mailTo, const char* mailSubject)
{
  String str;
  bool rez=false;

WiFiClient *mailclient = new WiFiClient;

  mailclient->setTimeout(5000);
#ifdef NDEBUG
    Serial.print(F("Connecting to "));
    Serial.println(smtpHost);
#endif

 
  if(mailclient->connect(smtpHost.c_str(), smtpPort))
    {
  #ifdef NDEBUG
  Serial.println("Connection OK");
  #endif
  if (!getLine(mailclient).startsWith("220 "))
    return false;
  if (!sendCommand(mailclient, F("HELO esp8266.local")).startsWith("250 "))
    return false;
  if (String(smtpPass).length()) {
    if (! sendCommand(mailclient, F("AUTH LOGIN")).startsWith("334 "))
      return false;
    if (! sendCommand(mailclient, base64::encode(smtpUser)).startsWith("334 "))
      return false;
    if (! sendCommand(mailclient, base64::encode(smtpPass)).startsWith("235 "))
      return false;
  }
  str = F("MAIL FROM: <");
  str += smtpUser;
  str += '>';
  if (! sendCommand(mailclient, str).startsWith("250 "))
    return false;
  str = F("RCPT TO: <");
  str += mailTo;
  str += '>';
  if (! sendCommand(mailclient, str).startsWith("250 "))
    return false;
  if (! sendCommand(mailclient, F("DATA")).startsWith("354 "))
    return false;
  str = F("Subject: =?utf-8?B?");
  str += base64::encode(mailSubject);
  str += F("=?=");
  sendLine(mailclient, str);
  sendLine(mailclient, F("MIME-Version: 1.0"));
  sendLine(mailclient, F("Content-type: text/plain; charset=utf-8"));
  str = F("From: <");
  str += smtpUser;
  str += '>';
  sendLine(mailclient, str);
  str = F("To: <");
  str += mailTo;
  str += '>';
  sendLine(mailclient, str);
  sendLine(mailclient, "");

#ifdef NDEBUG
  Serial.println("Send Message...");
#endif

// сообщение читается из файла для экономии оперативной памяти при
// длинном сообщении. Теоретически можно задействовать строковую переменную

  File f = SPIFFS.open("/mail/sendmes0.txt", "r");
  if (f)
    {
      String s;
      while (f.available())
      {
        s = f.readStringUntil('\n');
        sendLine(mailclient, s);
      }
     s=String();
     f.close();
    }
    // если нет файла с сообщением, то отправить такой текст.
    // У меня до вызова отправки проверяется наличие файла
    else sendLine(mailclient, "Not message file");


  if (! sendCommand(mailclient, F("\r\n.")).startsWith("250 "))
    return false;
  sendCommand(mailclient, F("QUIT"));

  mailclient->stop();
  rez=true;
  #ifdef NDEBUG
  Serial.println(F("Connect END..."));
  #endif
}
else {
    #ifdef NDEBUG
    Serial.print(F("Connection fail"));
    #endif
    }
  delete mailclient;
  mailclient=NULL;
  str=String();
  return rez;
}

#endif

//------------------------------------------------------------
 

Paul_B

Member
#endif в конце надо убрать, случайно сюда попал и не дает уже исправить.
 
Сверху Снизу