### Setup and Send Email with ReadyMail Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md This setup function configures the SSL client, connects to an SMTP server, authenticates, and sends an email. It requires network connectivity and valid SMTP credentials. Ensure time is synchronized for accurate timestamps. ```cpp void setup() { Serial.begin(115200); if (!initModem()) return; ssl_client.setClient(&gsm_client); ssl_client.setInsecure(); // For testing only — use setRootCA() in production ssl_client.setDebugLevel(1); ssl_client.setBufferSizes(1048 /* rx */, 1024 /* tx */); smtp.connect("smtp.example.com", 465); smtp.authenticate("user@example.com", "password", readymail_auth_password); SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "PPP Email"); msg.text.body("Sent via PPPClient + NetworkClientSecure"); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); smtp.send(msg); } void loop() { } ``` -------------------------------- ### Install ESP_SSLClient via PlatformIO Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Install the ESP_SSLClient library using PlatformIO's package manager. Add the dependency to your platformio.ini file. ```ini lib_deps = mobizt/ESP_SSLClient ``` -------------------------------- ### Install ReadyMail via Arduino IDE Library Manager Source: https://github.com/mobizt/readymail/blob/main/README.md Instructions for installing the ReadyMail library using the Arduino IDE's Library Manager. Alternatively, download the ZIP file from releases and add it via Sketch > Include Library > Add .ZIP Library. ```text Download the latest release from: https://github.com/mobizt/ReadyMail/releases Then go to Sketch > Include Library > Add .ZIP Library… ``` -------------------------------- ### Send Email with SMTPClient Source: https://context7.com/mobizt/readymail/llms.txt Example demonstrating how to send an email using the SMTPClient class. This includes connecting to the server, authenticating, building the message with plain text and HTML bodies, and sending the email. Ensure WiFi is connected and time is synchronized. ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #define READYMAIL_DEBUG_PORT Serial #define READYMAIL_TIME_SOURCE time(nullptr) #include WiFiClientSecure ssl_client; SMTPClient smtp(ssl_client); void smtpCb(SMTPStatus status) { if (status.progress.available) ReadyMail.printf("[smtp][%d] Uploading %s, %d%%\n", status.state, status.progress.filename.c_str(), status.progress.value); else ReadyMail.printf("[smtp][%d] %s\n", status.state, status.text.c_str()); if (status.isComplete) { if (status.errorCode < 0) ReadyMail.printf("Error: %d\n", status.errorCode); else ReadyMail.printf("Done, server code: %d\n", status.statusCode); } } void setup() { Serial.begin(115200); WiFi.begin("SSID", "PASSWORD"); while (WiFi.status() != WL_CONNECTED) delay(300); ssl_client.setInsecure(); // or set root CA // Connect (blocking/await mode) smtp.connect("smtp.gmail.com", 465, smtpCb); if (!smtp.isConnected()) return; // Authenticate with password smtp.authenticate("user@gmail.com", "app-password", readymail_auth_password); if (!smtp.isAuthenticated()) return; // Build message SMTPMessage msg; msg.headers.add(rfc822_from, "Sender "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "Hello from ReadyMail"); msg.text.body("Plain text body."); msg.html.body("HTML body."); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); // Send (with optional DSN notification) smtp.send(msg, "SUCCESS,FAILURE,DELAY"); smtp.logout(); smtp.stop(); } void loop() {} ``` -------------------------------- ### Send Email using ReadyMail (SMTP) Source: https://github.com/mobizt/readymail/blob/main/README.md Example demonstrating how to send a plain text and HTML email using the ReadyMail library over SMTP with SSL/TLS. Ensure WiFi is connected and NTP time is synchronized before sending. ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include WiFiClientSecure ssl_client; SMTPClient smtp(ssl_client); void setup() { Serial.begin(115200); WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); while (WiFi.status() != WL_CONNECTED) delay(500); ssl_client.setInsecure(); auto statusCallback = [](SMTPStatus status) { Serial.println(status.text); }; smtp.connect("smtp.example.com", 465, statusCallback); if (smtp.isConnected()) { smtp.authenticate("user@example.com", "password", readymail_auth_password); SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "Hello from ReadyMail"); msg.text.body("This is a plain text message."); msg.html.body("

Hello!

"); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); smtp.send(msg); } } void loop() {} ``` -------------------------------- ### Install ReadyMail via PlatformIO Source: https://github.com/mobizt/readymail/blob/main/README.md Add the ReadyMail library to your platformio.ini file for project dependency management. This method supports ESP32, STM32, RP2040, SAMD, Renesas, and more, but not 8-bit AVR devices. ```ini lib_deps = mobizt/ReadyMail@^0.4.0 ``` -------------------------------- ### STARTTLS IMAP Connection using ESP_SSLClient Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Connect to an IMAP server using STARTTLS on port 143 with ESP_SSLClient. The client starts in plain mode and upgrades to SSL. Use setRootCA() for production. ```cpp IMAPClient imap(ssl_client, startTLSCallback, true /* startTLS */); imap.connect("imap.example.com", 143, statusCallback); ``` -------------------------------- ### IMAP Status Callback Example Source: https://github.com/mobizt/readymail/blob/main/resources/docs/ADVANCED.md Use this callback to get real-time updates on the IMAP operation state and associated text messages. Suitable for tracking IMAP command execution. ```cpp void imapStatusCallback(IMAPStatus status) { ReadyMail.printf("State: %d, %s\n", status.state, status.text.c_str()); } ``` -------------------------------- ### STARTTLS SMTP Connection using ESP_SSLClient Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Connect to an SMTP server using STARTTLS on port 587 with ESP_SSLClient. The client starts in plain mode and upgrades to SSL. Use setRootCA() for production. ```cpp #include #include WiFiClient basic_client; ESP_SSLClient ssl_client; ssl_client.setClient(&basic_client, false); // Start in plain mode ssl_client.setInsecure(); // For testing only — use setRootCA() in production auto startTLSCallback = [](bool &success) { success = ssl_client.connectSSL(); }; SMTPClient smtp(ssl_client, startTLSCallback, true /* startTLS */); smtp.connect("smtp.example.com", 587, statusCallback); ``` -------------------------------- ### ESP32 Setup Function for Ethernet Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Initializes serial communication for debugging. Includes a comment indicating a necessary delay for specific clock modes, which is important for proper Ethernet initialization. ```cpp void setup() { Serial.begin(115200); // This delay is needed in case ETH_CLK_MODE was set to ETH_CLOCK_GPIO0_IN, ``` -------------------------------- ### SMTP Status Callback Example Source: https://github.com/mobizt/readymail/blob/main/resources/docs/ADVANCED.md Implement this callback to receive real-time updates on the SMTP process state, progress, and completion status. Useful for monitoring uploads and handling errors. ```cpp void smtpStatusCallback(SMTPStatus status) { if (status.progress.available) { ReadyMail.printf("State: %d, Uploading file %s, %d%% completed\n", status.state, status.progress.filename.c_str(), status.progress.value); } else { ReadyMail.printf("State: %d, %s\n", status.state, status.text.c_str()); } if (status.isComplete) { if (status.errorCode < 0) { ReadyMail.printf("Process Error: %d\n", status.errorCode); } else { ReadyMail.printf("Server Status: %d\n", status.statusCode); } } } ``` -------------------------------- ### ESP8266 Ethernet Email Setup Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Initializes Ethernet connection using DHCP and configures secure email client. For testing, insecure SSL is used; production requires setRootCA(). ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include #define ETH_CS_PIN 16 // D0 WiFiClientSecure ssl_client; ENC28J60lwIP eth(ETH_CS_PIN); // Wiznet5100lwIP eth(ETH_CS_PIN); // Wiznet5500lwIP eth(ETH_CS_PIN); void setup() { Serial.begin(115200); Serial.print("Connecting to Ethernet... "); if (!ethInitDHCP(eth)) { Serial.println("no hardware found!"); while (1) { delay(1000); } } while (!eth.connected()) { Serial.printf("."); delay(500); } ssl_client.setInsecure(); // For testing only — use setRootCA() in production smtp.connect("smtp.example.com", 465); smtp.authenticate("user@example.com", "password", readymail_auth_password); SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "PPP Email"); msg.text.body("Sent via PPPClient + NetworkClientSecure"); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); smtp.send(msg); } void loop() { } ``` -------------------------------- ### ESP32 Ethernet and SSL Client Setup Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Connects an ESP32 to a W5500 Ethernet module and configures it to send emails via SMTP with SSL/TLS. Ensure the W5500 module is correctly wired to the ESP32 GPIOs. For production, use setRootCA() instead of setInsecure(). ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include #define WIZNET_RESET_PIN 26 // -1 for no reset pin assigned #define WIZNET_CS_PIN 5 #define WIZNET_MISO_PIN 19 #define WIZNET_MOSI_PIN 23 #define WIZNET_SCLK_PIN 18 uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; EthernetClient eth_client; ESP_SSLClient ssl_client SMTPClient smtp(ssl_client); bool connectEthernet() { Serial.println("Resetting Ethernet Board..."); pinMode(WIZNET_RESET_PIN, OUTPUT); digitalWrite(WIZNET_RESET_PIN, HIGH); delay(200); digitalWrite(WIZNET_RESET_PIN, LOW); delay(50); digitalWrite(WIZNET_RESET_PIN, HIGH); delay(200); Serial.println("Starting Ethernet connection..."); Ethernet.begin(Eth_MAC); unsigned long to = millis(); while (Ethernet.linkStatus() != LinkON && millis() - to < 2000) { delay(100); } if (Ethernet.linkStatus() == LinkON) { Serial.print("Connected with IP "); Serial.println(Ethernet.localIP()); return true; } else Serial.println("Can't connected"); return false; } void setup() { Serial.begin(115200); if (!connectEthernet()) return; ssl_client.setClient(ð_client); ssl_client.setInsecure(); // For testing only — use setRootCA() in production ssl_client.setDebugLevel(1); ssl_client.setBufferSizes(1048 /* rx */, 1024 /* tx */); smtp.connect("smtp.example.com", 465); smtp.authenticate("user@example.com", "password", readymail_auth_password); SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "PPP Email"); msg.text.body("Sent via PPPClient + NetworkClientSecure"); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); smtp.send(msg); } void loop() { } ``` -------------------------------- ### SMTPClient::send() — Send Email Message Source: https://context7.com/mobizt/readymail/llms.txt Provides examples for sending a composed SMTPMessage. Demonstrates blocking sends with and without Delivery Status Notifications (DSN), and non-blocking/asynchronous sends. ```cpp // Blocking send with DSN smtp.send(msg, "SUCCESS,FAILURE,DELAY"); // Blocking send without DSN smtp.send(msg); // Non-blocking/async send (call smtp.loop() in loop()) smtp.send(msg, "", false /*await*/); ``` -------------------------------- ### ESP32 PPP Modem Configuration Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Configure PPP modem settings for ESP32, including pins, flow control, and modem model. This example shows hardware flow control for WaveShare SIM7600. ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include #define PPP_MODEM_APN "YourAPN" #define PPP_MODEM_PIN "0000" // or NULL // WaveShare SIM7600 HW Flow Control #define PPP_MODEM_RST 25 #define PPP_MODEM_RST_LOW false // active HIGH #define PPP_MODEM_RST_DELAY 200 #define PPP_MODEM_TX 21 #define PPP_MODEM_RX 22 #define PPP_MODEM_RTS 26 #define PPP_MODEM_CTS 27 #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_HW #define PPP_MODEM_MODEL PPP_MODEM_SIM7600 // LilyGO TTGO T-A7670 development board (ESP32 with SIMCom A7670) // #define PPP_MODEM_RST 5 // #define PPP_MODEM_RST_LOW true // active LOW // #define PPP_MODEM_RST_DELAY 200 // #define PPP_MODEM_TX 26 // #define PPP_MODEM_RX 27 // #define PPP_MODEM_RTS -1 // #define PPP_MODEM_CTS -1 // #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE // #define PPP_MODEM_MODEL PPP_MODEM_SIM7600 // SIM800 basic module with just TX,RX and RST // #define PPP_MODEM_RST 0 // #define PPP_MODEM_RST_LOW true //active LOW // #define PPP_MODEM_TX 2 // #define PPP_MODEM_RX 19 // #define PPP_MODEM_RTS -1 // #define PPP_MODEM_CTS -1 // #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE // #define PPP_MODEM_MODEL PPP_MODEM_SIM800 NetworkClientSecure ssl_client; SMTPClient smtp(ssl_client); void onEvent(arduino_event_id_t event, arduino_event_info_t info) { switch (event) { case ARDUINO_EVENT_PPP_START: Serial.println("PPP Started"); break; case ARDUINO_EVENT_PPP_CONNECTED: Serial.println("PPP Connected"); break; case ARDUINO_EVENT_PPP_GOT_IP: Serial.println("PPP Got IP"); break; case ARDUINO_EVENT_PPP_LOST_IP: Serial.println("PPP Lost IP"); break; case ARDUINO_EVENT_PPP_DISCONNECTED: Serial.println("PPP Disconnected"); break; case ARDUINO_EVENT_PPP_STOP: Serial.println("PPP Stopped"); break; default: break; } } void setup() { Serial.begin(115200); // Resetting the modem #if defined(PPP_MODEM_RST) pinMode(PPP_MODEM_RST, PPP_MODEM_RST_LOW ? OUTPUT_OPEN_DRAIN : OUTPUT); digitalWrite(PPP_MODEM_RST, PPP_MODEM_RST_LOW); delay(100); digitalWrite(PPP_MODEM_RST, !PPP_MODEM_RST_LOW); delay(3000); digitalWrite(PPP_MODEM_RST, PPP_MODEM_RST_LOW); #endif // Listen for modem events Network.onEvent(onEvent); // Configure the modem PPP.setApn(PPP_MODEM_APN); PPP.setPin(PPP_MODEM_PIN); PPP.setResetPin(PPP_MODEM_RST, PPP_MODEM_RST_LOW, PPP_MODEM_RST_DELAY); PPP.setPins(PPP_MODEM_TX, PPP_MODEM_RX, PPP_MODEM_RTS, PPP_MODEM_CTS, PPP_MODEM_FC); Serial.println("Starting the modem. It might take a while!"); PPP.begin(PPP_MODEM_MODEL); Serial.print("Manufacturer: "); Serial.println(PPP.cmd("AT+CGMI", 10000)); Serial.print("Model: "); Serial.println(PPP.moduleName()); Serial.print("IMEI: "); Serial.println(PPP.IMEI()); bool attached = PPP.attached()); if (!attached) { int i = 0; unsigned int s = millis(); Serial.print("Waiting to connect to network"); while (!attached && ((++i) < 600)) { Serial.print("."); delay(100); attached = PPP.attached(); } Serial.print((millis() - s) / 1000.0, 1); Serial.println("s"); attached = PPP.attached(); } Serial.print("Attached: "); Serial.println(attached); Serial.print("State: "); Serial.println(PPP.radioState()); if (attached) { Serial.print("Operator: "); Serial.println(PPP.operatorName()); Serial.print("IMSI: "); Serial.println(PPP.IMSI()); Serial.print("RSSI: "); Serial.println(PPP.RSSI()); int ber = PPP.BER(); if (ber > 0) { Serial.print("BER: "); Serial.println(ber); Serial.print("NetMode: "); Serial.println(PPP.networkMode()); } Serial.println("Switching to data mode..."); PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode if (!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 1000)) { ``` -------------------------------- ### ESP32 Ethernet Initialization with LAN8720 Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Configure Ethernet PHY type, address, and GPIO pins for MDC and MDIO. Set the clock mode, enabling RMII clock output from GPIO17 for modified LAN8720 modules. This setup is crucial for establishing a wired network connection. ```cpp #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include #ifdef ETH_CLK_MODE #undef ETH_CLK_MODE #endif // Type of the Ethernet PHY (LAN8720 or TLK110) #define ETH_PHY_TYPE ETH_PHY_LAN8720 // I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) #define ETH_PHY_ADDR 1 // Pin# of the I²C clock signal for the Ethernet PHY #define ETH_PHY_MDC 23 // Pin# of the I²C IO signal for the Ethernet PHY #define ETH_PHY_MDIO 18 // Pin# of the enable signal for the external crystal oscillator (-1 to disable) #define ETH_PHY_POWER -1 // RMII clock output from GPIO17 (for modified LAN8720 module only) // For LAN8720 built-in, RMII clock input at GPIO 0 from LAN8720 e.g. Olimex ESP32-EVB board // #define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT static bool eth_connected = false; NetworkClientSecure ssl_client; SMTPClient smtp(ssl_client); ``` -------------------------------- ### STM32 Ethernet and SSL Client Setup Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Connects an STM32 to a W5500 Ethernet module and configures it to send emails via SMTP with SSL/TLS, synchronizing time using NTP. Ensure the W5500 module is correctly wired to the STM32 GPIOs. For production, use setRootCA() instead of setInsecure(). ```cpp #include #include #include #include #include #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include // Ethernet settings byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // NTP client EthernetUDP udp; NTPClient timeClient(udp, "pool.ntp.org", 0, 60000); // GMT+0 // Network and SSL clients EthernetClient eth_client; ESP_SSLClient ssl_client; // ReadyMail SMTP client SMTPClient smtp(ssl_client); void setup() { Serial.begin(115200); // Initialize Ethernet Ethernet.begin(mac); delay(1000); // Sync time via NTP timeClient.begin(); timeClient.update(); time_t now = timeClient.getEpochTime(); struct timeval tv = { now, 0 }; settimeofday(&tv, nullptr); Serial.print("Synced time: "); Serial.println(ctime(&now)); // Configure SSL client ssl_client.setClient(ð_client); ssl_client.setInsecure(); // For testing only — use setRootCA() in production // Connect to SMTP server smtp.connect("smtp.example.com", 465); smtp.authenticate("user@example.com", "password", readymail_auth_password); // Compose and send email SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "STM32 Ethernet Email"); msg.text.body("Sent from STM32 + W5500 + ESP_SSLClient with NTP time"); msg.timestamp = time(nullptr); smtp.send(msg); } void loop() { // Optional: update time periodically timeClient.update(); } ``` -------------------------------- ### ESP32 PPP NetworkClientSecure Email Sending Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md This snippet demonstrates sending an email using ESP32 with PPP and NetworkClientSecure. It includes network connection, SSL client setup, SMTP authentication, and message construction. Note: `ssl_client.setInsecure()` is for testing only; use `setRootCA()` in production. ```cpp Serial.println("Failed to connect to internet!"); } else { Serial.println("Connected to internet!"); } } else { Serial.println("Failed to connect to network!"); } ssl_client.setInsecure(); // For testing only — use setRootCA() in production smtp.connect("smtp.example.com", 465); smtp.authenticate("user@example.com", "password", readymail_auth_password); SMTPMessage msg; msg.headers.add(rfc822_from, "ReadyMail "); msg.headers.add(rfc822_to, "Recipient "); msg.headers.add(rfc822_subject, "PPP Email"); msg.text.body("Sent via PPPClient + NetworkClientSecure"); configTime(0, 0, "pool.ntp.org"); while (time(nullptr) < 100000) delay(100); msg.timestamp = time(nullptr); smtp.send(msg); } void loop() { } ``` -------------------------------- ### Connect and Fetch Emails using IMAP Source: https://github.com/mobizt/readymail/blob/main/README.md Demonstrates how to connect to an IMAP server using SSL, authenticate, select a mailbox, and fetch email envelopes. Ensure WiFi is connected and SSL client is configured. ```cpp #include #include #include #define ENABLE_IMAP #define ENABLE_DEBUG #include WiFiClientSecure ssl_client; IMAPClient imap(ssl_client); void setup() { Serial.begin(115200); WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); while (WiFi.status() != WL_CONNECTED) delay(500); ssl_client.setInsecure(); auto statusCallback = [](IMAPStatus status) { Serial.println(status.text); }; auto dataCallback = [](IMAPCallbackData data) { if (data.event() == imap_data_event_fetch_envelope) { for (int i = 0; i < data.headerCount(); i++) { Serial.printf("%s: %s\n", data.getHeader(i).first.c_str(), data.getHeader(i).second.c_str()); } } }; imap.connect("imap.example.com", 993, statusCallback); if (imap.isConnected()) { imap.authenticate("user@example.com", "password", readymail_auth_password); imap.select("INBOX"); imap.fetch(imap.getMailbox().msgCount, dataCallback); } } void loop() {} ``` -------------------------------- ### Dynamic Port Switching with ReadyClient Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Configure ReadyClient for dynamic port switching and establish an SMTP connection. Ensure the ReadyClient is properly initialized before use. ```cpp ReadyClient client; client.setProtocol(readymail_protocol_smtp); client.setPort(587); client.setStartTLS(true); client.setClient(&basic_client); client.setInsecure(); SMTPClient smtp(client); smtp.connect("smtp.example.com", 587, statusCallback); ``` -------------------------------- ### ReadyClient - Auto Port/Protocol Selection Source: https://context7.com/mobizt/readymail/llms.txt ReadyClient automatically selects SSL, STARTTLS, or plain text protocols based on the port used during connection. Register ports with their corresponding protocol using `addPort()`. ```cpp #define ENABLE_SMTP #define READYCLIENT_SSL_CLIENT ESP_SSLClient #define READYCLIENT_TYPE_1 #include #include WiFiClient basic_client; ESP_SSLClient ssl_client; ReadyClient rClient(ssl_client); SMTPClient smtp(rClient); void setup() { ssl_client.setClient(&basic_client); ssl_client.setInsecure(); // Register ports with their protocol rClient.addPort(465, readymail_protocol_ssl); // SSL rClient.addPort(587, readymail_protocol_tls); // STARTTLS rClient.addPort(25, readymail_protocol_plain_text); // Plain // Connect via SSL on port 465 — protocol auto-selected smtp.connect("smtp.example.com", 465, smtpCb); smtp.authenticate("user@example.com", "password", readymail_auth_password); // ...send... smtp.stop(); // Reconnect via STARTTLS on port 587 smtp.connect("smtp.example.com", 587, smtpCb); smtp.authenticate("user@example.com", "password", readymail_auth_password); // ...send... smtp.stop(); } ``` -------------------------------- ### SMTPClient::connect() Server Connection Options Source: https://context7.com/mobizt/readymail/llms.txt Demonstrates various ways to connect to an SMTP server using `SMTPClient::connect()`. It covers SSL, STARTTLS, and asynchronous connection modes. For STARTTLS, a TLS callback is required. For async mode, `smtp.loop()` must be called in the main loop. ```cpp // SSL connection (blocking) smtp.connect("smtp.example.com", 465, smtpCb); ``` ```cpp // STARTTLS connection — requires TLS-capable client and setStartTLS() auto tlsCb = [](bool &success) { success = ssl_client.startTLS(); }; smtp.setStartTLS(tlsCb, true); smtp.connect("smtp.example.com", 587, smtpCb, false /*ssl*/); ``` ```cpp // Async / non-blocking smtp.connect("smtp.example.com", 465, smtpCb, true /*ssl*/, false /*await*/); // In loop(): // smtp.loop(); ``` -------------------------------- ### ReadyClient — Auto Port/Protocol Selection Source: https://context7.com/mobizt/readymail/llms.txt The `ReadyClient` class simplifies SMTP connections by automatically selecting the correct protocol (SSL, STARTTLS, or plain text) based on the port number. It wraps a compatible SSL client. ```APIDOC ## ReadyClient — Auto Port/Protocol Selection `ReadyClient` wraps a compatible SSL client (ESP_SSLClient or NetworkClientSecure) and automatically selects the correct protocol (SSL / STARTTLS / plain) based on the port used at connect time. ```cpp #define ENABLE_SMTP #define READYCLIENT_SSL_CLIENT ESP_SSLClient #define READYCLIENT_TYPE_1 #include #include WiFiClient basic_client; ESP_SSLClient ssl_client; ReadyClient rClient(ssl_client); SMTPClient smtp(rClient); void setup() { ssl_client.setClient(&basic_client); ssl_client.setInsecure(); // Register ports with their protocol rClient.addPort(465, readymail_protocol_ssl); // SSL rClient.addPort(587, readymail_protocol_tls); // STARTTLS rClient.addPort(25, readymail_protocol_plain_text); // Plain // Connect via SSL on port 465 — protocol auto-selected smtp.connect("smtp.example.com", 465, smtpCb); smtp.authenticate("user@example.com", "password", readymail_auth_password); // ...send... smtp.stop(); // Reconnect via STARTTLS on port 587 smtp.connect("smtp.example.com", 587, smtpCb); smtp.authenticate("user@example.com", "password", readymail_auth_password); // ...send... smtp.stop(); } ``` ``` -------------------------------- ### ReadyMail Global Helper Utilities Source: https://context7.com/mobizt/readymail/llms.txt Provides utility functions for debugging, encoding, and date formatting. Use ReadyMail.printf for debug output, ReadyMail.getDateTimeString for date formatting, ReadyMail.base64Encode for Base64 encoding, and ReadyMail.plainSASLEncode for PLAIN SASL authentication strings. ```cpp // Printf to debug port (default: Serial) ReadyMail.printf("State: %d, Text: %s\n", status.state, status.text.c_str()); // Format a UNIX timestamp to RFC 2822 date string String date = ReadyMail.getDateTimeString(time(nullptr), "%a, %d %b %Y %H:%M:%S %z"); // Example output: "Mon, 28 Apr 2025 14:30:00 +0000" // Base64 encode a string String encoded = ReadyMail.base64Encode("Hello World"); // Output: "SGVsbG8gV29ybGQ=" // Build PLAIN SASL encoded credential string (for custom auth) String sasl = ReadyMail.plainSASLEncode("user@example.com", "password"); ``` -------------------------------- ### Configure ESP_SSLClient Buffer Sizes Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Allows manual configuration of RX/TX buffer sizes for ESP_SSLClient. Ideal for boards with limited RAM or when sending large data. ```cpp ssl_client.setBufferSizes(2048, 1024); // RX = 2KB, TX = 1KB ``` -------------------------------- ### IMAPClient: Connect and Authenticate Source: https://context7.com/mobizt/readymail/llms.txt Connects to an IMAP server using SSL/TLS, authenticates with provided credentials, and lists mailboxes. Ensure WiFi is connected and credentials are correct. ```cpp #include #include #include #define ENABLE_IMAP #define ENABLE_DEBUG #define READYMAIL_DEBUG_PORT Serial #include WiFiClientSecure ssl_client; IMAPClient imap(ssl_client); void imapCb(IMAPStatus status) { ReadyMail.printf("[imap][%d] %s\n", status.state, status.text.c_str()); } void setup() { Serial.begin(115200); WiFi.begin("SSID", "PASSWORD"); while (WiFi.status() != WL_CONNECTED) delay(300); ssl_client.setInsecure(); imap.connect("imap.gmail.com", 993, imapCb); if (!imap.isConnected()) return; imap.authenticate("user@gmail.com", "app-password", readymail_auth_password); if (!imap.isAuthenticated()) return; // List all mailboxes imap.list(); for (size_t i = 0; i < imap.mailboxes.size(); i++) ReadyMail.printf("Attrs: %s Delim: %s Name: %s\n", imap.mailboxes[i][0].c_str(), imap.mailboxes[i][1].c_str(), imap.mailboxes[i][2].c_str()); // Select INBOX in read-only mode imap.select("INBOX", true /*readOnly*/); // Mailbox info MailboxInfo mb = imap.getMailbox(); ReadyMail.printf("Messages: %d, Next UID: %d, Unseen: %d\n", mb.msgCount, mb.nextUID, mb.UnseenIndex); } void loop() {} ``` -------------------------------- ### ESP32 Ethernet Event Handling Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Handles various Ethernet events such as starting, connecting, obtaining an IP address, and disconnecting. This function is essential for managing the network state and providing feedback through serial output. It configures the hostname and logs connection details. ```cpp void WiFiEvent(WiFiEvent_t event) { // Do not run any function here to prevent stack overflow or nested interrupt #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) switch (event) { case ARDUINO_EVENT_ETH_START: Serial.println("ETH Started"); // set eth hostname here ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: Serial.println("ETH Connected"); break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); eth_connected = true; break; case ARDUINO_EVENT_ETH_DISCONNECTED: Serial.println("ETH Disconnected"); eth_connected = false; break; case ARDUINO_EVENT_ETH_STOP: Serial.println("ETH Stopped"); eth_connected = false; break; default: break; } #else switch (event) { case SYSTEM_EVENT_ETH_START: Serial.println("ETH Started"); // set eth hostname here ETH.setHostname("esp32-ethernet"); break; case SYSTEM_EVENT_ETH_CONNECTED: Serial.println("ETH Connected"); break; case SYSTEM_EVENT_ETH_GOT_IP: Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); eth_connected = true; break; case SYSTEM_EVENT_ETH_DISCONNECTED: Serial.println("ETH Disconnected"); eth_connected = false; break; case SYSTEM_EVENT_ETH_STOP: Serial.println("ETH Stopped"); eth_connected = false; break; default: break; } #endif } ``` -------------------------------- ### Initialize ESP32 and TinyGsmClient Modem Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md This function initializes the serial communication, resets the modem, and connects to the cellular network. It configures network mode and waits for a stable connection. Ensure correct UART pins and baud rate are defined. ```cpp #define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions // For network independent usage (disable all network features). // #define DISABLE_NERWORKS // Set serial for debug console (to the Serial Monitor, default speed 115200) #define SerialMon Serial // Set serial for AT commands (to the module) // Use Hardware Serial on Mega, Leonardo, Micro #define SerialAT Serial1 // See all AT commands, if wanted // #define DUMP_AT_COMMANDS // Define the serial console for debug prints, if needed #define TINY_GSM_DEBUG SerialMon #define TINY_GSM_USE_GPRS true #define TINY_GSM_USE_WIFI false // set GSM PIN, if any #define GSM_PIN "" // Your GPRS credentials, if any const char apn[] = "YourAPN"; const char gprsUser[] = ""; const char gprsPass[] = ""; #define UART_BAUD 115200 // LilyGO TTGO T-A7670 development board (ESP32 with SIMCom A7670) #define SIM_MODEM_RST 5 #define SIM_MODEM_RST_LOW true // active LOW #define SIM_MODEM_RST_DELAY 200 #define SIM_MODEM_TX 26 #define SIM_MODEM_RX 27 #include // https://github.com/vshymanskyy/TinyGSM #include #include #define ENABLE_SMTP #define ENABLE_DEBUG #include TinyGsm modem(SerialAT); TinyGsmClient gsm_client(modem, 0) ESP_SSLClient ssl_client; SMTPClient smtp(ssl_client); bool initModem() { SerialMon.begin(115200); delay(10); // Resetting the modem #if defined(SIM_MODEM_RST) pinMode(SIM_MODEM_RST, SIM_MODEM_RST_LOW ? OUTPUT_OPEN_DRAIN : OUTPUT); digitalWrite(SIM_MODEM_RST, SIM_MODEM_RST_LOW); delay(100); digitalWrite(SIM_MODEM_RST, !SIM_MODEM_RST_LOW); delay(3000); digitalWrite(SIM_MODEM_RST, SIM_MODEM_RST_LOW); #endif DBG("Wait..."); delay(3000); SerialAT.begin(UART_BAUD, SERIAL_8N1, SIM_MODEM_RX, SIM_MODEM_TX); DBG("Initializing modem..."); if (!modem.init()) { DBG("Failed to restart modem, delaying 10s and retrying"); return false; } /** * 2 Automatic * 13 GSM Only * 14 WCDMA Only * 38 LTE Only */ modem.setNetworkMode(38); if (modem.waitResponse(10000L) != 1) { DBG(" setNetworkMode faill"); return false; } String name = modem.getModemName(); DBG("Modem Name:", name); String modemInfo = modem.getModemInfo(); DBG("Modem Info:", modemInfo); SerialMon.print("Waiting for network..."); if (!modem.waitForNetwork()) { SerialMon.println(" fail"); delay(10000); return false; } SerialMon.println(" success"); if (modem.isNetworkConnected()) SerialMon.println("Network connected"); return true; } ``` -------------------------------- ### STARTTLS SMTP Connection using ESP32 WiFiClientSecure Source: https://github.com/mobizt/readymail/blob/main/resources/docs/CONNECTION_GUIDE.md Connect to an SMTP server using STARTTLS on port 587 with ESP32's WiFiClientSecure. The client is configured to initiate a TLS upgrade. Use setRootCA() for production. ```cpp #include WiFiClientSecure ssl_client; ssl_client.setInsecure(); // For testing only — use setRootCA() in production ssl_client.setPlainStart(); auto startTLSCallback = [](bool &success) { success = ssl_client.startTLS(); }; SMTPClient smtp(ssl_client, startTLSCallback, true /* startTLS */); smtp.connect("smtp.example.com", 587, statusCallback); ``` -------------------------------- ### ReadyMail FileCallback for Filesystem Integration Source: https://context7.com/mobizt/readymail/llms.txt Implement FileCallback to bridge ReadyMail file operations with Arduino filesystem APIs like SPIFFS, LittleFS, or SD. Ensure the file handle is passed back to the library. ```cpp #define ENABLE_FS #include #include // or LittleFS, SD #include File myFile; void fileCb(File &file, const char *filename, readymail_file_operating_mode mode) { switch (mode) { case readymail_file_mode_open_read: myFile = SPIFFS.open(filename, FILE_OPEN_MODE_READ); break; case readymail_file_mode_open_write: myFile = SPIFFS.open(filename, FILE_OPEN_MODE_WRITE); break; case readymail_file_mode_open_append: myFile = SPIFFS.open(filename, FILE_OPEN_MODE_APPEND); break; case readymail_file_mode_remove: SPIFFS.remove(filename); break; } file = myFile; // Required: pass file handle back to library } // Use in attachment: Attachment att; att.filename = "data.csv"; att.mime = "text/csv"; att.attach_file.path = "/data.csv"; att.attach_file.callback = fileCb; msg.attachments.add(att, attach_type_attachment); // Use in message body from file: msg.text.body("/message.txt", fileCb); // Use in IMAP fetch download (pass to fetch/fetchUID): imap.fetch(msgNum, dataCb, fileCb, true, 5*1024*1024, "/downloads"); ``` -------------------------------- ### Enable ReadyMail Features Source: https://context7.com/mobizt/readymail/llms.txt Define these preprocessor directives before including the ReadyMail library to enable specific features like SMTP, IMAP, filesystem support, and debugging. Customize the debug port and time source as needed. ```cpp #define ENABLE_SMTP // Enable SMTPClient and SMTPMessage classes #define ENABLE_IMAP // Enable IMAPClient class #define ENABLE_FS // Enable filesystem (SPIFFS/LittleFS/SD) support #define ENABLE_DEBUG // Enable debug output #define READYMAIL_DEBUG_PORT Serial // Debug output port (default: Serial) #define READYMAIL_TIME_SOURCE time(nullptr) // Time source for message timestamps #define READYMAIL_NO_GLOBAL_INSTANCE // Suppress global ReadyMail instance (multi-.cpp builds) ``` -------------------------------- ### ReadyMail TLSHandshakeCallback for STARTTLS Upgrade Source: https://context7.com/mobizt/readymail/llms.txt Provide a TLSHandshakeCallback to perform the SSL handshake after a STARTTLS command for connections requiring manual protocol upgrade. This is typically used with WiFiClientSecure. ```cpp #include #include WiFiClientSecure ssl_client; // Callback performs the TLS upgrade auto tlsCb = [](bool &success) { success = ssl_client.startTLS(); // ESP32 v3.x NetworkClientSecure }; SMTPClient smtp(ssl_client, tlsCb, true /*startTLS*/); smtp.connect("smtp.example.com", 587, smtpCb, false /*ssl*/); // Or set after construction: smtp.setStartTLS(tlsCb, true); smtp.connect("smtp.example.com", 587, smtpCb, false); ``` -------------------------------- ### ReadyMail Global Helper Source: https://context7.com/mobizt/readymail/llms.txt Provides utility functions for printf-style debugging, base64 encoding, SASL encoding, and date formatting. ```APIDOC ## ReadyMail Global Helper - Utilities ### Description The global `ReadyMail` object (of type `ReadyMailClass`) provides printf-style debug output, base64 encoding, PLAIN SASL encoding, and date formatting. ### Methods - **printf(format, ...)**: Prints formatted output to the debug port. - **getDateTimeString(timestamp, format)**: Formats a UNIX timestamp to a RFC 2822 date string. - **base64Encode(string)**: Base64 encodes a given string. - **plainSASLEncode(username, password)**: Builds a PLAIN SASL encoded credential string. ### Usage Examples ```cpp // Printf to debug port (default: Serial) ReadyMail.printf("State: %d, Text: %s\n", status.state, status.text.c_str()); // Format a UNIX timestamp to RFC 2822 date string String date = ReadyMail.getDateTimeString(time(nullptr), "%a, %d %b %Y %H:%M:%S %z"); // Example output: "Mon, 28 Apr 2025 14:30:00 +0000" // Base64 encode a string String encoded = ReadyMail.base64Encode("Hello World"); // Output: "SGVsbG8gV29ybGQ=" // Build PLAIN SASL encoded credential string (for custom auth) String sasl = ReadyMail.plainSASLEncode("user@example.com", "password"); ``` ```