1

I am using MailKit .net library to fetch emails from gmail.

According to Getting only new mail from an IMAP server and IMAP: Search for messages with UID greater than X (or generally, after my last search)

I want to search all emails came after last remembered UID. lets say the last message fetched had a unique id of "123456". I want to search

123456:*

How do I achieve this search in MailKit?

Community
  • 1
  • 1
Kiran Beladiya
  • 441
  • 1
  • 5
  • 11

1 Answers1

8

There are multiple overloads of the Search method on an ImapFolder in MailKit. You'll want to use one of the overloads that take a IList<UniqueId> argument.

Given that, now you'll need to create the list of UIDs to search on. I would recommend taking a look at the UniqueIdRange class in the MailKit namespace.

If the last UID that your client program has seen in a previous session was 123456, you'll actually want your search to start with UID 123457. In IMAP-speak, * is just a wildcard for the "maximum unique id value in the folder". In MailKit, you can just use UniqueId.MaxValue.

var range = new UniqueIdRange (new UniqueId ((uint) 123457), UniqueId.MaxValue);

Now that you have the range 123457:*, you can perform the search:

foreach (var uid in folder.Search (range, query)) {
    var message = folder.GetMessage (uid);
}
jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • What should be there in query in Search (range, query) ? Isn't range itself a query, so why do we need to pass extra param? – Kiran Beladiya Jun 20 '16 at 05:29
  • `range` is not a query itself, it is simply a subset of messages to apply your search query to. If you want all of the messages in that range, then you would use `SearchQuery.All` as your query. – jstedfast Jun 20 '16 at 10:32
  • If I use **SearchQuery.All**, will it retrieve all the UIDs to client from server? and after that, it filters down to range subset (at client side)? My goal is to minimize data transfer. I just need UIDs came after the last UID I processed. This can also be done if I retrieve all UIDs from server and then I ignore the UIDs less then the last one I processed. I thought **folder.Search (range, query)** should be performing full filtering operation(range and query both) at server side. – Kiran Beladiya Jun 21 '16 at 12:28
  • No, the server will only return the IUDs of the messages within the range. Don't believe me? Check the IMAP protocol logs. – jstedfast Jun 21 '16 at 14:59
  • 4
    SearchQuery.All will only match the messages within the specified range as my answer explains. The answer I've given you will produce the absolute minimum traffic possible. Trust me, I know what I'm talking about. – jstedfast Jun 21 '16 at 15:02
  • Hi Folks, I guess this is from long time back but right now when I work the same way I am always getting the last email fetched (in the previous search) if no new emails are in the inbox; basically if I search with range(123457:*), I am still getting the email with uid 123456 if it's the last email in the inbox. Is this supposed to be the correct behavior @jstedfast ? – mlakhara Sep 08 '20 at 17:47