0 votes
by (280 points)
edited

Hi,

I want to extract only recent 10 receipts from my yahoo account. I have different mailbox folders in my yahoo account. So, right now for each of the mailbox folders I am calling imapConnection.Search() method and collecting ImapMessageCollection and after collecting all I am sorting it and then taking top 10 receipts. This process takes some time while crawling accounts having bigger mailbox folders.

Is there something which can directly give me recent 10 receipts? Please suggest asap,

Applies to: Rebex Secure Mail

2 Answers

0 votes
by (70.2k points)
edited

To retrieve recent 10 receipts please use the following code:

// select desired folder
imap.SelectFolder("Inbox");

// retrieve last sequence number and compute appropriate min sequence number
int max = imap.CurrentFolder.TotalMessageCount;
int min = Math.Max(1, max + 1 - 10);

// prepare message set to be retrieved
ImapMessageSet set = new ImapMessageSet();
set.AddRange(min, max);

// retrieve message infos specified by the message set
ImapMessageCollection col = imap.GetMessageList(set, ImapListFields.Envelope);
by (280 points)
edited

But I have multiple mailbox folders and it might be the case that different folders having different mail dates. In that case what should I do?

by (280 points)
edited

Lukas, Please suggest on this. I also want to do this using ImapSearchParameter also because some criteria i am looking for while fetching top 10 emails.

by (70.2k points)
edited

There is no method working with multiple folders. You can work only with the currently selected one. I suggest you to call the above code for each folder, then continue with your current code (collect results together and sort). Please note, the imap.GetMessageList(set) code is faster than imap.Search().

by (70.2k points)
edited

Actually, there is RFC 6237 - IMAP4 Multimailbox SEARCH Extension from May 2011, Category: Experimental.

This is what it says:

The IMAP4 specification allows the searching of only the selected mailbox. A user often wants to search multiple mailboxes, and a client that wishes to support this must issue a series of SELECT and SEARCH commands, waiting for each to complete before moving on to the next.

Rebex Imap for .NET doesn't support this extension. I think yahoo doesn't support it either.

by (280 points)
edited

Ok. But can we apply ImapSearchParameter also on imap.GetMessageList(set, ImapListFields.Envelope); ActuallY I want to fetch only those recent 10 recipts which are matching with criteria?

0 votes
by (70.2k points)
edited

Sorry, I missed you need to apply some search criteria. In this case a little bit optimal code can be used. It is optimal in case the search returns a lot of emails, but you want only recent 10.

// maximal number of recent messages
private const int MaxRecentCount = 10;

private List<ImapMessageInfo> MultiSearch(Imap imap, ImapListFields fields, ImapSearchParameter criteria, params string[] folders)
{
    // search within each folder, but retrieve only UniqueId and ReceivedDate
    List<FolderMessageInfoPair> list = new List<FolderMessageInfoPair>();
    foreach (string folder in folders)
    {
        imap.SelectFolder(folder);
        ImapMessageCollection col = imap.Search(ImapListFields.UniqueId | ImapListFields.ReceivedDate, criteria);
        foreach (ImapMessageInfo info in col)
        {
            list.Add(new FolderMessageInfoPair(folder, info));
        }
    }
    list.Sort();

    // remove unwanted messages
    if (list.Count > MaxRecentCount)
        list.RemoveRange(0, list.Count - MaxRecentCount);

    // get full info of messages we found, each from its folder
    List<ImapMessageInfo> ret = new List<ImapMessageInfo>();
    foreach (string folder in folders)
    {
        bool search = false;
        ImapMessageSet set = new ImapMessageSet();
        foreach (FolderMessageInfoPair pair in list)
        {
            if (pair.Folder == folder)
            {
                search = true;
                set.Add(pair.MessageInfo.UniqueId);
            }
        }
        if (search)
        {
            imap.SelectFolder(folder);
            ImapMessageCollection col = imap.GetMessageList(set, fields);
            ret.AddRange(col);
        }
    }
    return ret;
}

// helper class for MultiSearch method
private class FolderMessageInfoPair : IComparable<FolderMessageInfoPair>
{
    public string Folder { get; private set; }
    public ImapMessageInfo MessageInfo { get; private set; }
    public FolderMessageInfoPair(string folder, ImapMessageInfo messageInfo)
    {
        Folder = folder;
        MessageInfo = messageInfo;
    }

    // compares two instances according to ReceivedDate
    int IComparable<FolderMessageInfoPair>.CompareTo(FolderMessageInfoPair other)
    {
        return MessageInfo.ReceivedDate.UniversalTime.CompareTo(other.MessageInfo.ReceivedDate.UniversalTime);
    }
}

The method can be used as follows:

List<ImapMessageInfo> col = MultiSearch(imap, ImapListFields.Envelope, ImapSearchParameter.All, "Inbox", "folder2", "folder3");
by (280 points)
edited

Thanks. Let me check this.

...