mirror of https://github.com/arendst/Tasmota.git
Refactor sendmail
This commit is contained in:
parent
ffcf90bdfe
commit
6cd19cbdf9
|
@ -30,11 +30,37 @@
|
|||
* 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 "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
|
||||
{
|
||||
private:
|
||||
|
@ -49,173 +75,24 @@ class SendEmail
|
|||
BearSSL::WiFiClientSecure_light *client;
|
||||
|
||||
String readClient();
|
||||
void a3_to_a4(unsigned char * a4, unsigned char * a3);
|
||||
int base64_encode(char *output, const char *input, int inputLen);
|
||||
public:
|
||||
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);
|
||||
void send_message_txt(char *msg);
|
||||
// void send_message_txt(char *msg);
|
||||
~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;
|
||||
|
||||
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() {
|
||||
|
@ -231,91 +108,75 @@ String SendEmail::readClient() {
|
|||
}
|
||||
|
||||
bool SendEmail::send(const String& from, const String& to, const String& subject, const char *msg) {
|
||||
bool status=false;
|
||||
String buffer;
|
||||
|
||||
if (!host.length()) {
|
||||
return status;
|
||||
}
|
||||
if (!host.length()) { return false; }
|
||||
|
||||
client->setTimeout(timeout);
|
||||
client->setInsecure();
|
||||
|
||||
// smtp connect
|
||||
#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
|
||||
|
||||
if (!client->connect(host.c_str(), port)) {
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Connection failed"));
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: ! E: connection failed"));
|
||||
#endif
|
||||
goto exit;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = readClient();
|
||||
String buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("220"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("220"))) { return false; }
|
||||
|
||||
buffer = F("EHLO ");
|
||||
buffer += client->localIP().toString();
|
||||
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("250"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (user.length()>0 && passwd.length()>0 ) {
|
||||
if (!buffer.startsWith(F("250"))) { return false; }
|
||||
|
||||
if ((user.length() > 0) && (passwd.length() > 0)) {
|
||||
buffer = F("AUTH LOGIN");
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("334")))
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("334"))) { return false; }
|
||||
|
||||
base64 b;
|
||||
buffer = b.encode(user);
|
||||
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("334"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("334"))) { return false; }
|
||||
|
||||
buffer = b.encode(passwd);
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("235"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("235"))) { return false; }
|
||||
}
|
||||
|
||||
// smtp send mail
|
||||
|
@ -323,69 +184,65 @@ String buffer;
|
|||
buffer += from;
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("250"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("250"))) { return false; }
|
||||
|
||||
buffer = F("RCPT TO:");
|
||||
buffer += to;
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("250"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("250"))) { return false; }
|
||||
|
||||
buffer = F("DATA");
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = readClient();
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailReadAddLogBuffer(&buffer);
|
||||
#endif
|
||||
if (!buffer.startsWith(F("354"))) {
|
||||
goto exit;
|
||||
}
|
||||
if (!buffer.startsWith(F("354"))) { return false; }
|
||||
|
||||
buffer = F("From: ");
|
||||
buffer += from;
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = F("To: ");
|
||||
buffer += to;
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
buffer = F("Subject: ");
|
||||
buffer += subject;
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef USE_SCRIPT
|
||||
if (*msg=='*' && *(msg+1)==0) {
|
||||
if (*msg == '*' && *(msg +1) == 0) {
|
||||
buffer = F("MIME-Version: 1.0\r\n");
|
||||
client->print(buffer);
|
||||
buffer = F("Content-Type: Multipart/mixed; boundary=frontier\r\n\r\n");
|
||||
client->print(buffer);
|
||||
|
||||
g_client=client;
|
||||
g_client = client;
|
||||
script_send_email_body(xsend_message_txt);
|
||||
} else {
|
||||
#endif // USE_SCRIPT
|
||||
|
@ -394,29 +251,121 @@ String buffer;
|
|||
client->println(msg);
|
||||
#ifdef USE_SCRIPT
|
||||
}
|
||||
#endif
|
||||
#endif // USE_SCRIPT
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
client->println('.');
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
|
||||
buffer = F("QUIT");
|
||||
client->println(buffer);
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
|
||||
MailWriteAddLogBuffer(&buffer);
|
||||
#endif
|
||||
|
||||
status=true;
|
||||
exit:
|
||||
return true;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#ifdef USE_SCRIPT
|
||||
void xsend_message_txt(char *msg) {
|
||||
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"),msg);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: '%s'"), msg);
|
||||
#endif
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
|
@ -456,7 +405,7 @@ void attach_Array(char *aname) {
|
|||
g_client->print(F("Content-Type: text/plain\r\n"));
|
||||
if (array && alen) {
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("array found %d"),alen);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: Array found %d"), alen);
|
||||
#endif
|
||||
char buff[64];
|
||||
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
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
|
||||
|
@ -519,6 +469,8 @@ void attach_File(char *path) {
|
|||
|
||||
#endif // USE_UFILESYS
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#endif // USE_SENDMAIL
|
||||
#endif // USE_WEBSERVER
|
||||
#endif // ESP8266
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include <ESP_Mail_Client.h>
|
||||
|
||||
//#define DEBUG_EMAIL_PORT // Enable serial debugging
|
||||
// #define DEBUG_EMAIL_PORT // Enable debugging
|
||||
|
||||
#ifndef SEND_MAIL32_MINRAM
|
||||
#undef SEND_MAIL32_MINRAM
|
||||
|
@ -35,224 +35,177 @@
|
|||
#endif
|
||||
|
||||
#define xPSTR(a) a
|
||||
|
||||
#define MAX_ATTCHMENTS 8
|
||||
|
||||
void script_send_email_body(void(*func)(char *));
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
char *attachments[MAX_ATTCHMENTS];
|
||||
uint8_t num_attachments;
|
||||
void script_send_email_body(void(*func)(char *));
|
||||
String html_content = "";
|
||||
SMTP_Message *email_mptr;
|
||||
SMTPSession *smtp;
|
||||
|
||||
//SMTPSession smtp;
|
||||
void smtpCallback(SMTP_Status status);
|
||||
|
||||
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
|
||||
uint32_t mem = ESP.getFreeHeap();
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("heap: %d"),mem);
|
||||
if (mem < SEND_MAIL32_MINRAM) {
|
||||
return 4;
|
||||
}
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("heap: %d"),mem);
|
||||
#endif
|
||||
uint32_t mem = ESP_getFreeHeap();
|
||||
if (mem < SEND_MAIL32_MINRAM) { return 4; }
|
||||
|
||||
while (*buffer==' ') buffer++;
|
||||
|
||||
if (*buffer != '[') {
|
||||
goto exit;
|
||||
}
|
||||
if (*buffer != '[') { return 1; }
|
||||
|
||||
buffer++;
|
||||
|
||||
endcmd = strchr(buffer, ']');
|
||||
if (!endcmd) {
|
||||
goto exit;
|
||||
}
|
||||
char *endcmd = strchr(buffer, ']');
|
||||
if (!endcmd) { return 1; }
|
||||
|
||||
// copy params
|
||||
blen = (uint32_t)endcmd - (uint32_t)buffer;
|
||||
oparams = (char*)calloc(blen+2, 1);
|
||||
if (!oparams) return 4;
|
||||
params = oparams;
|
||||
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;
|
||||
|
||||
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++) {
|
||||
attachments[cnt] = 0;
|
||||
}
|
||||
num_attachments = 0;
|
||||
|
||||
#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;
|
||||
smtp = new SMTPSession();
|
||||
if (!smtp) {
|
||||
if (oparams) { free(oparams); }
|
||||
return 4;
|
||||
}
|
||||
|
||||
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
|
||||
if (*user == '*') {
|
||||
user = xPSTR(EMAIL_USER);
|
||||
}
|
||||
if (*user == '*') { user = xPSTR(EMAIL_USER); }
|
||||
#endif
|
||||
|
||||
#ifdef EMAIL_PASSWORD
|
||||
if (*passwd == '*') {
|
||||
passwd = xPSTR(EMAIL_PASSWORD);
|
||||
}
|
||||
if (*passwd == '*') { passwd = xPSTR(EMAIL_PASSWORD); }
|
||||
#endif
|
||||
|
||||
#ifdef EMAIL_SERVER
|
||||
if (*mserv == '*') {
|
||||
mserv = xPSTR(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);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %d, %s, %s"), mserv, port, user, passwd);
|
||||
#endif
|
||||
|
||||
#ifdef EMAIL_FROM
|
||||
if (*from == '*') {
|
||||
from = xPSTR(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);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s, %s, %s, %s"), from, to, subject, cmd);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
smtp->debug(true);
|
||||
smtp->debug(true);
|
||||
#else
|
||||
smtp->debug(false);
|
||||
smtp->debug(false);
|
||||
#endif
|
||||
|
||||
// smtp->callback(smtpCallback);
|
||||
// smtp->callback(smtpCallback);
|
||||
|
||||
message.clearRecipients();
|
||||
message.clearCc();
|
||||
message.clearBcc();
|
||||
SMTP_Message message;
|
||||
email_mptr = &message;
|
||||
message.clearRecipients();
|
||||
message.clearCc();
|
||||
message.clearBcc();
|
||||
|
||||
session.server.host_name = mserv;
|
||||
session.server.port = port;
|
||||
session.login.email = user;
|
||||
session.login.password = passwd;
|
||||
session.login.user_domain = "googlemail.com";
|
||||
ESP_Mail_Session session;
|
||||
session.server.host_name = mserv;
|
||||
session.server.port = port;
|
||||
session.login.email = user;
|
||||
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
|
||||
if (*cmd == '*' && *(cmd + 1) == 0) {
|
||||
script_send_email_body(send_message_txt);
|
||||
} else {
|
||||
html_content += cmd;
|
||||
message.html.content = html_content.c_str();
|
||||
#ifdef USE_SCRIPT
|
||||
if (*cmd == '*' && *(cmd + 1) == 0) {
|
||||
script_send_email_body(send_message_txt);
|
||||
} else {
|
||||
html_content += cmd;
|
||||
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 */
|
||||
delay(0);
|
||||
|
||||
if (!MailClient.sendMail(smtp, &message, true)) {
|
||||
Serial.println("Error sending Email, " + smtp->errorReason());
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (smtp) delete smtp;
|
||||
if (smtp) { delete smtp; }
|
||||
for (uint32_t cnt = 0; cnt < MAX_ATTCHMENTS; cnt++) {
|
||||
if (attachments[cnt]) {
|
||||
free(attachments[cnt]);
|
||||
|
@ -260,10 +213,13 @@ exit:
|
|||
}
|
||||
}
|
||||
html_content = "";
|
||||
if (oparams) free(oparams);
|
||||
if (oparams) { free(oparams); }
|
||||
return status;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#ifdef USE_SCRIPT
|
||||
|
||||
void send_message_txt(char *txt) {
|
||||
if (*txt == '@') {
|
||||
|
@ -363,42 +319,41 @@ void attach_Data(char *name, uint8_t *buff, uint32_t len) {
|
|||
email_mptr->resetAttachItem(att);
|
||||
}
|
||||
|
||||
#endif // USE_SCRIPT
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
/* Callback function to get the Email sending status */
|
||||
void smtpCallback(SMTP_Status status)
|
||||
{
|
||||
/* Print the current status */
|
||||
Serial.println(status.info());
|
||||
void smtpCallback(SMTP_Status status) {
|
||||
/* Print the current status */
|
||||
Serial.println(status.info());
|
||||
|
||||
/* Print the sending result */
|
||||
if (status.success())
|
||||
{
|
||||
Serial.println("----------------");
|
||||
Serial.printf("Message sent success: %d\n", status.completedCount());
|
||||
Serial.printf("Message sent failled: %d\n", status.failedCount());
|
||||
Serial.println("----------------\n");
|
||||
struct tm dt;
|
||||
/* Print the sending result */
|
||||
if (status.success()) {
|
||||
Serial.println("----------------");
|
||||
Serial.printf("Message sent success: %d\n", status.completedCount());
|
||||
Serial.printf("Message sent failled: %d\n", status.failedCount());
|
||||
Serial.println("----------------\n");
|
||||
struct tm dt;
|
||||
|
||||
for (size_t i = 0; i < smtp->sendingResult.size(); i++)
|
||||
{
|
||||
/* Get the result item */
|
||||
SMTP_Result result = smtp->sendingResult.getItem(i);
|
||||
localtime_r(&result.timesstamp, &dt);
|
||||
for (size_t i = 0; i < smtp->sendingResult.size(); i++) {
|
||||
/* Get the result item */
|
||||
SMTP_Result result = smtp->sendingResult.getItem(i);
|
||||
localtime_r(&result.timesstamp, &dt);
|
||||
|
||||
Serial.printf("Message No: %d\n", i + 1);
|
||||
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("Recipient: %s\n", result.recipients);
|
||||
Serial.printf("Subject: %s\n", result.subject);
|
||||
Serial.printf("Message No: %d\n", i + 1);
|
||||
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("Recipient: %s\n", result.recipients);
|
||||
Serial.printf("Subject: %s\n", result.subject);
|
||||
}
|
||||
Serial.println("----------------\n");
|
||||
}
|
||||
Serial.println("----------------\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Tasmota_print(const char *txt) {
|
||||
#ifdef DEBUG_EMAIL_PORT
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("ESP32mail: %s"),txt);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MAI: %s"),txt);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue