Refactor sendmail

This commit is contained in:
Theo Arends 2022-06-21 23:03:34 +02:00
parent ffcf90bdfe
commit 6cd19cbdf9
2 changed files with 324 additions and 417 deletions

View File

@ -30,11 +30,37 @@
* SW Watchdog 3.2 sec. * SW Watchdog 3.2 sec.
\*********************************************************************************************/ \*********************************************************************************************/
//#define DEBUG_EMAIL_PORT // Enable serial debugging //#define DEBUG_EMAIL_PORT // Enable debugging
#ifndef MAIL_TIMEOUT
#define MAIL_TIMEOUT 2000
#endif
#ifndef SEND_MAIL_MINRAM
#define SEND_MAIL_MINRAM 12*1024
#endif
#define xPSTR(a) a
#include <base64.h> #include <base64.h>
#include "WiFiClientSecureLightBearSSL.h" #include "WiFiClientSecureLightBearSSL.h"
void script_send_email_body(void(*func)(char *));
/*********************************************************************************************/
#ifdef DEBUG_EMAIL_PORT
void MailWriteAddLogBuffer(String *buffer) {
AddLog(LOG_LEVEL_INFO, PSTR("MAI: > C: %s"), buffer->c_str());
}
void MailReadAddLogBuffer(String *buffer) {
AddLog(LOG_LEVEL_INFO, PSTR("MAI: < S: %s"), buffer->c_str());
}
#endif
/*********************************************************************************************/
class SendEmail class SendEmail
{ {
private: private:
@ -49,173 +75,24 @@ class SendEmail
BearSSL::WiFiClientSecure_light *client; BearSSL::WiFiClientSecure_light *client;
String readClient(); String readClient();
void a3_to_a4(unsigned char * a4, unsigned char * a3);
int base64_encode(char *output, const char *input, int inputLen);
public: public:
SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used); SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used);
bool send(const String& from, const String& to, const String& subject, const char *msg); bool send(const String& from, const String& to, const String& subject, const char *msg);
void send_message_txt(char *msg); // void send_message_txt(char *msg);
~SendEmail() {client->stop(); delete client;} ~SendEmail() {client->stop(); delete client;}
}; };
#ifndef SEND_MAIL_MINRAM
#define SEND_MAIL_MINRAM 12*1024
#endif
void script_send_email_body(void(*func)(char *));
#define xPSTR(a) a
uint16_t SendMail(char *buffer) {
char *params,*oparams;
const char *mserv;
uint16_t port;
const char *user;
const char *pstr;
const char *passwd;
const char *from;
const char *to;
const char *subject;
const char *cmd;
char auth=0;
uint16_t status=1;
SendEmail *mail=0;
uint16_t blen;
char *endcmd;
// return if not enough memory
uint16_t mem=ESP.getFreeHeap();
if (mem<SEND_MAIL_MINRAM) {
return 4;
}
while (*buffer==' ') buffer++;
if (*buffer!='[') {
goto exit;
}
buffer++;
endcmd=strchr(buffer,']');
if (!endcmd) {
goto exit;
}
// copy params
blen=(uint32_t)endcmd-(uint32_t)buffer;
oparams=(char*)calloc(blen+2,1);
if (!oparams) return 4;
params=oparams;
strncpy(oparams,buffer,blen+2);
oparams[blen]=0;
cmd=endcmd+1;
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("mailsize: %d"),blen);
#endif
mserv=strtok(params,":");
if (!mserv) {
goto exit;
}
// port
pstr=strtok(NULL,":");
if (!pstr) {
goto exit;
}
#ifdef EMAIL_PORT
if (*pstr=='*') {
port=EMAIL_PORT;
} else {
port=atoi(pstr);
}
#else
port=atoi(pstr);
#endif
user=strtok(NULL,":");
if (!user) {
goto exit;
}
passwd=strtok(NULL,":");
if (!passwd) {
goto exit;
}
from=strtok(NULL,":");
if (!from) {
goto exit;
}
to=strtok(NULL,":");
if (!to) {
goto exit;
}
subject=strtok(NULL,"]");
if (!subject) {
goto exit;
}
#ifdef EMAIL_USER
if (*user=='*') {
user=xPSTR(EMAIL_USER);
}
#endif
#ifdef EMAIL_PASSWORD
if (*passwd=='*') {
passwd=xPSTR(EMAIL_PASSWORD);
}
#endif
#ifdef EMAIL_SERVER
if (*mserv=='*') {
mserv=xPSTR(EMAIL_SERVER);
}
#endif
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s - %d - %s - %s"),mserv,port,user,passwd);
#endif
// 2 seconds timeout
#ifndef MAIL_TIMEOUT
#define MAIL_TIMEOUT 2000
#endif
mail = new SendEmail(mserv,port,user,passwd, MAIL_TIMEOUT, auth);
#ifdef EMAIL_FROM
if (*from=='*') {
from=xPSTR(EMAIL_FROM);
}
#endif
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s - %s - %s - %s"),from,to,subject,cmd);
#endif
if (mail) {
bool result=mail->send(from,to,subject,cmd);
delete mail;
if (result==true) status=0;
}
exit:
if (oparams) free(oparams);
return status;
}
WiFiClient *g_client; WiFiClient *g_client;
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) : SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) { host(host),
port(port),
user(user),
passwd(passwd),
timeout(timeout),
ssl(ssl),
auth_used(auth_used),
client(new BearSSL::WiFiClientSecure_light(1024,1024)) {
} }
String SendEmail::readClient() { String SendEmail::readClient() {
@ -231,91 +108,75 @@ String SendEmail::readClient() {
} }
bool SendEmail::send(const String& from, const String& to, const String& subject, const char *msg) { bool SendEmail::send(const String& from, const String& to, const String& subject, const char *msg) {
bool status=false; if (!host.length()) { return false; }
String buffer;
if (!host.length()) {
return status;
}
client->setTimeout(timeout); client->setTimeout(timeout);
client->setInsecure(); client->setInsecure();
// smtp connect // smtp connect
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("Connecting: %s on port %d"),host.c_str(),port); AddLog(LOG_LEVEL_INFO, PSTR("MAI: > C: connecting host %s on port %d"), host.c_str(), port);
#endif #endif
if (!client->connect(host.c_str(), port)) { if (!client->connect(host.c_str(), port)) {
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("Connection failed")); AddLog(LOG_LEVEL_INFO, PSTR("MAI: ! E: connection failed"));
#endif #endif
goto exit; return false;
} }
buffer = readClient(); String buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("220"))) { if (!buffer.startsWith(F("220"))) { return false; }
goto exit;
}
buffer = F("EHLO "); buffer = F("EHLO ");
buffer += client->localIP().toString(); buffer += client->localIP().toString();
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) { return false; }
goto exit;
}
if (user.length()>0 && passwd.length()>0 ) {
if ((user.length() > 0) && (passwd.length() > 0)) {
buffer = F("AUTH LOGIN"); buffer = F("AUTH LOGIN");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("334"))) if (!buffer.startsWith(F("334"))) { return false; }
{
goto exit;
}
base64 b; base64 b;
buffer = b.encode(user); buffer = b.encode(user);
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("334"))) { if (!buffer.startsWith(F("334"))) { return false; }
goto exit;
}
buffer = b.encode(passwd); buffer = b.encode(passwd);
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("235"))) { if (!buffer.startsWith(F("235"))) { return false; }
goto exit;
}
} }
// smtp send mail // smtp send mail
@ -323,69 +184,65 @@ String buffer;
buffer += from; buffer += from;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) { return false; }
goto exit;
}
buffer = F("RCPT TO:"); buffer = F("RCPT TO:");
buffer += to; buffer += to;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) { return false; }
goto exit;
}
buffer = F("DATA"); buffer = F("DATA");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailReadAddLogBuffer(&buffer);
#endif #endif
if (!buffer.startsWith(F("354"))) { if (!buffer.startsWith(F("354"))) { return false; }
goto exit;
}
buffer = F("From: "); buffer = F("From: ");
buffer += from; buffer += from;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = F("To: "); buffer = F("To: ");
buffer += to; buffer += to;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = F("Subject: "); buffer = F("Subject: ");
buffer += subject; buffer += subject;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
/*-------------------------------------------------------------------------------------------*/
#ifdef USE_SCRIPT #ifdef USE_SCRIPT
if (*msg=='*' && *(msg+1)==0) { if (*msg == '*' && *(msg +1) == 0) {
buffer = F("MIME-Version: 1.0\r\n"); buffer = F("MIME-Version: 1.0\r\n");
client->print(buffer); client->print(buffer);
buffer = F("Content-Type: Multipart/mixed; boundary=frontier\r\n\r\n"); buffer = F("Content-Type: Multipart/mixed; boundary=frontier\r\n\r\n");
client->print(buffer); client->print(buffer);
g_client = client;
g_client=client;
script_send_email_body(xsend_message_txt); script_send_email_body(xsend_message_txt);
} else { } else {
#endif // USE_SCRIPT #endif // USE_SCRIPT
@ -394,29 +251,121 @@ String buffer;
client->println(msg); client->println(msg);
#ifdef USE_SCRIPT #ifdef USE_SCRIPT
} }
#endif #endif // USE_SCRIPT
/*-------------------------------------------------------------------------------------------*/
client->println('.'); client->println('.');
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
buffer = F("QUIT"); buffer = F("QUIT");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str()); MailWriteAddLogBuffer(&buffer);
#endif #endif
status=true; return true;
exit: }
/*********************************************************************************************/
uint16_t SendMail(char *buffer) {
// return if not enough memory
uint16_t mem = ESP_getFreeHeap();
if (mem < SEND_MAIL_MINRAM) { return 4; }
while (*buffer == ' ') { buffer++; }
if (*buffer != '[') { return 1; }
buffer++;
char *endcmd = strchr(buffer, ']');
if (!endcmd) { return 1; }
// copy params
uint16_t blen = (uint32_t)endcmd - (uint32_t)buffer;
char *oparams = (char*)calloc(blen +2, 1);
if (!oparams) { return 4; }
uint16_t status = 1;
char *params = oparams;
strncpy(oparams, buffer, blen +2);
oparams[blen] = 0;
const char *cmd = endcmd +1;
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("MAI: Size: %d"), blen);
#endif
const char *mserv = strtok(params, ":");
if (mserv) {
// port
const char *pstr = strtok(NULL, ":");
if (pstr) {
uint16_t port;
#ifdef EMAIL_PORT
port = (*pstr == '*') ? EMAIL_PORT : atoi(pstr);
#else
port = atoi(pstr);
#endif
const char *user = strtok(NULL, ":");
if (user) {
const char *passwd = strtok(NULL, ":");
if (passwd) {
const char *from = strtok(NULL, ":");
if (from) {
const char *to = strtok(NULL,":");
if (to) {
const char *subject = strtok(NULL, "]");
if (subject) {
#ifdef EMAIL_USER
if (*user == '*') { user = xPSTR(EMAIL_USER); }
#endif
#ifdef EMAIL_PASSWORD
if (*passwd == '*') { passwd = xPSTR(EMAIL_PASSWORD); }
#endif
#ifdef EMAIL_SERVER
if (*mserv == '*') { mserv = xPSTR(EMAIL_SERVER); }
#endif
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %d, %s, %s"), mserv, port, user, passwd);
#endif
#ifdef EMAIL_FROM
if (*from == '*') { from = xPSTR(EMAIL_FROM); }
#endif
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %s, %s, %s"), from, to, subject, cmd);
#endif
char auth = 0;
SendEmail *mail = new SendEmail(mserv, port, user, passwd, MAIL_TIMEOUT, auth);
if (mail) {
bool result = mail->send(from, to, subject, cmd);
delete mail;
if (result == true) { status = 0; }
}
}
}
}
}
}
}
}
if (oparams) { free(oparams); }
return status; return status;
} }
/*********************************************************************************************/
#ifdef USE_SCRIPT #ifdef USE_SCRIPT
void xsend_message_txt(char *msg) { void xsend_message_txt(char *msg) {
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s"),msg); AddLog(LOG_LEVEL_INFO, PSTR("MAI: '%s'"), msg);
#endif #endif
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
@ -456,7 +405,7 @@ void attach_Array(char *aname) {
g_client->print(F("Content-Type: text/plain\r\n")); g_client->print(F("Content-Type: text/plain\r\n"));
if (array && alen) { if (array && alen) {
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("array found %d"),alen); AddLog(LOG_LEVEL_INFO, PSTR("MAI: Array found %d"), alen);
#endif #endif
char buff[64]; char buff[64];
sprintf_P(buff,PSTR("Content-Disposition: attachment; filename=\"%s.txt\"\r\n\r\n"), aname); sprintf_P(buff,PSTR("Content-Disposition: attachment; filename=\"%s.txt\"\r\n\r\n"), aname);
@ -485,6 +434,7 @@ void attach_Array(char *aname) {
} }
#endif // USE_SCRIPT #endif // USE_SCRIPT
/*********************************************************************************************/
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
@ -519,6 +469,8 @@ void attach_File(char *path) {
#endif // USE_UFILESYS #endif // USE_UFILESYS
/*********************************************************************************************/
#endif // USE_SENDMAIL #endif // USE_SENDMAIL
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
#endif // ESP8266 #endif // ESP8266

View File

@ -27,7 +27,7 @@
#include <ESP_Mail_Client.h> #include <ESP_Mail_Client.h>
//#define DEBUG_EMAIL_PORT // Enable serial debugging // #define DEBUG_EMAIL_PORT // Enable debugging
#ifndef SEND_MAIL32_MINRAM #ifndef SEND_MAIL32_MINRAM
#undef SEND_MAIL32_MINRAM #undef SEND_MAIL32_MINRAM
@ -35,224 +35,177 @@
#endif #endif
#define xPSTR(a) a #define xPSTR(a) a
#define MAX_ATTCHMENTS 8 #define MAX_ATTCHMENTS 8
void script_send_email_body(void(*func)(char *));
/*********************************************************************************************/
char *attachments[MAX_ATTCHMENTS]; char *attachments[MAX_ATTCHMENTS];
uint8_t num_attachments; uint8_t num_attachments;
void script_send_email_body(void(*func)(char *));
String html_content = ""; String html_content = "";
SMTP_Message *email_mptr; SMTP_Message *email_mptr;
SMTPSession *smtp; SMTPSession *smtp;
//SMTPSession smtp; //SMTPSession smtp;
void smtpCallback(SMTP_Status status); void smtpCallback(SMTP_Status status);
uint16_t SendMail(char *buffer) { uint16_t SendMail(char *buffer) {
char *params,*oparams = 0;
const char *mserv;
uint16_t port;
const char *user;
const char *pstr;
const char *passwd;
const char *from;
const char *to;
const char *subject;
const char *cmd;
uint16_t status = 1;
uint16_t blen;
char *endcmd;
ESP_Mail_Session session;
SMTP_Message message;
email_mptr = &message;
smtp = new SMTPSession();
if (!smtp) {
return 4;
}
// return if not enough memory // return if not enough memory
uint32_t mem = ESP.getFreeHeap(); uint32_t mem = ESP_getFreeHeap();
//AddLog(LOG_LEVEL_INFO, PSTR("heap: %d"),mem); if (mem < SEND_MAIL32_MINRAM) { return 4; }
if (mem < SEND_MAIL32_MINRAM) {
return 4;
}
#ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("heap: %d"),mem);
#endif
while (*buffer==' ') buffer++; while (*buffer==' ') buffer++;
if (*buffer != '[') { return 1; }
if (*buffer != '[') {
goto exit;
}
buffer++; buffer++;
char *endcmd = strchr(buffer, ']');
endcmd = strchr(buffer, ']'); if (!endcmd) { return 1; }
if (!endcmd) {
goto exit;
}
// copy params // copy params
blen = (uint32_t)endcmd - (uint32_t)buffer; uint16_t blen = (uint32_t)endcmd - (uint32_t)buffer;
oparams = (char*)calloc(blen+2, 1); char *oparams = (char*)calloc(blen+2, 1);
if (!oparams) return 4; if (!oparams) { return 4; }
params = oparams;
uint16_t status = 1;
char *params = oparams;
strncpy(oparams, buffer, blen+2); strncpy(oparams, buffer, blen+2);
oparams[blen] = 0; oparams[blen] = 0;
const char *cmd = endcmd + 1;
cmd = endcmd + 1; #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("MAI: Size %d"), blen);
#endif
for (uint32_t cnt = 0; cnt < MAX_ATTCHMENTS; cnt++) { for (uint32_t cnt = 0; cnt < MAX_ATTCHMENTS; cnt++) {
attachments[cnt] = 0; attachments[cnt] = 0;
} }
num_attachments = 0; num_attachments = 0;
#ifdef DEBUG_EMAIL_PORT smtp = new SMTPSession();
AddLog(LOG_LEVEL_INFO, PSTR("mailsize: %d"),blen); if (!smtp) {
#endif if (oparams) { free(oparams); }
return 4;
mserv = strtok(params, ":");
if (!mserv) {
goto exit;
}
// port
pstr = strtok(NULL, ":");
if (!pstr) {
goto exit;
}
#ifdef EMAIL_PORT
if (*pstr == '*') {
port = EMAIL_PORT;
} else {
port = atoi(pstr);
}
#else
port = atoi(pstr);
#endif
user = strtok(NULL, ":");
if (!user) {
goto exit;
}
passwd = strtok(NULL, ":");
if (!passwd) {
goto exit;
}
from = strtok(NULL, ":");
if (!from) {
goto exit;
}
to = strtok(NULL, ":");
if (!to) {
goto exit;
}
subject = strtok(NULL, "]");
if (!subject) {
goto exit;
} }
const char *mserv = strtok(params, ":");
if (mserv) {
// port
const char *pstr = strtok(NULL, ":");
if (pstr) {
uint16_t port;
#ifdef EMAIL_PORT
port = (*pstr == '*') ? EMAIL_PORT : port = atoi(pstr);
#else
port = atoi(pstr);
#endif
const char *user = strtok(NULL, ":");
if (user) {
const char *passwd = strtok(NULL, ":");
if (passwd) {
const char *from = strtok(NULL, ":");
if (from) {
const char *to = strtok(NULL, ":");
if (to) {
const char *subject = strtok(NULL, "]");
if (subject) {
#ifdef EMAIL_USER #ifdef EMAIL_USER
if (*user == '*') { if (*user == '*') { user = xPSTR(EMAIL_USER); }
user = xPSTR(EMAIL_USER);
}
#endif #endif
#ifdef EMAIL_PASSWORD #ifdef EMAIL_PASSWORD
if (*passwd == '*') { if (*passwd == '*') { passwd = xPSTR(EMAIL_PASSWORD); }
passwd = xPSTR(EMAIL_PASSWORD);
}
#endif #endif
#ifdef EMAIL_SERVER #ifdef EMAIL_SERVER
if (*mserv == '*') { if (*mserv == '*') { mserv = xPSTR(EMAIL_SERVER); }
mserv = xPSTR(EMAIL_SERVER);
}
#endif #endif
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s - %d - %s - %s"), mserv, port, user, passwd); AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %d, %s, %s"), mserv, port, user, passwd);
#endif #endif
#ifdef EMAIL_FROM #ifdef EMAIL_FROM
if (*from == '*') { if (*from == '*') { from = xPSTR(EMAIL_FROM); }
from = xPSTR(EMAIL_FROM);
}
#endif #endif
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("%s - %s - %s - %s"), from, to, subject, cmd); AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %s, %s, %s"), from, to, subject, cmd);
#endif #endif
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
smtp->debug(true); smtp->debug(true);
#else #else
smtp->debug(false); smtp->debug(false);
#endif #endif
// smtp->callback(smtpCallback); // smtp->callback(smtpCallback);
message.clearRecipients(); SMTP_Message message;
message.clearCc(); email_mptr = &message;
message.clearBcc(); message.clearRecipients();
message.clearCc();
message.clearBcc();
session.server.host_name = mserv; ESP_Mail_Session session;
session.server.port = port; session.server.host_name = mserv;
session.login.email = user; session.server.port = port;
session.login.password = passwd; session.login.email = user;
session.login.user_domain = "googlemail.com"; session.login.password = passwd;
session.login.user_domain = "googlemail.com";
message.enable.chunking = true;
char sname[32];
strlcpy(sname, SettingsText(SET_FRIENDLYNAME1), sizeof(sname));
message.sender.name = sname;
message.sender.email = from;
message.subject = subject;
message.addRecipient("user1", to);
message.html.charSet = "utf-8";
message.text.charSet = "utf-8";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal;
//message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
message.response.notify = esp_mail_smtp_notify_failure;
message.html.charSet = "us-ascii";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
message.addHeader("Message-ID: <user1@gmail.com>");
message.enable.chunking = true; /*-------------------------------------------------------------------------------------------*/
char sname[32];
strlcpy(sname, SettingsText(SET_FRIENDLYNAME1), sizeof(sname));
message.sender.name = sname;
message.sender.email = from;
message.subject = subject;
message.addRecipient("user1", to);
message.html.charSet = "utf-8";
message.text.charSet = "utf-8";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal;
//message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
message.response.notify = esp_mail_smtp_notify_failure;
message.html.charSet = "us-ascii";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
message.addHeader("Message-ID: <user1@gmail.com>");
#ifdef USE_SCRIPT #ifdef USE_SCRIPT
if (*cmd == '*' && *(cmd + 1) == 0) { if (*cmd == '*' && *(cmd + 1) == 0) {
script_send_email_body(send_message_txt); script_send_email_body(send_message_txt);
} else { } else {
html_content += cmd; html_content += cmd;
message.html.content = html_content.c_str(); message.html.content = html_content.c_str();
}
#else
html_content += cmd;
message.html.content = html_content.c_str();
#endif // USE_SCRIPT
/*-------------------------------------------------------------------------------------------*/
/* Connect to server with the session config */
delay(0);
if (smtp->connect(&session)) {
/* Start sending the Email and close the session */
delay(0);
if (!MailClient.sendMail(smtp, &message, true)) {
Serial.println("Error sending Email, " + smtp->errorReason());
} else {
status = 0;
}
}
}
}
}
}
}
} }
#else
html_content += cmd;
message.html.content = html_content.c_str();
#endif
/* Connect to server with the session config */
delay(0);
if (!smtp->connect(&session)) {
goto exit;
} }
/* Start sending the Email and close the session */ if (smtp) { delete smtp; }
delay(0);
if (!MailClient.sendMail(smtp, &message, true)) {
Serial.println("Error sending Email, " + smtp->errorReason());
} else {
status = 0;
}
exit:
if (smtp) delete smtp;
for (uint32_t cnt = 0; cnt < MAX_ATTCHMENTS; cnt++) { for (uint32_t cnt = 0; cnt < MAX_ATTCHMENTS; cnt++) {
if (attachments[cnt]) { if (attachments[cnt]) {
free(attachments[cnt]); free(attachments[cnt]);
@ -260,10 +213,13 @@ exit:
} }
} }
html_content = ""; html_content = "";
if (oparams) free(oparams); if (oparams) { free(oparams); }
return status; return status;
} }
/*********************************************************************************************/
#ifdef USE_SCRIPT
void send_message_txt(char *txt) { void send_message_txt(char *txt) {
if (*txt == '@') { if (*txt == '@') {
@ -363,42 +319,41 @@ void attach_Data(char *name, uint8_t *buff, uint32_t len) {
email_mptr->resetAttachItem(att); email_mptr->resetAttachItem(att);
} }
#endif // USE_SCRIPT
/*********************************************************************************************/
/* Callback function to get the Email sending status */ /* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status) void smtpCallback(SMTP_Status status) {
{ /* Print the current status */
/* Print the current status */ Serial.println(status.info());
Serial.println(status.info());
/* Print the sending result */ /* Print the sending result */
if (status.success()) if (status.success()) {
{ Serial.println("----------------");
Serial.println("----------------"); Serial.printf("Message sent success: %d\n", status.completedCount());
Serial.printf("Message sent success: %d\n", status.completedCount()); Serial.printf("Message sent failled: %d\n", status.failedCount());
Serial.printf("Message sent failled: %d\n", status.failedCount()); Serial.println("----------------\n");
Serial.println("----------------\n"); struct tm dt;
struct tm dt;
for (size_t i = 0; i < smtp->sendingResult.size(); i++) for (size_t i = 0; i < smtp->sendingResult.size(); i++) {
{ /* Get the result item */
/* Get the result item */ SMTP_Result result = smtp->sendingResult.getItem(i);
SMTP_Result result = smtp->sendingResult.getItem(i); localtime_r(&result.timesstamp, &dt);
localtime_r(&result.timesstamp, &dt);
Serial.printf("Message No: %d\n", i + 1); Serial.printf("Message No: %d\n", i + 1);
Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); Serial.printf("Status: %s\n", result.completed ? "success" : "failed");
Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
Serial.printf("Recipient: %s\n", result.recipients); Serial.printf("Recipient: %s\n", result.recipients);
Serial.printf("Subject: %s\n", result.subject); Serial.printf("Subject: %s\n", result.subject);
}
Serial.println("----------------\n");
} }
Serial.println("----------------\n");
} }
}
void Tasmota_print(const char *txt) { void Tasmota_print(const char *txt) {
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
AddLog(LOG_LEVEL_INFO, PSTR("ESP32mail: %s"),txt); AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s"),txt);
#endif #endif
} }