Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

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

Тема в разделе "Общие вопросы по esp8266", создана пользователем AlexTVR, 14 фев 2019.

  1. AlexTVR

    AlexTVR Новичок

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

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

    Вопрос, почему в первом случае получение данных с удаленного сервера происходит, а во втором - нет?
     
  2. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    1.862
    Симпатии:
    208
  3. AlexTVR

    AlexTVR Новичок

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

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

    Может микротик что-то не пропускает?
     
  4. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    1.862
    Симпатии:
    208
    @AlexTVR скорее вы просто не подключились. Библиотеки для 100% отправки почты по SSL для esp8266 нет, насколько я знаю. Все от почтового сервера зависит.
     
  5. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
  6. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    Кто-нибудь использует ESP8266 для отправки писем из локальной сети? Поделитесь кодом, не могу никак отправить письма.
     
  7. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    1.862
    Симпатии:
    208
    @AlexTVR поднимите локальный почтовый сервер и шлите через него. 100% рабочий вариант
     
  8. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    На чем поднимать почтовый сервер? У меня в режиме ОХРАНА будет работать только ESP8266. Домашний ПК будет выключен.
     
  9. Сергей_Ф

    Сергей_Ф Moderator Команда форума

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

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    - вот люди шлют письма.
    Я бы и не парился, если бы знал, что слать письма из ESP8266 невозможно.
     
  11. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    1.862
    Симпатии:
    208
    отлично. Что мешает вам? Выясните и шлите.
    Экстрасенсов тут нет. Вы ни свой код не привели, ни ответы от сервера.
     
  12. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    Код (Text):
    1. #include <ESP8266WiFi.h>
    2. #include "Mail.h"
    3.  
    4. const char* const staSSID = "****";
    5. const char* const staPass = "****";
    6.  
    7. const char* const smtpHost[] = {"smtp.inbox.ru"};
    8. const uint16_t smtpPort = 465;
    9. const char* const smtpUser[] = { "-----@inbox.ru"};
    10. const char* const smtpPass[] = { "--------"};
    11. const char* const mailTo = "-------@inbox.ru";
    12. const char* const mailSubject = "Проверочное сообщение";
    13.  
    14. void setup() {
    15.   Serial.begin(115200);
    16.   Serial.println();
    17.  
    18.   Serial.print(F("Connecting to \""));
    19.   Serial.print(staSSID);
    20.   Serial.print('"');
    21.  
    22.   WiFi.begin(staSSID, staPass);
    23.   while (WiFi.status() != WL_CONNECTED) {
    24.     delay(500);
    25.     Serial.print('.');
    26.   }
    27.   Serial.print(' ');
    28.   Serial.println(WiFi.localIP());
    29.  
    30.   delay(10000);
    31.  
    32.   for (int8_t i = 0; i < 3; ++i) {
    33.     Serial.println();
    34.     if (sendMail(smtpHost[i], smtpPort, smtpUser[i], smtpPass[i], mailTo, mailSubject, F("Это многострочное сообщение для проверки\r\nВторая строка\r\nТретья строка"))) {
    35.       Serial.print(F("Mail sended through "));
    36.       Serial.println(smtpHost[i]);
    37.     } else {
    38.       Serial.print(F("Error sending mail through "));
    39.       Serial.print(smtpHost[i]);
    40.       Serial.println('!');
    41.     }
    42.   }
    43.  
    44.   WiFi.disconnect();
    45. }
    46.  
    47. void loop() {
    48.  
    49. }
     
  13. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    Выше мой код, а это библиотека к нему.

    Код (Text):
    1. #include <WiFiClientSecure.h>
    2. //#include <WiFiClientSecureAxTLS.h>
    3. //using namespace axTLS;
    4. #include <base64.h>
    5. #include "Mail.h"
    6.  
    7. #define NDEBUG
    8.  
    9. static inline bool checkResponse(const String& response, int16_t code) {
    10.   return response.startsWith(String(code) + ' ');
    11. }
    12.  
    13. static bool checkResponse(const String& response, int16_t code, const String& errorMsg) {
    14.   bool result = checkResponse(response, code);
    15.  
    16.   if (! result) {
    17.     Serial.print(errorMsg);
    18.     Serial.print(F(": \""));
    19.     if (response.endsWith(F("\r\n")))
    20.       Serial.print(response.substring(0, response.length() - 2));
    21.     else
    22.       Serial.print(response);
    23.     Serial.println(F("\"!"));
    24.   }
    25.  
    26.   return result;
    27. }
    28.  
    29. static String getLine(WiFiClient& client) {
    30.   String result;
    31.  
    32.   if (client.connected())
    33.     result = client.readStringUntil('\n');
    34. #ifndef NDEBUG
    35.   Serial.print(F("<<"));
    36.   Serial.println(result);
    37. #endif
    38.  
    39.   return result;
    40. }
    41.  
    42. static void sendLine(WiFiClient& client, const String& str) {
    43. #ifndef NDEBUG
    44.   Serial.print(F(">>"));
    45.   Serial.println(str);
    46. #endif
    47.   if (client.connected())
    48.     client.println(str);
    49. }
    50.  
    51. static String sendCommand(WiFiClient& client, const String& str) {
    52.   sendLine(client, str);
    53.   client.flush();
    54.  
    55.   return getLine(client);
    56. }
    57.  
    58. bool sendMail(const String& smtpHost, uint16_t smtpPort, const String& smtpUser, const String& smtpPassword, const String& mailTo, const String& mailSubject, const String& mailMessage) {
    59.   WiFiClientSecure client;
    60.   String str;
    61.  
    62.   Serial.print(F("Connecting to "));
    63.   Serial.println(smtpHost);
    64.  
    65. //  client.setInsecure();
    66.  
    67.   if (! client.connect(smtpHost.c_str(), smtpPort)) {
    68.     Serial.println(F("Connection failed!"));
    69.     return false;
    70.   }
    71.   client.setTimeout(15000); // 15 sec. read timeout
    72.   str = getLine(client);
    73.   if (! checkResponse(str, 220, F("SMTP connection error")))
    74.     return false;
    75.   str = sendCommand(client, F("HELO esp8266.local"));
    76.   if (! checkResponse(str, 250, F("SMTP HELO error")))
    77.     return false;
    78.   if (smtpPassword.length()) {
    79.     str = sendCommand(client, F("AUTH LOGIN"));
    80.     if (! checkResponse(str, 334, F("SMTP AUTH error")))
    81.       return false;
    82.     str = sendCommand(client, base64::encode(smtpUser));
    83.     if (! checkResponse(str, 334, F("SMTP AUTH USER error")))
    84.       return false;
    85.     str = sendCommand(client, base64::encode(smtpPassword));
    86.     if (! checkResponse(str, 235, F("SMTP AUTH PASS error")))
    87.       return false;
    88.   }
    89.   str = F("MAIL FROM: <");
    90.   str += smtpUser;
    91.   str += '>';
    92.   str = sendCommand(client, str);
    93.   if (! checkResponse(str, 250, F("SMTP MAIL FROM error")))
    94.     return false;
    95.   str = F("RCPT TO: <");
    96.   str += mailTo;
    97.   str += '>';
    98.   str = sendCommand(client, str);
    99.   if (! checkResponse(str, 250, F("SMTP RCPT TO error")))
    100.     return false;
    101.   str = sendCommand(client, F("DATA"));
    102.   if (! checkResponse(str, 354, F("SMTP DATA error")))
    103.     return false;
    104.   str = F("Subject: =?utf-8?B?");
    105.   str += base64::encode(mailSubject);
    106.   str += F("=?=");
    107.   sendLine(client, str);
    108.   sendLine(client, F("MIME-Version: 1.0"));
    109.   sendLine(client, F("Content-type: text/plain; charset=utf-8"));
    110.   str = F("From: <");
    111.   str += smtpUser;
    112.   str += '>';
    113.   sendLine(client, str);
    114.   str = F("To: <");
    115.   str += mailTo;
    116.   str += '>';
    117.   sendLine(client, str);
    118.   sendLine(client, "");
    119.   sendLine(client, mailMessage);
    120.   str = sendCommand(client, F("\r\n."));
    121.   if (! checkResponse(str, 250, F("SMTP send error")))
    122.     return false;
    123.   sendCommand(client, F("QUIT"));
    124.   client.stop();
    125.  
    126.   return true;
    127. }
     
  14. AlexTVR

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    Ошибка возникает на строке 67 библиотеки:

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

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

    AlexTVR Новичок

    Сообщения:
    20
    Симпатии:
    0
    Проблема решена.

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

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

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

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

    Алексей. Авторитетный участник сообщества

    Сообщения:
    426
    Симпатии:
    48
    Код не безопасный, не проверяете подлинность хоста "smtp.inbox.ru", к которому подключается клиент.
    Поделкам на esp от этих ssl/tls-оф ни горячо ни холодно, плевать они хотели на безопасность.
     
  17. Сергей_Ф

    Сергей_Ф Moderator Команда форума

    Сообщения:
    1.862
    Симпатии:
    208
    Я знаю
     

Поделиться этой страницей