• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Отправка почты

AlexTVR

Member
Добрый день!
Домашняя сеть, роутер Микротик раздает интернет по wifi.
NodeMcu клиент (тестовый пример), после подачи питания подключается к wifi, запрашивает удаленный сайт (порт 80), получает ответ, результаты видны в мониторе COM-порта.

Загружаю пример отправки email (SMTP, порт 465), настраиваю свои логины и пароли - отправки не происходит.
Затык возникает при попытке получения ответа от SMTP-сервера - ответа нет, потому происходит выход по тайм-ауту (пробовал с разными серверами - ситуация аналогичная).

Вопрос, почему в первом случае получение данных с удаленного сервера происходит, а во втором - нет?
 

AlexTVR

Member
Спасибо за SSL, но использование другой библиотеки и WiFiClientSecure ничего не дает.
Ошибка та же, вот здесь:

if(!client.connect(SMTP_SERVER, SMTP_PORT)) {
_error = "Could not connect to mail server";
return false;
}

Может микротик что-то не пропускает?
 

Сергей_Ф

Moderator
Команда форума
@AlexTVR скорее вы просто не подключились. Библиотеки для 100% отправки почты по SSL для esp8266 нет, насколько я знаю. Все от почтового сервера зависит.
 

AlexTVR

Member
Кто-нибудь использует ESP8266 для отправки писем из локальной сети? Поделитесь кодом, не могу никак отправить письма.
 

AlexTVR

Member
На чем поднимать почтовый сервер? У меня в режиме ОХРАНА будет работать только ESP8266. Домашний ПК будет выключен.
 

Сергей_Ф

Moderator
Команда форума
@AlexTVR в некоторые роутеры можно поставить. Малинка, апельсинка - решать вам. Современные защищенные протоколы esp8266 не по зубам. Либо арендуйте сервер у провайдера и поставьте туда свой без SSL.
 

AlexTVR

Member
- вот люди шлют письма.
Я бы и не парился, если бы знал, что слать письма из ESP8266 невозможно.
 

AlexTVR

Member
Код:
#include <ESP8266WiFi.h>
#include "Mail.h"

const char* const staSSID = "****";
const char* const staPass = "****";

const char* const smtpHost[] = {"smtp.inbox.ru"};
const uint16_t smtpPort = 465;
const char* const smtpUser[] = { "-----@inbox.ru"};
const char* const smtpPass[] = { "--------"};
const char* const mailTo = "-------@inbox.ru";
const char* const mailSubject = "Проверочное сообщение";

void setup() {
  Serial.begin(115200);
  Serial.println();

  Serial.print(F("Connecting to \""));
  Serial.print(staSSID);
  Serial.print('"');

  WiFi.begin(staSSID, staPass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  Serial.print(' ');
  Serial.println(WiFi.localIP());

  delay(10000);

  for (int8_t i = 0; i < 3; ++i) {
    Serial.println();
    if (sendMail(smtpHost[i], smtpPort, smtpUser[i], smtpPass[i], mailTo, mailSubject, F("Это многострочное сообщение для проверки\r\nВторая строка\r\nТретья строка"))) {
      Serial.print(F("Mail sended through "));
      Serial.println(smtpHost[i]);
    } else {
      Serial.print(F("Error sending mail through "));
      Serial.print(smtpHost[i]);
      Serial.println('!');
    }
  }

  WiFi.disconnect();
}

void loop() {

}
 

AlexTVR

Member
Выше мой код, а это библиотека к нему.

Код:
#include <WiFiClientSecure.h>
//#include <WiFiClientSecureAxTLS.h>
//using namespace axTLS;
#include <base64.h>
#include "Mail.h"

#define NDEBUG

static inline bool checkResponse(const String& response, int16_t code) {
  return response.startsWith(String(code) + ' ');
}

static bool checkResponse(const String& response, int16_t code, const String& errorMsg) {
  bool result = checkResponse(response, code);

  if (! result) {
    Serial.print(errorMsg);
    Serial.print(F(": \""));
    if (response.endsWith(F("\r\n")))
      Serial.print(response.substring(0, response.length() - 2));
    else
      Serial.print(response);
    Serial.println(F("\"!"));
  }

  return result;
}

static String getLine(WiFiClient& client) {
  String result;

  if (client.connected())
    result = client.readStringUntil('\n');
#ifndef NDEBUG
  Serial.print(F("<<"));
  Serial.println(result);
#endif

  return result;
}

static void sendLine(WiFiClient& client, const String& str) {
#ifndef NDEBUG
  Serial.print(F(">>"));
  Serial.println(str);
#endif
  if (client.connected())
    client.println(str);
}

static String sendCommand(WiFiClient& client, const String& str) {
  sendLine(client, str);
  client.flush();

  return getLine(client);
}

bool sendMail(const String& smtpHost, uint16_t smtpPort, const String& smtpUser, const String& smtpPassword, const String& mailTo, const String& mailSubject, const String& mailMessage) {
  WiFiClientSecure client;
  String str;

  Serial.print(F("Connecting to "));
  Serial.println(smtpHost);

//  client.setInsecure();
 
  if (! client.connect(smtpHost.c_str(), smtpPort)) {
    Serial.println(F("Connection failed!"));
    return false;
  }
  client.setTimeout(15000); // 15 sec. read timeout
  str = getLine(client);
  if (! checkResponse(str, 220, F("SMTP connection error")))
    return false;
  str = sendCommand(client, F("HELO esp8266.local"));
  if (! checkResponse(str, 250, F("SMTP HELO error")))
    return false;
  if (smtpPassword.length()) {
    str = sendCommand(client, F("AUTH LOGIN"));
    if (! checkResponse(str, 334, F("SMTP AUTH error")))
      return false;
    str = sendCommand(client, base64::encode(smtpUser));
    if (! checkResponse(str, 334, F("SMTP AUTH USER error")))
      return false;
    str = sendCommand(client, base64::encode(smtpPassword));
    if (! checkResponse(str, 235, F("SMTP AUTH PASS error")))
      return false;
  }
  str = F("MAIL FROM: <");
  str += smtpUser;
  str += '>';
  str = sendCommand(client, str);
  if (! checkResponse(str, 250, F("SMTP MAIL FROM error")))
    return false;
  str = F("RCPT TO: <");
  str += mailTo;
  str += '>';
  str = sendCommand(client, str);
  if (! checkResponse(str, 250, F("SMTP RCPT TO error")))
    return false;
  str = sendCommand(client, F("DATA"));
  if (! checkResponse(str, 354, F("SMTP DATA error")))
    return false;
  str = F("Subject: =?utf-8?B?");
  str += base64::encode(mailSubject);
  str += F("=?=");
  sendLine(client, str);
  sendLine(client, F("MIME-Version: 1.0"));
  sendLine(client, F("Content-type: text/plain; charset=utf-8"));
  str = F("From: <");
  str += smtpUser;
  str += '>';
  sendLine(client, str);
  str = F("To: <");
  str += mailTo;
  str += '>';
  sendLine(client, str);
  sendLine(client, "");
  sendLine(client, mailMessage);
  str = sendCommand(client, F("\r\n."));
  if (! checkResponse(str, 250, F("SMTP send error")))
    return false;
  sendCommand(client, F("QUIT"));
  client.stop();

  return true;
}
 

AlexTVR

Member
Ошибка возникает на строке 67 библиотеки:

if (! client.connect(smtpHost.c_str(), smtpPort)) {
Serial.println(F("Connection failed!"));
return false;

Никакой код не возвращается.
 

AlexTVR

Member
Проблема решена.

Код с сайта
работает отлично.
Если появятся проблемы как у меня на NODEMCU, используйте рекомендацию автора :
1. Замените начальную строку в файле mail.cpp на следующие строки:

//#include <WiFiClientSecure.h>
#include <WiFiClientSecureAxTLS.h>
using namespace axTLS;

2. В файле mail.cpp перед строкой с client.connect(...) - где обычно возникает ошибка, добавьте строку client.setInsecure();"

! Не копируйте эти коды с сайта (другая кодировка и будут ошибки), а пропишите их вручную в ардуино.
 

Алексей.

Active member
Выше мой код, а это библиотека к нему.
Код не безопасный, не проверяете подлинность хоста "smtp.inbox.ru", к которому подключается клиент.
Поделкам на esp от этих ssl/tls-оф ни горячо ни холодно, плевать они хотели на безопасность.
 

pvvx

Активный участник сообщества
Adafruit и прочие уже давно начали отказываться от ESP8266. Основные причины:
1) Нет наличия USB у чипа.
2) Нет поддержки современного уровня SSL.

Welcome to CircuitPython!
Авто-перевод:
Почему мы отказываемся от поддержки ESP8266?
CircuitPython на ESP8266 не очень удобен для пользователей. Трудно отправить файлы на устройство, потому что у него нет собственного USB, и вы можете быстро исчерпать ОЗУ (это меньше, чем вы думаете, после добавления сетевого стека). Мы решили использовать ESP только в качестве сопроцессора. В частности, ESP32, потому что он имеет хорошую поддержку TLS / SSL, которая сейчас необходима даже для самых простых взаимодействий.

Если вы хотите добавить поддержку WiFi, ознакомьтесь с нашим руководством по ESP32 / ESP8266 в качестве сопроцессора.
 
Сверху Снизу