• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 в конце надо убрать, случайно сюда попал и не дает уже исправить.
 
Сверху Снизу