Closed BenSeventy9 closed 2 years ago
It's very strange, but I think you have some network delay, try to put the router and device close. Bye Renzo
Maybe the delay is on the line
if (this->useEHLO == true) { for (int i = 0; i<=11; i++) awaitSMTPResponse(client); }
If the server sends fewer outputs, it still waits for 6. I will change the code on my end to stop the loop when there is a call with a delay occuring, and see if it helps on my end.
Hi @salasidis, If there is a timeout the email is not sent with a timeout error. Bye Renzo
When I use a Gmail address it sends within 2s. It isn't caused by network delay. I send it only once when battery is low so I can live with those 40 seconds.
Hi Ben, can you enable the DEBUG and send me the result.
#define EMAIL_SENDER_DEBUG
https://github.com/xreef/EMailSender/blob/master/EMailSenderKey.h#L43
Bye Renzo
`............................... Connection: ESTABLISHED Got IP address: 192.168.1.80 ONLY ONE RECIPIENTmiltiple destination and attachments Insecure client:0 MFLN supported: yes mail.gmx.net 465 220 gmx.net (mrgmx005) Nemesis ESMTP Service ready
EHLO WemosSensor: 250-gmx.net Hello WemosSensor: [84.226.107.152]
250-8BITMIME
250-AUTH LOGIN PLAIN
250 SIZE 69920427
AUTH LOGIN: 334 VXNlcm5hbWU6
Encoding hidden@gmx.net 18 hidden Encoding hidden@gmx.net 18 334 UGFzc3dvcmQ6
Encoding hidden 24 hidden Encoding hidden 24 235 Authentication succeeded
MAIL FROM: *hidden*@gmx.net 250 Requested mail action okay, completed
RCPT TO: *hidden*@gmx.ch 250 OK
DATA:
354 Start mail input; end with
Message end 250 Requested mail action okay, completed: id=1MLzBj-1oP2pU2fyb-00Hv5c
221 gmx.net Service closing transmission channel
Sending status: 1 0 Message sent! Time for sending: 43.00 seconds `
There is a point that needs more time?
After "250 SIZE 69920427" starts the delay until "AUTH LOGIN:". Hope that helps
I played a bit around and changed the loop to 2:
if (this->useEHLO == true) { for (int i = 0; i<=2; i++) awaitSMTPResponse(client); }
Output:
250 Requested mail action okay, completed: id=1MWzfv-1o9ceG3VCj-00XI1S
221 gmx.net Service closing transmission channel
Sending status: 1 0 Message sent! Time for sending: 2.40 seconds
Looks like salasidis was right!
I added a test code on my end,
I time the rime between successive 250-×××
If the time of any one is greater than a few seconds, I presume there are no more left, and I proceed to an auth login
This way the delay happens just once, and is independent of the number of 250×× replies from the server.
Otherwise there wad a risk of interviewing the 250××× responses with the auth login going out, or too long delay, if exoect more 250s than there actually are.
-------- Original message -------- From: BenSeventy9 @.> Date: 2022-07-01 08:39 (GMT-05:00) To: xreef/EMailSender @.> Cc: rsalasidis @.>, Mention @.> Subject: Re: [xreef/EMailSender] Needs more than 40 seconds to send. Any ideas why? (Issue #26)
After "250 SIZE 69920427" starts the delay until "AUTH LOGIN:". Hope that helps
— Reply to this email directly, view it on GitHubhttps://github.com/xreef/EMailSender/issues/26#issuecomment-1172303032, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK5VYZODOIQ3U7PURPV3OFDVR3RHHANCNFSM5ZMZRLZQ. You are receiving this because you were mentioned.Message ID: @.***>
I added a test code on my end, I time the rime between successive 250-××× If the time of any one is greater than a few seconds, I presume there are no more left, and I proceed to an auth login This way the delay happens just once, and is independent of the number of 250×× replies from the server. Otherwise there wad a risk of interviewing the 250××× responses with the auth login going out, or too long delay, if exoect more 250s than there actually are.
Do you have some code snipped for me?
In emailSender.cpp I did the following. I also attached the whole file.
Let me know if helpful. Thanks
response = awaitSMTPResponse(client, "220", "Connection Error"); if (!response.status) { client.flush(); client.stop(); return response; }
String commandHELO = "HELO"; if (this->useEHLO == true) { commandHELO = "EHLO"; } String helo = commandHELO + " "+/String(publicIPDescriptor)/ smtp_server /+": "/; DEBUG_PRINTLN(helo); client.println(helo);
response = awaitSMTPResponse(client, "250", "Identification error"); DEBUG_PRINTLN(response.status); if (!response.status) { client.flush(); client.stop(); return response; }
loopTime1 = millis(); DEBUG_PRINTLN(loopTime1); if (this->useEHLO == true) { for (int i = 0; i<=20; i++) { awaitSMTPResponse(client); loopTime2 = millis(); DEBUG_PRINTLN(loopTime2); if ((loopTime2 - loopTime1) > 2500) { break; } else { loopTime1 = loopTime2; } } } DEBUG_PRINTLN("End of awaitSMTPResponse");
From: BenSeventy9 @.> Sent: July 1, 2022 16:04 To: xreef/EMailSender @.> Cc: rsalasidis @.>; Mention @.> Subject: Re: [xreef/EMailSender] Needs more than 40 seconds to send. Any ideas why? (Issue #26)
I added a test code on my end, I time the rime between successive 250-××× If the time of any one is greater than a few seconds, I presume there are no more left, and I proceed to an auth login This way the delay happens just once, and is independent of the number of 250×× replies from the server. Otherwise there wad a risk of interviewing the 250××× responses with the auth login going out, or too long delay, if exoect more 250s than there actually are.
Do you have some code snipped for me?
— Reply to this email directly, view it on GitHubhttps://github.com/xreef/EMailSender/issues/26#issuecomment-1172676055, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK5VYZMGWYZLF4SOYO4YXF3VR5FMFANCNFSM5ZMZRLZQ. You are receiving this because you were mentioned.Message ID: @.**@.>>
/*
//#include
//#define SD SPIFFS
// BASE64 ----------------------------------------------------------- const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
inline void a3_to_a4(unsigned char a4, unsigned char a3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = (a3[2] & 0x3f); }
int base64_encode(char output, char input, int inputLen) { int i = 0, j = 0; int encLen = 0; unsigned char a3[3]; unsigned char a4[4];
while (inputLen--) { a3[i++] = *(input++); if (i == 3) { a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
}
i = 0;
}
}
if (i) { for (j = i; j < 3; j++) { a3[j] = '\0'; }
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
}
while ((i++ < 3)) {
output[encLen++] = '=';
}
} output[encLen] = '\0'; return encLen; }
int base64_enc_length(int plainLen) { int n = plainLen; return (n + 2 - ((n + 2) % 3)) / 3 * 4; }
const char encode64_f(char input, uint8_t len) { // encoding
DEBUG_PRINTLN(F("Encoding"));
DEBUG_PRINTLN(input);
DEBUG_PRINTLN(len);
//int encodedLen = base64_enc_length(len); static char encoded[256]; // note input is consumed in this step: it will be empty afterwards base64_encode(encoded, input, len); return encoded; }
// END BASE64 ---------------------------------------------------------
EMailSender::EMailSender(const char email_login, const char email_password, const char email_from, const char name_from , const char smtp_server, uint16_t smtp_port) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setSMTPServer(smtp_server); this->setSMTPPort(smtp_port); this->setNameFrom(name_from); // this->isSecure = isSecure; } EMailSender::EMailSender(const char email_login, const char email_password, const char email_from, const char* smtp_server, uint16_t smtp_port) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setSMTPServer(smtp_server); this->setSMTPPort(smtp_port);
// this->isSecure = isSecure; }
EMailSender::EMailSender(const char email_login, const char email_password, const char email_from, const char name_from ) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setNameFrom(name_from); this->setNameFrom(name_from);
// this->isSecure = isSecure; } EMailSender::EMailSender(const char email_login, const char email_password, const char* email_from) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password);
// this->isSecure = isSecure; }
EMailSender::EMailSender(const char email_login, const char email_password){ this->setEMailLogin(email_login); this->setEMailFrom(email_login); this->setEMailPassword(email_password);
// this->isSecure = isSecure; }
void EMailSender::setSMTPPort(uint16_t smtp_port){ this->smtp_port = smtp_port; }; void EMailSender::setSMTPServer(const char* smtp_server){ delete [] this->smtp_server; this->smtp_server = new char[strlen(smtp_server)+1]; strcpy(this->smtp_server, smtp_server); };
void EMailSender::setEMailLogin(const char email_login){ delete [] this->email_login; this->email_login = new char[strlen(email_login)+1]; strcpy(this->email_login, email_login); }; void EMailSender::setEMailFrom(const char email_from){ delete [] this->email_from; this->email_from = new char[strlen(email_from)+1]; strcpy(this->email_from, email_from); }; void EMailSender::setNameFrom(const char name_from){ delete [] this->name_from; this->name_from = new char[strlen(name_from)+1]; strcpy(this->name_from, name_from); }; void EMailSender::setEMailPassword(const char email_password){ delete [] this->email_password; this->email_password = new char[strlen(email_password)+1]; strcpy(this->email_password, email_password); };
void EMailSender::setIsSecure(bool isSecure) { this->isSecure = isSecure; }
EMailSender::Response EMailSender::awaitSMTPResponse(SSLClient &client, const char resp, const char respDesc, uint16_t timeOut) { EMailSender::Response response; uint32_t ts = millis(); while (!client.available()) { if (millis() > (ts + timeOut)) { response.code = F("1"); response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!"); response.status = false;
return response;
}
}
_serverResponce = client.readStringUntil('\n');
DEBUG_PRINTLN(_serverResponce);
if (resp && _serverResponce.indexOf(resp) == -1){
response.code = resp;
response.desc = respDesc +String(" (") + _serverResponce + String(")");
response.status = false;
return response;
}
response.status = true;
return response;
}
EMailSender::Response EMailSender::awaitSMTPResponse(EMAIL_NETWORK_CLASS &client, const char resp, const char respDesc, uint16_t timeOut) { EMailSender::Response response; uint32_t ts = millis(); while (!client.available()) { if (millis() > (ts + timeOut)) { response.code = F("1"); response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!"); response.status = false; return response; } } _serverResponce = client.readStringUntil('\n');
DEBUG_PRINTLN("Server Response = ");
DEBUG_PRINTLN(_serverResponce);
if (resp && _serverResponce.indexOf(resp) == -1){
response.code = resp;
response.desc = respDesc +String(" (") + _serverResponce + String(")");
response.status = false;
return response;
}
response.status = true;
return response;
}
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encodeblock(unsigned char in[3],unsigned char out[4],int len) { out[0]=cb64[in[0]>>2]; out[1]=cb64[((in[0]&0x03)<<4)|((in[1]&0xF0)>>4)]; out[2]=(unsigned char) (len>1 ? cb64[((in[1]&0x0F)<<2)|((in[2]&0xC0)>>6)] : '='); out[3]=(unsigned char) (len>2 ? cb64[in[2]&0x3F] : '='); }
#ifdef STORAGE_EXTERNAL_ENABLED
#if (defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE_EX)) || !defined(STORAGE_INTERNAL_ENABLED)
#ifdef SSLCLIENT_WRAPPER
void encode(EMAIL_FILE_EX *file, SSLClient *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#else
void encode(EMAIL_FILE_EX *file, EMAIL_NETWORK_CLASS *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#endif
#endif
#endif
#ifdef STORAGE_INTERNAL_ENABLED
#if defined(DIFFERENT_FILE_MANAGE) || (!defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE)) || !defined(STORAGE_EXTERNAL_ENABLED)
#ifdef SSLCLIENT_WRAPPER
void encode(EMAIL_FILE *file, SSLClient *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#else
void encode(EMAIL_FILE *file, EMAIL_NETWORK_CLASS *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#endif
#endif
#endif
const char toCharArray(String arr[], int num) { // If we ever alloc with new with have to delete const char buffer = new const char*[num];
for(int i = 0; i < num; i++) {
buffer[i] = arr[i].c_str();
}
return buffer;
} const char* toCharArray(char arr[], int num) { // If we ever alloc with new with have to delete const char* buffer = new const char[num];
for(int i = 0; i < num; i++) {
buffer[i] = arr[i];
}
return buffer;
}
EMailSender::Response EMailSender::send(char tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments); } EMailSender::Response EMailSender::send(char tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments); } EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){ return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments); }
EMailSender::Response EMailSender::send(String to, EMailMessage &email, Attachments attachments){ DEBUG_PRINT(F("ONLY ONE RECIPIENT"));
const char* arrEmail[] = {to.c_str()};
return send(arrEmail, 1, email, attachments);
}
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments); }
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments); }
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){ return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments); }
EMailSender::Response EMailSender::send(const char* to, EMailMessage &email, Attachments attachments){ DEBUG_PRINT(F("ONLY ONE RECIPIENT"));
const char* arrEmail[] = {to};
return send(arrEmail, 1, email, attachments);
}
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { DEBUG_PRINTLN(F("miltiple destination and attachments")); return send(to, sizeOfTo, 0, email, attachments); }
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(to, sizeOfTo, sizeOfCc, 0, email, attachments); }
// Initialize the SSL client library
// We input an EthernetClient, our trust anchors, and the analog pin
EMAIL_NETWORK_CLASS base_client;
SSLClient client(base_client, TAs, (size_t)TAs_NUM, ANALOG_PIN, 2);
#error "You must put outside scope the client declaration if you want use SSLClient!"
#ifdef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION
EMAIL_NETWORK_CLASS client;
#endif
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments) { unsigned long loopTime1, loopTime2;
DEBUG_PRINTLN(F("SSLClient active!"));
#ifndef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION
EMAIL_NETWORK_CLASS client;
#endif
DEBUG_PRINT(F("Insecure client:")); DEBUG_PRINTLN(this->isSecure);
#if (EMAIL_NETWORK_TYPE == NETWORK_ESP8266 || EMAIL_NETWORK_TYPE == NETWORK_ESP8266_242)
#ifndef ARDUINO_ESP8266_RELEASE_2_4_2
if (this->isSecure == false){
client.setInsecure();
bool mfln = client.probeMaxFragmentLength(this->smtp_server, this->smtp_port, 512);
DEBUG_PRINT("MFLN supported: ");
DEBUG_PRINTLN(mfln?"yes":"no");
if (mfln) {
client.setBufferSizes(512, 512);
}
}
#endif
#elif (EMAIL_NETWORK_TYPE == NETWORK_ESP32)
// String coreVersion = String(ESP.getSdkVersion());
// uint8_t firstdot = coreVersion.indexOf('.');
//
// DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat());
// DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f);
// if (coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f) {
// client.setInsecure();
// }
#include <core_version.h>
#if ((!defined(ARDUINO_ESP32_RELEASE_1_0_4)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_3)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_2)))
client.setInsecure();
#endif
#endif
EMailSender::Response response;
DEBUG_PRINTLN(this->smtp_server); DEBUG_PRINTLN(this->smtp_port);
if(!client.connect(this->smtp_server, this->smtp_port)) { response.desc = F("Could not connect to mail server"); response.code = F("2"); response.status = false;
client.flush();
client.stop();
return response;
}
response = awaitSMTPResponse(client, "220", "Connection Error"); if (!response.status) { client.flush(); client.stop(); return response; }
String commandHELO = "HELO"; if (this->useEHLO == true) { commandHELO = "EHLO"; } String helo = commandHELO + " "+/String(publicIPDescriptor)/ smtp_server /+": "/; DEBUG_PRINTLN(helo); client.println(helo);
response = awaitSMTPResponse(client, "250", "Identification error"); DEBUG_PRINTLN(response.status); if (!response.status) { client.flush(); client.stop(); return response; }
loopTime1 = millis(); DEBUG_PRINTLN(loopTime1); if (this->useEHLO == true) { for (int i = 0; i<=20; i++) { awaitSMTPResponse(client); loopTime2 = millis(); DEBUG_PRINTLN(loopTime2); if ((loopTime2 - loopTime1) > 2500) { break; } else { loopTime1 = loopTime2; } } } DEBUG_PRINTLN("End of awaitSMTPResponse");
if (useAuth){ if (this->isSASLLogin == true){
int size = 1 + strlen(this->email_login)+ strlen(this->email_password)+2;
char * logPass = (char *) malloc(size);
// strcpy(logPass, " "); // strcat(logPass, this->email_login); // strcat(logPass, " "); // strcat(logPass, this->email_password);
// String logPass; int maincont = 0;
logPass[maincont++] = ' ';
logPass[maincont++] = (char) 0;
for (unsigned int i = 0;i<strlen(this->email_login);i++){
logPass[maincont++] = this->email_login[i];
}
logPass[maincont++] = (char) 0;
for (unsigned int i = 0;i<strlen(this->email_password);i++){
logPass[maincont++] = this->email_password[i];
}
// strcpy(logPass, "\0"); // strcat(logPass, this->email_login); // strcat(logPass, "\0"); // strcat(logPass, this->email_password);
String auth = "AUTH PLAIN "+String(encode64_f(logPass, size));
// String auth = "AUTH PLAIN "+String(encode64(logPass)); DEBUG_PRINTLN(auth); client.println(auth); }else{ DEBUG_PRINTLN(F("AUTH LOGIN:")); client.println(F("AUTH LOGIN")); awaitSMTPResponse(client);
DEBUG_PRINTLN(encode64(this->email_login));
client.println(encode64(this->email_login));
awaitSMTPResponse(client);
DEBUG_PRINTLN(encode64(this->email_password));
client.println(encode64(this->email_password));
}
response = awaitSMTPResponse(client, "235", "SMTP AUTH error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
} DEBUG_PRINT(F("MAIL FROM: <")); DEBUG_PRINT(this->email_from); DEBUG_PRINTLN(F(">"));
client.print(F("MAIL FROM: <")); client.print(this->email_from); client.println(F(">")); awaitSMTPResponse(client);
// String rcpt = "RCPT TO: <" + String(to) + '>'; // // DEBUG_PRINTLN(rcpt); // client.println(rcpt);
int cont; for (cont=0;cont<(sizeOfTo+sizeOfCc+sizeOfCCn);cont++){ DEBUG_PRINT(F("RCPT TO: <")); DEBUG_PRINT(to[cont]); DEBUG_PRINTLN(F(">"));
client.print(F("RCPT TO: <"));
client.print(to[cont]);
client.println(F(">"));
awaitSMTPResponse(client);
}
DEBUG_PRINTLN(F("DATA:")); client.println(F("DATA"));
response = awaitSMTPResponse(client, "354", "SMTP DATA error"); if (!response.status) { client.flush(); client.stop(); return response; }
// client.println("From: <" + String(this->email_from) + '>');
client.print(F("From: ")); if (this->name_from){ client.print(this->name_from); } client.print(F(" <")); client.print(this->email_from); client.println(F(">"));
// client.println("To: <" + String(to) + '>');
client.print(F("To: ")); for (cont=0;cont<sizeOfTo;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfTo-1){ client.print(","); } } client.println();
if (sizeOfCc>0){ client.print(F("Cc: ")); for (;cont<sizeOfTo+sizeOfCc;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfCc-1){ client.print(","); } } client.println(); }
if (sizeOfCCn>0){ client.print(F("CCn: ")); for (;cont<sizeOfTo+sizeOfCc+sizeOfCCn;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfCCn-1){ client.print(","); } } client.println(); }
client.print(F("Subject: ")); client.println(email.subject);
// client.println(F("Mime-Version: 1.0"));
client.println(F("MIME-Version: 1.0")); client.println(F("Content-Type: Multipart/mixed; boundary=frontier"));
client.println(F("--frontier"));
client.print(F("Content-Type: "));
client.print(email.mime);
client.println(F("; charset=\"UTF-8\""));
// client.println(F("Content-Type: text/html; charset=\"UTF-8\"")); client.println(F("Content-Transfer-Encoding: 7bit")); client.println(); if (email.mime==F("text/html")){ // String body = "<!DOCTYPE html><html lang=\"en\">" + String(email.message) + "
Serial Monitor:
My code: Credentials and mail replaced by "***"