Inviare email con allegati (libreria v2.x): esp32 e esp8266 – Part 2

Spread the love
  •  
  •  
  •  
  • 1
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    1
    Share

Vorrei andare ad introdurre la versione 2 della libreria EMailSender, una grande evoluzione rispetto alla versione 1, con supporto per Arduino con dispositivi ethernet w5100, w5200 e w5500 e dispositivi clone enc28J60, e supporto per esp32 ed esp8266 .
Ora puoi anche aggiungere allegati , caricati da un dispositivo di archiviazione come SD o SPIFFS.

Puoi fare riferimento alla versione 1 in questo articolo Invia email con esp8266 e Arduino

Introduzione

Un metodo semplice per notificare un problema è utilizzare la posta elettronica, quindi ho creato una libreria per farlo.

Send email with attachments esp8266 esp32 library
Send email with attachments esp8266 esp32 library

Questa libreria utilizza il protocollo SMTP:

Simple Mail Transfer Protocol (SMTP) è un protocollo standard per la trasmissione di email. Inizialmente proposto nella RFC 778 nel 1981, poi aggiornato con RFC 821 nel 1982 ed ulteriormente modificato nel 2008 con l’introduzione di extended SMTP (RFC 1869 e RFC 5321), che è il protocollo attualmente in uso.
Anche se i 
server di posta elettronica utilizzano SMTP per inviare e ricevere mail, i client mail a livello utente utilizzano SMTP solo per inviare il messaggio al server mail, il quale si occupa dell’invio del messaggio stesso. Per recuperare i messaggi, le applicazioni client usano solitamente protocolli come IMAP o POP3.
La comunicazione tra i server mail utilizza il protocollo 
TCP sulla porta 25. I client mail, tuttavia, spesso inviano le mail in uscita al server sulla porta 587. Anche se deprecata, i provider mail e alcuni produttori come Apple, permettono ancora l’uso della porta non standard 465 per questa operazione. (Cit. Wiki)

Per gli esempi utilizzo un account dedicato di Gmail, creo un nuovo account perché è necessario ridurre la sicurezza per utilizzarlo con un programma esterno.

Libreria

Puoi trovare la mia libreria qui.

Per scaricare.

Clicca il bottone DOWNLOADS sull’angolo in alto a destra, e rinomina la cartella decompressa EMailSender.

Controlla che la cartella EMailSender contenga EMailSender.cpp e EMailSender.h.

Posizione la libreria EMailSender nella tua cartella /libraries/.

Potresti dover creare la sottocartella libraries se è la tua prima libreria.

Riavvia l’IDE.

Uso

Costruttore: il valore predefinito è abbastanza semplice e usa GMail come server smtp.

EMailSender emailSend("smtp.account@gmail.com", "password");

Se si desidera utilizzare un altro fornitore, è possibile utilizzare un costruttore più complesso (ma comunque semplice)

EMailSender(const char* email_login, const char* email_password);

EMailSender(const char* email_login, const char* email_password, const char* email_from);

EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* smtp_server, uint16_t smtp_port);
  • email_login: login account smtp
  • email_password: password account smtp
  • email_from: email del mittente
  • smtp_server: server SMTP
  • smtp_port: porta SMTP

Ora rispetto alla libreria v1.x puoi notare che il flag isSecure non esiste più

  • isSecure = false: if false BearSSL permette una connessione insicura TLS

ma puoi continuare a gestirlo con

void setIsSecure(bool isSecure = false);

Altri parametri che è possibile impostare post costruttore sono

void setUseAuth(bool useAuth = true);
void setPublicIpDescriptor(const char *publicIpDescriptor = "mischianti");

Il primo permette di escludere l’handshake di autenticazione, il secondo modifica l’identificazione del messaggio HELO.

È necessario connettersi a ad internet :P.

Esempio di base con GMail smtp

In fondo all’articolo trovi come configurare GMail.

Crea un messaggio con la struttura EMailMessage

    EMailSender::EMailMessage message;
    message.subject = "Subject";
    message.message = "Hi, How are you<br>Fine.";

Invia messaggio:

    EMailSender::Response resp = emailSend.send("account_to_send@gmail.com", message);

Quindi controlla la risposta:

    Serial.println("Sending status: ");
    Serial.println(resp.code);
    Serial.println(resp.desc);
    Serial.println(resp.status);

Esempio di output:

Connection: ESTABLISHED
Got IP address: 192.168.1.104
Sending status: 
1
0
Message sent!

esp8266

Di norma utilizzo un WeMos D1 mini per il mio test

Puoi trovare il WeMos D1 mini qui AliExpress

Per inviare e-mail con esp8266 con WiFi integrato è abbastanza semplice, ma devi prestare attenzione alla alla versione del core, perché se hai una versione core inferiore o uguale a 2.4.2 devi selezionare una specifica #define.

Per selezionare il tuo dispositivo devi andare sul file EMailSenderKey.h della libreria e sostituire questa riga

#define DEFAULT_EMAIL_NETWORK_TYPE_ESP8266 	NETWORK_ESP8266

con

#define DEFAULT_EMAIL_NETWORK_TYPE_ESP8266 	NETWORK_ESP8266_242

Retrocompatibilità con la libreria v1.x

Per garantire compatibilità con le versioni precedenti della libreria (1.x) puoi anche decommentare la stessa definizione della vecchia libreria.

Quindi, se hai un core esp8266 2.4.2 o inferiore, devi decomporre questa linea

// Uncomment if you use esp8266 core <= 2.4.2
#define ARDUINO_ESP8266_RELEASE_2_4_2

Inviare una semplice email

Ecco un semplice esempio di come inviare una EMail con GMail come provider SMTP.

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * Simple esp8266 Gmail send example
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <EMailSender.h>
#include <ESP8266WiFi.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

uint8_t connection_state = 0;
uint16_t reconnect_interval = 10000;

EMailSender emailSend("smtp.account@gmail.com", "password");

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);
        Serial.println(nSSID);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED &amp;&amp; i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) &amp;&amp; !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

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

    connection_state = WiFiConnect(ssid, password);
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";

    EMailSender::Response resp = emailSend.send("account_to_send@gmail.com", message);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
}

void loop()
{

}

Inviare una EMail con allegati

Send email with attachments Arduino esp8266 esp32 test with image and txt
Send email with attachments Arduino esp8266 esp32 test with image and txt

Per inviare allegati è necessario selezionare un dispositivo di archiviazione, per semplificare la gestione useremo il filesystem integrato SPIFFS, su come inserire i dati sul filesystem SPIFFS fate riferimento a questo articolo “WeMos D1 mini (esp8266): SPIFFS FileSystem integrato“.

Il core del codice è la generazione della struttura per trasmettere le informazioni per caricare e trasmettere i file.

    EMailSender::FileDescriptior fileDescriptor[2];
    fileDescriptor[1].filename = F("test.txt");
    fileDescriptor[1].url = F("/test.txt");
    fileDescriptor[1].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    fileDescriptor[0].filename = F("logo.jpg");
    fileDescriptor[0].url = F("/logo.jpg");
    fileDescriptor[0].mime = "image/jpg";
    fileDescriptor[0].encode64 = true;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    EMailSender::Attachments attachs = {2, fileDescriptor};

    EMailSender::Response resp = emailSend.send("<receipe@gmail.com>", message, attachs);

I campi di MailSender::FileDescriptiorsono abbastanza comprensibili, ma presta attenzione a encode64che specifica se vuoi codificare l’allegato, questo è utile se ci sono alcuni caratteri speciali non supportati.
Per le immagini se non specifichi encode64 probabilmente arrivano con artefatte.

Ma attenzione, la codifica di file di grandi dimensioni richiede un po ‘di tempo.

Il campo mime specifica il tipo mime del file che si desidera allegare. Ecco alcuni esempi di tipi MIME esistenti.

Poi dovrai specificare storageType, in genere supportiamo SD e SPIFFS, per Arduino solo SD.

filenameurl il nome del file è il nome che appare al destinatario, l’URL è dove si trova il file nell’FS selezionato.

Poi in EMailSender::Attachmentsè necessario specificare il numero di allegati e impostare l’array del EMailSender::FileDescriptior.

Il codice risultante è questo

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * esp8266 Gmail send example with 2 attach loaded in SPIFFS
 *
 * The base64 encoding of the image is slow, so be patient
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <EMailSender.h>
#include <ESP8266WiFi.h>

uint8_t connection_state = 0;
uint16_t reconnect_interval = 10000;

const char* ssid = "<YOUR_SSID>";
const char* password = "<YOUR_PASSWD>";

EMailSender emailSend("<smtp_account@gmail.com>", "<PASSWORD>");

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);
        Serial.println(nSSID);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED &amp;&amp; i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) &amp;&amp; !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

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

    if(!SPIFFS.begin()){
          Serial.println("An Error has occurred while mounting SPIFFS");
          return;
    }

    Serial.println("ReadDir");
    Dir dir = SPIFFS.openDir("/");
    while (dir.next()) {
        Serial.print(dir.fileName());
        if(dir.fileSize()) {
            File f = dir.openFile("r");
            Serial.println(f.size());
        }
    }

    connection_state = WiFiConnect(ssid, password);
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";

    EMailSender::FileDescriptior fileDescriptor[2];
    fileDescriptor[1].filename = F("test.txt");
    fileDescriptor[1].url = F("/test.txt");
    fileDescriptor[1].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    fileDescriptor[0].filename = F("logo.jpg");
    fileDescriptor[0].url = F("/logo.jpg");
    fileDescriptor[0].mime = "image/jpg";
    fileDescriptor[0].encode64 = true;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    EMailSender::Attachments attachs = {2, fileDescriptor};

    EMailSender::Response resp = emailSend.send("<receipe@gmail.com>", message, attachs);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
}

void loop()
{

}

ESP32

Qui puoi trovare alcuni modelli di esp32 che uso per il mio test AliExpress ESP32 Dev Kit v1 - AliExpress selectable - AliExpress TTGO T-Display 1.14 ESP32 - AliExpress NodeMCU V3 V2 ESP8266 Lolin32
Send email with attachments Arduino esp8266 esp32 test with image and txt
Send email with attachments Arduino esp8266 esp32 test with image and txt

ESP32 è molto simile a esp8266 ma SD e SPIFFS funzionano senza FS_NO_GLOBALS perché utilizzano la stessa File di FS.h

Quindi ora possiamo ripetere le considerazioni dell’implementazione dell’esp8266.

Inviare semplici email

Ecco quindi un esempio di invio di e-mail con il provider GMail (configurare GMail come descritto alla fine dell’articolo).

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * Simple esp32 Gmail send example
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <EMailSender.h>
#include <WiFi.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

uint8_t connection_state = 0;
uint16_t reconnect_interval = 10000;

EMailSender emailSend("account_login@gmail.com", "<YOUR-GMAIL-PASSWD>");

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);
        Serial.println(nSSID);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED &amp;&amp; i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) &amp;&amp; !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

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

    connection_state = WiFiConnect(ssid, password);
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";

    EMailSender::Response resp = emailSend.send("receive_email@gmail.com", message);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
}

void loop()
{

}

Inviare email con allegati

Per inviare gli allegati è necessario selezionare un dispositivo di archiviazione, per semplificare la gestione useremo il filesystem integrato SPIFFS, fare riferimento a questo articolo su come caricare i dati su SPIFFS “ESP32: fileSystem integrato SPIFFS”.

Il core del codice è la generazione della struttura per trasmettere le informazioni per caricare e trasmettere i file.

    EMailSender::FileDescriptior fileDescriptor[2];
    fileDescriptor[1].filename = F("test.txt");
    fileDescriptor[1].url = F("/test.txt");
    fileDescriptor[1].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    fileDescriptor[0].filename = F("logo.jpg");
    fileDescriptor[0].url = F("/logo.jpg");
    fileDescriptor[0].mime = "image/jpg";
    fileDescriptor[0].encode64 = true;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    EMailSender::Attachments attachs = {2, fileDescriptor};

    EMailSender::Response resp = emailSend.send("<receipe@gmail.com>", message, attachs);

I campi di MailSender::FileDescriptiorsono abbastanza comprensibili, ma presta attenzione a encode64che specifica se vuoi codificare l’allegato, questo è utile se ci sono alcuni caratteri speciali non supportati.
Per le immagini se non specifichi encode64 probabilmente arrivano con artefatte.

Ma attenzione, la codifica di file di grandi dimensioni richiede un po ‘di tempo.

Il campo mime specifica il tipo mime del file che si desidera allegare. Ecco alcuni esempi di tipi MIME esistenti.

Poi dovrai specificare storageType, in genere supportiamo SD e SPIFFS, per Arduino solo SD.

filenameurl il nome del file è il nome che appare al destinatario, l’URL è dove si trova il file nell’FS selezionato.

Poi in EMailSender::Attachmentsè necessario specificare il numero di allegati e impostare l’array del EMailSender::FileDescriptior.

Il codice risultante è questo

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * esp32 Gmail send example with 2 attach loaded in SPIFFS
 *
 * The base64 encoding of the image is slow, so be patient
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <EMailSender.h>
#include <WiFi.h>

#include <SPIFFS.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

uint8_t connection_state = 0;
uint16_t reconnect_interval = 10000;

EMailSender emailSend("account_gmail@gmail.com", "<YOUR-GMAIL-PASSWD>");

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);
        Serial.println(nSSID);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED &amp;&amp; i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) &amp;&amp; !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

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

    if(!SPIFFS.begin()){
          Serial.println("An Error has occurred while mounting SPIFFS");
          return;
    }

    Serial.println("ReadDir");
    File dir = SPIFFS.open("/");
    File file = dir.openNextFile();
    while (file) {
        Serial.print(file.name());
        Serial.println(file.size());

        file = dir.openNextFile();
    }

    connection_state = WiFiConnect(ssid, password);
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";

    EMailSender::FileDescriptior fileDescriptor[2];
    fileDescriptor[1].filename = F("test.txt");
    fileDescriptor[1].url = F("/test.txt");
    fileDescriptor[1].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    fileDescriptor[0].filename = F("logo.jpg");
    fileDescriptor[0].url = F("/logo.jpg");
    fileDescriptor[0].mime = "image/jpg";
    fileDescriptor[0].encode64 = true;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SPIFFS;

    EMailSender::Attachments attachs = {2, fileDescriptor};

    EMailSender::Response resp = emailSend.send("email_to_receive@gmail.com", message, attachs);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
}

void loop()
{

}

Abilita GMail

Allow less secure apps in Gmail

Consenti alle app meno sicure di accedere al tuo account Gmail

Google potrebbe bloccare i tentativi di accesso da alcune app o dispositivi che non utilizzano i moderni standard di sicurezza. Poiché queste app e dispositivi sono più facili da violare, il loro blocco aiuta a proteggere il tuo account.

Per disabilitare questa funzione di sicurezza:

  1. Accedi a Gmail
  2. Fai clic qui per accedere a Accesso meno sicuro all’app  nel mio account.
  3. Accanto a “Consenti app meno sicure:  OFF ”, selezionare l’interruttore per accendere  su ON .

Questa impostazione potrebbe non essere disponibile per:

Per gli utenti di G-Suite: abilitazione delle app meno sicure per accedere agli account

  1. Accedi  alla tua Console di amministrazione Google (accedi utilizzando un  account amministratore , non il tuo account corrente.
  2. Fai clic su  Sicurezza> Impostazioni di base .
  3. In  App meno sicure , seleziona  Vai a impostazioni per app meno sicure .
  4. Nella finestra secondaria, selezionare il pulsante di opzione  Consenti agli utenti di gestire il loro accesso ad app meno sicure  .

Dopo aver impostato  Consenti agli utenti  di gestire il loro accesso ad app meno sicure  , gli utenti interessati all’interno del gruppo selezionato o Unità organizzativa saranno in grado di attivare o disattivare le app meno sicure.

Amministratori di G-Suite: imporre l’accesso ad app meno sicure per tutti gli utenti

Utilizzare questa impostazione quando si desidera che l’accesso da un’app meno sicura sia disponibile per tutti per un periodo di tempo limitato, ad esempio per gli aggiornamenti.

  1. Accedi  alla tua Console di amministrazione Google. Accedi utilizzando un  account amministratore
  2. Fai clic su  Sicurezza> Impostazioni di base .
  3. In  App meno sicure , seleziona  Vai a impostazioni per app meno sicure .
  4. Nella finestra secondaria, seleziona il  pulsante di opzione  Imponi accesso ad app meno sicure per tutti gli utenti .

Una volta impostato  Applica l’accesso ad app meno sicure per tutti gli utenti  , gli utenti interessati all’interno del gruppo selezionato o Unità organizzativa non saranno in grado di disattivare l’accesso per le app meno sicure. Dovrai ripristinare le impostazioni su  Consenti agli utenti di gestire il loro accesso ad app meno sicure  per consentire loro di attivare o disattivare le app meno sicure.

Grazie

  1. Inviare email con allegati (libreria v2.x): Arduino Ethernet
  2. Inviare email con allegati (libreria v2.x): esp32 e esp8266

GitHub library


Spread the love
  •  
  •  
  •  
  • 1
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    1
    Share

Potrebbero interessarti anche...

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *