Fail to read IMAP subject content

I use Wemos D1 mini (ESP8266). My application is required to access Gmail IMAP server and identifies the unread emails and then read these emails subject and check their content. I have tried several examples taken from ESP_Mail_Client library but always with same results. No problems encountered in accessing the email account but never got the right result for the unread emails (Unseen) as well as the emails subject content. Any ideas?

No, you missed a very important point: you failed to post your code!
How should we know what you did wrong without seeing your code?

1 Like

Sorry to miss this. Here one of the example I am using. The link for the original example appears in the first line. Just want to explain what I need from this example.
First, I use Wemos D1 mini without external memory and SD.
Second, my mail box contain only three emails where 2 are unread. Body text contains about 10 text words.
Third, I am looking for the unread emails subject lines at first stage and then to check the text int each subject line. If the text match to a predefined text, then open the specific email and read it body. There might be more than onematching email. afterwards, delete the matcg email from server.
Fourth, I removed my personal detail from this example. no problem is aceessing my wifi as well as Gmail server.
Fifth, call function (line 66) MailClient.readMail(&imap) casung memory dump and the enter into reset cycle on and on.


```cpp


// an example taken from github: https://github.com/mobizt/ESP-Mail-Client#sdfat-conflicts-in-esp8266-and-must-be-removed
// Include WiFi library
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP_Mail_Client.h>

// Declare the global used IMAPSession object for IMAP transport
IMAPSession imap;

// Declare the global used Session_Config for user defined session credentials
Session_Config config;


void setup()
{
  Serial.begin(115200);
  WiFi.begin("My_SSID", "My_password");

  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  // Set the session config
  config.server.host_name = "imap.gmail.com";
  config.server.port = 993; // for SSL or 143 for Plain or TLS with STARTTLS
  config.login.email = "My_Email";
  config.login.password = "application_password";

  // Declare the IMAP_Data object used for user defined IMAP operating options 
  // and contains the IMAP operating result
  IMAP_Data imap_data;

  
  // Set to enable the message content which will be stored in the IMAP_Data data
  imap_data.enable.html = true;
  imap_data.enable.text = true;


  // Connect to the server
  imap.connect(&config, &imap_data);

  // Open or select the mailbox folder to read the message
  imap.selectFolder("INBOX");


  // Define the message UID (number) which required to fetch or read the message
  // In this case we will get the UID from the max message number (lastest message)
  // then imap.getUID and imap.selectedFolder().msgCount() should be called after 
  // calling select or open the folder (mailbox).
  imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount());

  // Empty search criteria to disable the messsage search
  imap_data.search.criteria.clear();


  // Read the Email and close the session
  MailClient.readMail(&imap);


  // Get the message(s) list
  IMAP_MSG_List msgList = imap.data();

  // ESP_MAIL_PRINTF used in the examples is for format printing via debug Serial port
  // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266.
  // In ESP32 and ESP32, you can use Serial.printf directly.

  for (size_t i = 0; i < msgList.msgItems.size(); i++)
  {
    // Iterate to get each message data through the message item data
    IMAP_MSG_Item msg = msgList.msgItems[i];

    Serial.println("################################");
    ESP_MAIL_PRINTF("Messsage Number: %s\n", msg.msgNo);
    ESP_MAIL_PRINTF("Messsage UID: %s\n", msg.UID);
    ESP_MAIL_PRINTF("Messsage ID: %s\n", msg.ID);
    ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);
    ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);
    ESP_MAIL_PRINTF("From: %s\n", msg.from);
    ESP_MAIL_PRINTF("From Charset: %s\n", msg.fromCharset);
    ESP_MAIL_PRINTF("To: %s\n", msg.to);
    ESP_MAIL_PRINTF("To Charset: %s\n", msg.toCharset);
    ESP_MAIL_PRINTF("CC: %s\n", msg.cc);
    ESP_MAIL_PRINTF("CC Charset: %s\n", msg.ccCharset);
    ESP_MAIL_PRINTF("Date: %s\n", msg.date);
    ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);
    Serial.print("Subject: %s\n ");
    Serial.println(msg.subject);
    ESP_MAIL_PRINTF("Subject Charset: %s\n", msg.subjectCharset);

    // If the message body is available
    if (!imap.headerOnly())
    {
      ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);
      ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);
      ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);
      ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);
      ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);
      ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);
    }
  }

}
void loop()
{

}


You do not check if the connection was established nor if the authentication was successful.

You should also limit the amount of data to be loaded, otherwise you quickly get memory problems, even if you think that there aren't any more mails on the server. The available memory of an ESP8266 is less than 50kB and with your configuration every bit downloaded has to stored in RAM.

Check for error for every method you call!

tnx pylon. The connection is established. This is one of the examples I am trying (part of the email library). Some of them contain lot of debug options' hence I can see clearly the connection to both - wifi and IMAP server establishment. All examples ending with same results. I minimized my code to the exapmles solely to reduce memory resources. I understand that there is major memory issue and that is the reason why I am looking just for the subject lines. is there any idea I can perform this task and 'survive'?

Set both to false.

Set imap_data.enable_header to true (the subject is part of the header).

The rest of the default values should be OK, I hope.

Thanks. I found that I have used quite old examples . Due to Mobizt rcommendation I tried the updated Read_Single_Email_Loop example, which set these two parameters to true, and all of a sudden it started to work. Now I am struggling with my requirements based on the working code.

The example in your post is for fetching (reading) a latest message (with latest UID) in your mailbox instead of unread message.
imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount());

If you want to get the unread messages in your mailbox, you have to search your mailbox first to get the message sequence numbers or UIDs of the unread messages in the search result.

The search result will contain only headers, its UID and sequence number of messages.

Then you can read or fetch each message content (body) later using its UID or sequence number.

Please see this example and use imap_data.search.criteria = "SEARCH NEW";

thank you so much for your detailed answer. Just to remind you, I use at the moment Wemos D1 board, and it seems that your Read_Single_Email_loop is running nicely including my
modifications. I am still struggling to reduce memory resources. I tried to follow your recent recommendation for imap_data.search.criteria but haven't seen any change. I also searched for a specific sunbject content but haven't seen any change. The inbox contain only two unread emails. Message body contains very few letters and digits, about 10 bytes. I don't understand why I am geyting in the serial consule Unseen Message Index: 0.
Here is my modified code based on your example:

/**
 * This example Read_Single_Email_Loop, shows how to read Email repeatedly.
 * Created by K. Suwatchai (Mobizt)
 *
 * Github: https://github.com/mobizt/ESP-Mail-Client
  */

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP_Mail_Client.h>

// Provide the SD card interfaces setting and mounting
#include <extras/SDHelper.h>

#define WIFI_SSID "my-net24"
#define WIFI_PASSWORD "my-pass"

/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */
#define IMAP_HOST "imap.gmail.com"

/** The imap port e.g.
 * 143  or esp_mail_imap_port_143
 * 993 or esp_mail_imap_port_993
 */
#define IMAP_PORT 993

/* The log in credentials */
#define AUTHOR_EMAIL "abc@gmail.com"
#define AUTHOR_PASSWORD "abcdefgef123"

/* Callback function to get the Email reading status */
void imapCallback(IMAP_Status status);

/* Print the list of mailbox folders */
void printAllMailboxesInfo(IMAPSession &imap);

/* Print the selected folder info */
void printSelectedMailboxInfo(SelectedFolderInfo sFolder);

/* Print all messages from the message list */
void printMessages(MB_VECTOR<IMAP_MSG_Item> &msgItems, bool headerOnly);

/* Print all attachments info from the message */
void printAttacements(MB_VECTOR<IMAP_Attach_Item> &atts);

/* Declare the global used IMAPSession object for IMAP transport */
IMAPSession imap;

unsigned long readMillis = 0;
int totalMessage = 0;
int msgNum = 0;
int sign = -1;

/* Declare the global used Session_Config for user defined session credentials */
Session_Config config;

/** Declare the global used IMAP_Data object used for user defined IMAP operating options
 * and contains the IMAP operating result
 */
IMAP_Data imap_data;

// For Free Heap checking
#include "HeapStat.h"
HeapStat heapInfo;

void setup()
{

    Serial.begin(115200);
    Serial.println();

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting to Wi-Fi");
    unsigned long ms = millis();
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    /*  Set the network reconnection option */
    MailClient.networkReconnect(true);

    /** Enable the debug via Serial port: 0 for no debugging, 1 for basic level debugging   */
    imap.debug(0);

    /* Set the callback function to get the reading results */
    imap.callback(imapCallback);

    /* Set the session config */
    config.server.host_name = IMAP_HOST;
    config.server.port = IMAP_PORT;
    config.login.email = AUTHOR_EMAIL;
    config.login.password = AUTHOR_PASSWORD;

    /* Message UID to fetch or read */
    imap_data.fetch.uid.clear();

    /* Search criteria */
    imap_data.search.criteria.clear();

    imap_data.search.criteria = F("SUBJECT dudi@hotmail.com");

    /* Also search the unseen message */
    imap_data.search.unseen_msg = true;

    /* Set the storage to save the downloaded files and attachments */
    imap_data.storage.saved_path = F("/email_data");

    /** The file storage type e.g.
     * esp_mail_file_storage_type_none,
     * esp_mail_file_storage_type_flash, and
     * esp_mail_file_storage_type_sd
     */
    imap_data.storage.type = esp_mail_file_storage_type_none;

    /** Set to download heades, text and html messaeges,
     * attachments and inline images respectively.
     */
    imap_data.download.header = false;
    imap_data.download.text = false;
    imap_data.download.html = false;
    imap_data.download.attachment = false;
    imap_data.download.inlineImg = false;

    /** Set to enable the results i.e. html and text messaeges     */
    imap_data.enable.html = false;
    imap_data.enable.text = true;

    /* Set to enable the sort the result by message UID in the decending order */
    imap_data.enable.recent_sort = true;

    /* Set to report the download progress via the default serial port */
//-->    imap_data.enable.download_status = true;
    imap_data.enable.download_status = false;

    /* Set the limit of number of messages in the search results */
    imap_data.limit.search = 10;

    /** Set the maximum size of message stored in
     * IMAPSession object in byte
     */
    imap_data.limit.msg_size = 512;

    /** Set the maximum attachments and inline images files size     */
    imap_data.limit.attachment_size = 0;

    /* Connect to the server */
    if (!imap.connect(&config, &imap_data))
        return;

    if (!imap.isLoggedIn())
    {
        Serial.println("\nNot yet logged in.");
    }
    else
    {
        if (imap.isAuthenticated())
            Serial.println("\nSuccessfully logged in.");
        else
            Serial.println("\nConnected with no Auth.");
    }

    /*  {Optional} */
    printAllMailboxesInfo(imap);

    /* Open or select the mailbox folder to read or search the message */
    if (!imap.selectFolder(F("INBOX")))
        return;

    /*  {Optional} */
    printSelectedMailboxInfo(imap.selectedFolder());

    totalMessage = imap.selectedFolder().msgCount();
    Serial.print(F("[dudi] totalMessage: "));
    Serial.println(totalMessage);
    
    /* Start fetch from last message */
    msgNum = totalMessage;
    sign = -1; // count down

    /* To start fetch from first message */
    // msgNum = 1;
    // sign = 1;// count up
    long readMillis = 0;
}

void loop()
{
    if (millis() - readMillis > 30000 || readMillis == 0)
    {
        readMillis = millis();

        // If session was closed, reconnect and re-select the mailbox
        if (!imap.connected())
        {
            if (!imap.connect(&config, &imap_data))
                return;

            if (!imap.selectFolder(F("INBOX")))
                return;

            if (totalMessage == 0)
            {
                totalMessage = imap.selectedFolder().msgCount();
                msgNum = totalMessage;
                sign = -1;
            }
        }

        if (msgNum <= 0)
        {
            msgNum = 1;
            sign = 1;
        }
        else if (msgNum >= totalMessage)
        {
            msgNum = totalMessage;
            sign = -1;
        }

        /* Message number to fetch or read */
        imap_data.fetch.number = msgNum;

        /* Set seen flag */
        // imap_data.fetch.set_seen = true;

        // When message was fetched or read, the /Seen flag will not set
        MailClient.readMail(&imap, false);
        /* Clear all stored data in IMAPSession object */
        imap.empty();

        msgNum += sign;
    }
}

/* Callback function to get the Email reading status */
void imapCallback(IMAP_Status status)
{
    /* Print the current status */
    Serial.println(status.info());

    /* Show the result when reading finished */
    if (status.success())
    {
        /* Print the result */
        /* Get the message list from the message list data */
        IMAP_MSG_List msgList = imap.data();
        printMessages(msgList.msgItems, imap.headerOnly());

        /* Clear all stored data in IMAPSession object */
        imap.empty();

        // Collect memory info
        heapInfo.collect();

        // Print memory info
        heapInfo.print();
    }
}

void printAllMailboxesInfo(IMAPSession &imap)
{
    /* Declare the folder collection class to get the list of mailbox folders */
    FoldersCollection folders;

    /* Get the mailbox folders */
    if (imap.getFolders(folders))
    {
        for (size_t i = 0; i < folders.size(); i++)
        {
            /* Iterate each folder info using the  folder info item data */
            FolderInfo folderInfo = folders.info(i);
            ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : "");
        }
    }
}

void printSelectedMailboxInfo(SelectedFolderInfo sFolder)
{
    /* Show the mailbox info */
    ESP_MAIL_PRINTF("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount());
    ESP_MAIL_PRINTF("UID Validity: %d\n", sFolder.uidValidity());
    ESP_MAIL_PRINTF("Predicted next UID: %d\n", sFolder.nextUID());
    ESP_MAIL_PRINTF("Unseen Message Index: %d\n", sFolder.unseenIndex());
    if (sFolder.modSeqSupported())
        ESP_MAIL_PRINTF("Highest Modification Sequence: %d\n", sFolder.highestModSeq());
    for (size_t i = 0; i < sFolder.flagCount(); i++)
        ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : "");

    if (sFolder.flagCount(true))
    {
        for (size_t i = 0; i < sFolder.flagCount(true); i++)
            ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : "");
    }
}

void printAttacements(MB_VECTOR<IMAP_Attach_Item> &atts)
{
    ESP_MAIL_PRINTF("Attachment: %d file(s)\n****************************\n", atts.size());
    for (size_t j = 0; j < atts.size(); j++)
    {
        IMAP_Attach_Item att = atts[j];
        /** att.type can be
         * esp_mail_att_type_none or 0
         * esp_mail_att_type_attachment or 1
         * esp_mail_att_type_inline or 2
         */
        ESP_MAIL_PRINTF("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate);
    }
    Serial.println();
}

void printMessages(MB_VECTOR<IMAP_MSG_Item> &msgItems, bool headerOnly)
{
    /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and
     * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename
     * (> 13 characters) is not support in the SD.h library.
     * To show how its original file name, use imap.fileList().
     */
    // Serial.println(imap.fileList());

    for (size_t i = 0; i < msgItems.size(); i++)
    {

        /* Iterate to get each message data through the message item data */
        IMAP_MSG_Item msg = msgItems[i];

        Serial.println("****************************");
        ESP_MAIL_PRINTF("Number: %d\n", msg.msgNo);
        ESP_MAIL_PRINTF("UID: %d\n", msg.UID);
        ESP_MAIL_PRINTF("Messsage-ID: %s\n", msg.ID);

        ESP_MAIL_PRINTF("Flags: %s\n", msg.flags);

        // The attachment status in search may be true in case the "multipart/mixed"
        // content type header was set with no real attachtment included.
        ESP_MAIL_PRINTF("Attachment: %s\n", msg.hasAttachment ? "yes" : "no");

        if (strlen(msg.acceptLang))
            ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);
        if (strlen(msg.contentLang))
            ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);
        if (strlen(msg.from))
            ESP_MAIL_PRINTF("From: %s\n", msg.from);
        if (strlen(msg.sender))
            ESP_MAIL_PRINTF("Sender: %s\n", msg.sender);
        if (strlen(msg.to))
            ESP_MAIL_PRINTF("To: %s\n", msg.to);
        if (strlen(msg.cc))
            ESP_MAIL_PRINTF("CC: %s\n", msg.cc);
        if (strlen(msg.date))
        {
            ESP_MAIL_PRINTF("Date: %s\n", msg.date);
            ESP_MAIL_PRINTF("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date));
        }
        if (strlen(msg.subject))
            ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);
        if (strlen(msg.reply_to))
            ESP_MAIL_PRINTF("Reply-To: %s\n", msg.reply_to);
        if (strlen(msg.return_path))
            ESP_MAIL_PRINTF("Return-Path: %s\n", msg.return_path);
        if (strlen(msg.in_reply_to))
            ESP_MAIL_PRINTF("In-Reply-To: %s\n", msg.in_reply_to);
        if (strlen(msg.references))
            ESP_MAIL_PRINTF("References: %s\n", msg.references);
        if (strlen(msg.comments))
            ESP_MAIL_PRINTF("Comments: %s\n", msg.comments);
        if (strlen(msg.keywords))
            ESP_MAIL_PRINTF("Keywords: %s\n", msg.keywords);

        /* If the result contains the message info (Fetch mode) */
        if (!headerOnly)
        {
            if (strlen(msg.text.content))
                ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);
            if (strlen(msg.text.charSet))
                ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);
            if (strlen(msg.text.transfer_encoding))
                ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);
//            if (strlen(msg.html.content))
//                ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);
//            if (strlen(msg.html.charSet))
//                ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);
//            if (strlen(msg.html.transfer_encoding))
//                ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);

            if (msg.rfc822.size() > 0)
            {
                ESP_MAIL_PRINTF("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size());
                printMessages(msg.rfc822, headerOnly);
            }

            if (msg.attachments.size() > 0)
                printAttacements(msg.attachments);
        }

        Serial.println();
    }
}

Because the message at index 0 wasn't read yet.

Can you post a complete output?

imap_data.enable.text = true;

That still enables downloading of the complete message. How many emails do you have that are already seen?

If you want to see the subjects you have to get the headers:

imap_data.download.header = false;

imap_data.search.criteria = F("SUBJECT dudi@hotmail.com");

Does that match at least one mail in your inbox?

As pylon said, you should share all debug messages.

Did you read this comment? Did you get it?

Please increase the size until you get enough data from message body.

You should read all comments in the examples carefully and do not ignore any comment in the examples.

You should open the Email app on your PC or phone and try to set any message as unread (remove \Seen flag) and you will see different from "NEW" or "UNSEEN" search result.

Note that, not all keywords in search criteria are supported by all mail servers which it depends on server implementation, and you should try it yourself.

If mail server (IMAP) does not recognize your search criteria, there is no result returned (empty message list) or returns the bad command or argument error.

Here is the available search keywords that you can try.

@dudi

This example will make you clearly understand.


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

#include <ESP_Mail_Client.h>

#define WIFI_SSID "<ssid>"
#define WIFI_PASSWORD "<password>"

#define IMAP_HOST "<host>"

#define IMAP_PORT esp_mail_imap_port_993

#define AUTHOR_EMAIL "<email>"
#define AUTHOR_PASSWORD "<password>"

void imapCallback(IMAP_Status status);

void printMessageData();

IMAPSession imap;

// Max messages in the search result
int max_result = 3;

// Array to store the UID of messages in search result
int msg_uid[3];

void setup()
{

    Serial.begin(115200);

    Serial.println();

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    Serial.print("Connecting to Wi-Fi");

    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    MailClient.networkReconnect(true);

    imap.debug(1);

    imap.callback(imapCallback);

    Session_Config config;

    config.server.host_name = IMAP_HOST;
    config.server.port = IMAP_PORT;
    config.login.email = AUTHOR_EMAIL;
    config.login.password = AUTHOR_PASSWORD;

    IMAP_Data imap_data;

    imap_data.fetch.uid.clear();

    imap_data.search.unseen_msg = true;

    // Don't download all to filesystem
    imap_data.download.header = false;
    imap_data.download.text = false;
    imap_data.download.html = false;
    imap_data.download.attachment = false;
    imap_data.download.inlineImg = false;

    // Store html/text message body in IMAPSession object
    imap_data.enable.html = true;
    imap_data.enable.text = true;

    imap_data.enable.recent_sort = true;

    // Max messages in the search result
    imap_data.limit.search = max_result;

    imap_data.limit.msg_size = 2048;

    imap_data.limit.attachment_size = 1024 * 1024 * 5;

    if (!imap.connect(&config, &imap_data))
        return;

    if (!imap.selectFolder(F("INBOX")))
        return;

    // We search the unseen messages first to get its UID and stored in msg_uid.
    imap_data.search.criteria = F("SEARCH NEW"); // or "SEARCH RECENT"
    MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */);

    // We already get the search result message, fetch it

    // Fetch the messages using UID stored in msg_uid one by one
    for (int i = 0; i < max_result; i++)
    {
        imap_data.search.criteria.clear();

        // Now Fech message by UID stored in msg_uid
        imap_data.fetch.uid = msg_uid[i];
        MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */);
    }

    imap.closeSession();
    imap.empty();
}

void loop()
{
}

void imapCallback(IMAP_Status status)
{
    Serial.println(status.info());

    if (status.success())
    {
        // If this is the search result (imap contains only header info),
        // store the message UID that we can fetch for its body later.
        if (imap.headerOnly())
        {
            int matches_count = 0;
            for (size_t i = 0; i < imap.data().msgItems.size(); i++)
            {
                // You can compare the message subject with text you want from
                // imap.data().msgItems[i].subject before storing its UID in msg_uid

                msg_uid[i] = imap.data().msgItems[i].UID;
                matches_count++;
            }

            max_result = matches_count;
        }
        else
        {
            // This is the fetch result, print the whole message (header + body)
            printMessageData();
        }

        imap.empty();
    }
}

void printMessageData()
{

    IMAP_MSG_Item msg = imap.data().msgItems[0]; // msgItems contains only one message from fetch

    Serial.println("****************************");

    ESP_MAIL_PRINTF("Number: %d\n", msg.msgNo);
    ESP_MAIL_PRINTF("UID: %d\n", msg.UID);
    ESP_MAIL_PRINTF("Messsage-ID: %s\n", msg.ID);
    ESP_MAIL_PRINTF("Flags: %s\n", msg.flags);

    ESP_MAIL_PRINTF("Attachment: %s\n", msg.hasAttachment ? "yes" : "no");

    if (strlen(msg.acceptLang))
        ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);
    if (strlen(msg.contentLang))
        ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);
    if (strlen(msg.from))
        ESP_MAIL_PRINTF("From: %s\n", msg.from);
    if (strlen(msg.sender))
        ESP_MAIL_PRINTF("Sender: %s\n", msg.sender);
    if (strlen(msg.to))
        ESP_MAIL_PRINTF("To: %s\n", msg.to);
    if (strlen(msg.cc))
        ESP_MAIL_PRINTF("CC: %s\n", msg.cc);
    if (strlen(msg.date))
    {
        ESP_MAIL_PRINTF("Date: %s\n", msg.date);
        ESP_MAIL_PRINTF("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date));
    }
    if (strlen(msg.subject))
        ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);
    if (strlen(msg.reply_to))
        ESP_MAIL_PRINTF("Reply-To: %s\n", msg.reply_to);
    if (strlen(msg.return_path))
        ESP_MAIL_PRINTF("Return-Path: %s\n", msg.return_path);
    if (strlen(msg.in_reply_to))
        ESP_MAIL_PRINTF("In-Reply-To: %s\n", msg.in_reply_to);
    if (strlen(msg.references))
        ESP_MAIL_PRINTF("References: %s\n", msg.references);
    if (strlen(msg.comments))
        ESP_MAIL_PRINTF("Comments: %s\n", msg.comments);
    if (strlen(msg.keywords))
        ESP_MAIL_PRINTF("Keywords: %s\n", msg.keywords);

    if (strlen(msg.text.content))
        ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);
    if (strlen(msg.text.charSet))
        ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);
    if (strlen(msg.text.transfer_encoding))
        ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);
    if (strlen(msg.html.content))
        ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);
    if (strlen(msg.html.charSet))
        ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);
    if (strlen(msg.html.transfer_encoding))
        ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);

    Serial.println();
}

Hey pylon,

Sorry for the delay. Here is my consule monitor prontout. It is quite furstrating this outpur copying. I noticed that many user already raised this frustrating issue in othe form cathegory. To hid e personal information I replaced the real aithor name with dummy value. Anyway, here is the monitor output:
Connecting to Wi-Fi..............

Connected with IP: 192.168.1.32

Connecting to IMAP server...

IMAP server connected

Checking the capability...

Logging in...

Send client identification...

Successfully logged in.

Reading the list of mailboxes...

Available folders: INBOX, [Gmail], [Gmail]/&BdAF6QXkBdQ-, [Gmail]/&BdMF1QXQBeg- &BdkF1QXmBdA-, [Gmail]/&BdcF6QXVBdE-, [Gmail]/&BdgF2QXVBdgF1QXq-, [Gmail]/&BdsF3A- &BdQF0wXVBdAF6A-, [Gmail]/&Bd4F4QXVBd4F3w- &BdEF2wXVBdsF0Q-, [Gmail]/&BeEF5AXQBd0-

Open the mailbox folder...

Info of the selected folder

Total Messages: 2

UID Validity: 1

Predicted next UID: 138

Unseen Message Index: 0

Highest Modification Sequence: 20071

Flags: \Answered, \Flagged, \Draft, \Deleted, \Seen, $NotPhishing, $Phishing

[dudi] totalMessage: 2

Fetch message 1, Number: 2

Get Flags...

Reading messages...

Finished reading Email


Number: 2

UID: 137

Messsage-ID: DB9PR02MB6747AB1EC4C035FEC45AF4E4C05EA@DB9PR02MB6747.eurprd02.prod.outlook.com

Flags:

Attachment: no

Accept Language: en-US

Content Language: en-US

From: abc@gmail.com <abc@gmail.com>

To: "abc@gmail.com" <abc@gmail.com>

Date: Sun, 18 Jun 2023 15:10:34 +0000

Timestamp: 1687101034

Subject: 1234

Return-Path: <abc@gmail.com>

Text Message: abcdefg

Text Message Charset: iso-8859-1

Text Message Transfer Encoding: quoted-printable

Heap Info

Current: 31768, Min: 31768, Max: 31768, Diff_1: 0, Diff_1: 0

Fetch message 2, Number: 1

Get Flags...

Reading messages...

Finished reading Email


Number: 1

UID: 136

Messsage-ID: DB9PR02MB6747755DBE751188C1BBAC07C05EA@DB9PR02MB6747.eurprd02.prod.outlook.com

Flags:

Attachment: no

Accept Language: en-US

Content Language: en-US

From: Dudi ardudi@hotmail.com

To: " abc@gmail.com" <abc@gmail.com>

Date: Sun, 18 Jun 2023 15:05:35 +0000

Timestamp: 1687100735

Subject: ardudi@gmail.com

Return-Path: ardudi@hotmail.com

Text Message: E1;L8;D5

Text Message Charset: iso-8859-1

Text Message Transfer Encoding: quoted-printable

Heap Info

Current: 31264, Min: 31264, Max: 31768, Diff_1: -504, Diff_2: -504

That looks promising! It read the first message completely but fails at the second one. Did you check what part of the ESP flash is already used? You tell the library to store the message content in flash so It might be a problem in that part.

It might be a mistske of mine. You know, I had to copy and paste in pieces the serial monitor content. I'll re-capture serial monitor later today. Just remember that I want first to read just an unread message subject line ad to find a match to a specific text pattern. So far, it dowloads a complete message details and the unseen flag shows zero. In my case the email Inbox contains only 2 short emails both are unread...w

It there any option to reduce the information that downloded from the Inbox? For my iot device, I only need to know the from, subjectline, unread indication, message body, and perhaps the date fields. e

Hey pylon,
Returned now to the email code. See below the updated srial output. Want to remind that there are only 2 unread emails in my Inbox. As you may see below, they are very short. Just to summatize what is my wishlist related to this eample:

  1. to get details of the unread email
  2. to read the sunbject lines of each of unread emails and
    look for a match between a subject line to a pre-defined text
  3. if a match, read email content and then remove it from the email server.
  4. in order to save as much as memory possible, I want to control each each type of header to download. for example, I am not interested ay 'Accept Language', 'Content Language', 'Timestamp', 'Return-Path', etc...
    Connecting to Wi-Fi..............
    Connected with IP: 192.168.1.32

Connecting to IMAP server...

IMAP server connected

Checking the capability...

Logging in...

Send client identification...

Successfully logged in.

Reading the list of mailboxes...

Available folders: INBOX, [Gmail], [Gmail]/&BdAF6QXkBdQ-, [Gmail]/&BdMF1QXQBeg- &BdkF1QXmBdA-, [Gmail]/&BdcF6QXVBdE-, [Gmail]/&BdgF2QXVBdgF1QXq-, [Gmail]/&BdsF3A- &BdQF0wXVBdAF6A-, [Gmail]/&Bd4F4QXVBd4F3w- &BdEF2wXVBdsF0Q-, [Gmail]/&BeEF5AXQBd0-

Open the mailbox folder...

Info of the selected folder
Total Messages: 2
UID Validity: 1
Predicted next UID: 138
Unseen Message Index: 0
Highest Modification Sequence: 20165
Flags: \Answered, \Flagged, \Draft, \Deleted, \Seen, $NotPhishing, $Phishing
[dudi] totalMessage: 2

Fetch message 1, Number: 2

Get Flags...

Finished reading Email


Number: 2
UID: 137
Messsage-ID: DB9PR02MB6747AB1EC4C035FEC45AF4E4C05EA@DB9PR02MB6747.eurprd02.prod.outlook.com
Flags:
Attachment: no
Accept Language: en-US
Content Language: en-US
From: Dudi ardudi@hotmail.com
To: "abc@gmail.com" abc@gmail.com
Date: Sun, 18 Jun 2023 15:10:34 +0000
Timestamp: 1687101034
Subject: 1234
Return-Path: ardudi@hotmail.com

Heap Info

Current: 31768, Min: 31768, Max: 31768, Diff_1: 0, Diff_1: 0

Fetch message 2, Number: 1

Get Flags...

Reading messages...

Finished reading Email


Number: 1
UID: 136
Messsage-ID: DB9PR02MB6747755DBE751188C1BBAC07C05EA@DB9PR02MB6747.eurprd02.prod.outlook.com
Flags:
Attachment: no
Accept Language: en-US
Content Language: en-US
From:abc@gmail.com abc@gmail.com
To: "abc@gmail.com" abc@gmail.com
Date: Sun, 18 Jun 2023 15:05:35 +0000
Timestamp: 1687100735
Subject: ardudi@gmail.com
Return-Path: ardudi@hotmail.com
Text Message: E1;L8;D5

Text Message Charset: iso-8859-1
Text Message Transfer Encoding: quoted-printable

Heap Info

Current: 31264, Min: 31264, Max: 31768, Diff_1: -504, Diff_2: -504

Fetch message 3, Number: 1

Get Flags...

Reading messages...

Finished reading Email


This looks promising. Post the complete code you used for this. The debug output of the library shows that you get all information you need, you just have to call the correct methods to get to that information.

Hello fellow developers,

I've been working on setting up an IMAP email client on my ESP32 using the ESP_Mail_Client.h library. However, I've encountered a specific issue that I'd like to discuss and hopefully get some guidance on.

The Problem: When attempting to connect to the IMAP server, the library encounters a timeout during the authentication process. The error message in the debug output indicates "response read timed out," leading to a connection closure.

Here's a snippet of the debug output:

Connecting to Wi-Fi...

Connected with IP: 192.168.1.207

#### Connecting to IMAP server...

> C: ESP Mail Client v3.3.7

> C: connecting to IMAP server

> C: Host > imap.ukr.net

> C: Port > 993

> C: Free internal heap before TLS 209772

> C: Starting socket

> C: SSL/TLS negotiation

> C: seeding the random number generator

> C: setting up the SSL/TLS structure

! W: Skipping SSL Verification. INSECURE!

> C: setting hostname for TLS session

> C: perform the SSL/TLS handshake

> C: verifying peer X.509 certificate

#### IMAP server connected
> C: IMAP server connected

#### Checking the capability...

> C: check the capability

#### Logging in...

> C: send IMAP command, AUTHENTICATE PLAIN

> C: cleaning SSL connection

! E: response read timed out

#### Error, connection closed

! E: connection closed

The code is

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

#include <ESP_Mail_Client.h>

#define WIFI_SSID "ssid"
#define WIFI_PASSWORD "password"

#define IMAP_HOST "imap.ukr.net"

#define IMAP_PORT esp_mail_imap_port_993

#define AUTHOR_EMAIL "mymail@ukr.net"
#define AUTHOR_PASSWORD "mypassword"

void imapCallback(IMAP_Status status);

void printMessageData();

IMAPSession imap;

// Max messages in the search result
int max_result = 3;

// Array to store the UID of messages in search result
int msg_uid[3];

void setup()
{

    Serial.begin(115200);

    Serial.println();

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    Serial.print("Connecting to Wi-Fi");

    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    MailClient.networkReconnect(true);

    imap.debug(1);

    imap.callback(imapCallback);

    Session_Config config;

    config.server.host_name = IMAP_HOST;
    config.server.port = IMAP_PORT;
    config.login.email = AUTHOR_EMAIL;
    config.login.password = AUTHOR_PASSWORD;

    IMAP_Data imap_data;

    imap_data.fetch.uid.clear();

    imap_data.search.unseen_msg = true;

    // Don't download all to filesystem
    imap_data.download.header = false;
    imap_data.download.text = false;
    imap_data.download.html = false;
    imap_data.download.attachment = false;
    imap_data.download.inlineImg = false;

    // Store html/text message body in IMAPSession object
    imap_data.enable.html = true;
    imap_data.enable.text = true;

    imap_data.enable.recent_sort = true;

    // Max messages in the search result
    imap_data.limit.search = max_result;

    imap_data.limit.msg_size = 2048;

    imap_data.limit.attachment_size = 1024 * 1024 * 5;

    if (!imap.connect(&config, &imap_data))
        return;

    if (!imap.selectFolder(F("INBOX")))
        return;

    // We search the unseen messages first to get its UID and stored in msg_uid.
    imap_data.search.criteria = F("SEARCH NEW"); // or "SEARCH RECENT"
    MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */);

    // We already get the search result message, fetch it

    // Fetch the messages using UID stored in msg_uid one by one
    for (int i = 0; i < max_result; i++)
    {
        imap_data.search.criteria.clear();

        // Now Fech message by UID stored in msg_uid
        imap_data.fetch.uid = msg_uid[i];
        MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */);
    }

    imap.closeSession();
    imap.empty();
}

void loop()
{
}

void imapCallback(IMAP_Status status)
{
    Serial.println(status.info());

    if (status.success())
    {
        // If this is the search result (imap contains only header info),
        // store the message UID that we can fetch for its body later.
        if (imap.headerOnly())
        {
            int matches_count = 0;
            for (size_t i = 0; i < imap.data().msgItems.size(); i++)
            {
                // You can compare the message subject with text you want from
                // imap.data().msgItems[i].subject before storing its UID in msg_uid

                msg_uid[i] = imap.data().msgItems[i].UID;
                matches_count++;
            }

            max_result = matches_count;
        }
        else
        {
            // This is the fetch result, print the whole message (header + body)
            printMessageData();
        }

        imap.empty();
    }
}

void printMessageData()
{

    IMAP_MSG_Item msg = imap.data().msgItems[0]; // msgItems contains only one message from fetch

    Serial.println("****************************");

    ESP_MAIL_PRINTF("Number: %d\n", msg.msgNo);
    ESP_MAIL_PRINTF("UID: %d\n", msg.UID);
    ESP_MAIL_PRINTF("Messsage-ID: %s\n", msg.ID);
    ESP_MAIL_PRINTF("Flags: %s\n", msg.flags);

    ESP_MAIL_PRINTF("Attachment: %s\n", msg.hasAttachment ? "yes" : "no");

    if (strlen(msg.acceptLang))
        ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);
    if (strlen(msg.contentLang))
        ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);
    if (strlen(msg.from))
        ESP_MAIL_PRINTF("From: %s\n", msg.from);
    if (strlen(msg.sender))
        ESP_MAIL_PRINTF("Sender: %s\n", msg.sender);
    if (strlen(msg.to))
        ESP_MAIL_PRINTF("To: %s\n", msg.to);
    if (strlen(msg.cc))
        ESP_MAIL_PRINTF("CC: %s\n", msg.cc);
    if (strlen(msg.date))
    {
        ESP_MAIL_PRINTF("Date: %s\n", msg.date);
        ESP_MAIL_PRINTF("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date));
    }
    if (strlen(msg.subject))
        ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);
    if (strlen(msg.reply_to))
        ESP_MAIL_PRINTF("Reply-To: %s\n", msg.reply_to);
    if (strlen(msg.return_path))
        ESP_MAIL_PRINTF("Return-Path: %s\n", msg.return_path);
    if (strlen(msg.in_reply_to))
        ESP_MAIL_PRINTF("In-Reply-To: %s\n", msg.in_reply_to);
    if (strlen(msg.references))
        ESP_MAIL_PRINTF("References: %s\n", msg.references);
    if (strlen(msg.comments))
        ESP_MAIL_PRINTF("Comments: %s\n", msg.comments);
    if (strlen(msg.keywords))
        ESP_MAIL_PRINTF("Keywords: %s\n", msg.keywords);

    if (strlen(msg.text.content))
        ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);
    if (strlen(msg.text.charSet))
        ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);
    if (strlen(msg.text.transfer_encoding))
        ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);
    if (strlen(msg.html.content))
        ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);
    if (strlen(msg.html.charSet))
        ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);
    if (strlen(msg.html.transfer_encoding))
        ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);

    Serial.println();
}

Required settings:

Incoming Mail Server (IMAP): imap.ukr.net.
Port: 993.
Connection: SSL encrypted.
Secure Password Authentication (SPA) is disabled.

Comparative Library: Interestingly, I also tried the ESP32_MailClient.h library, which does work. However, it's not without its issues. While it successfully connects, it sometimes causes my ESP32 to restart unexpectedly.

Possible Causes and Solutions: I've considered that this issue might stem from network connectivity, IMAP server configuration, or compatibility with the ESP_Mail_Client.h library. I've ensured my Wi-Fi credentials are correct and verified the IMAP server settings. The decision to skip SSL verification is marked as "INSECURE," which could contribute to the problem. Additionally, library updates could potentially address this issue.

Request for Assistance: Has anyone else encountered a similar timeout issue with the ESP_Mail_Client.h library during authentication? Any insights into what might be causing this and how to resolve it would be greatly appreciated. Furthermore, if you have any suggestions for stabilizing the ESP32_MailClient.h library to prevent restarts, I'd love to hear them.

Thank you in advance for your help!

So, the author of the library answered me:

Actually, server SHALL reply with NO response to client when it's not accepted AUTHENTICATE.

I will update library based on this worst situation from bad server behavior by redirecting to send LOGIN when server is not responding to AUTHENTICATE command.

I will inform you when update is available.

I recommend using other better Email service provider.

With AUTH=PLAIN capability, server can accept one or all of these authenticate commands i.e. LOGIN and AUTHENTICATE PLAIN.

The current version library preferred to send AUTHENTICATE PLAIN while the old version (v2.x.x), preferred to send LOGIN.

I think this IMAP server accepts only LOGIN command.

This is a fiasco for me :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.