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