facebooktwittermenuarrow-up

GemBox Support Forum

How to use IMAP IDLE Mode?

I’m trying out GemBox for a project, and I notice that there are several methods for enabling IDLE mode within the IMAP Client. Once IDLE is enabled, how are the messages actually received? I can’t find any methods for doing that, though I’m probably missing something. I’ve never used IDLE before in any capacity, and I’m pretty new to IMAP in general. Any assistance is appreciated.

Thanks!

Hi Cubemaster,

With IDLE mode you can continuously listen to your mailbox and get triggered when the new email is received or when an older email is deleted.

For example, something like the following:

static class Program
{
    static void Main()
    {
        using (var imap = new ImapClient("<HOST>"))
        {
            imap.Connect();
            imap.Authenticate("<USERNAME>", "<PASSWORD>");
            imap.SelectInbox();
            var messages = GetMessages(imap);

            // Enable IDLE and wait for selected folder message count change
            imap.IdleEnable();
            while (!Console.KeyAvailable)
            {
                if (imap.SelectedFolder.Count < messages.Count)
                {
                    var newMessages = GetMessages(imap);
                    foreach (var key in messages.Keys)
                        if (!newMessages.ContainsKey(key))
                            Console.WriteLine("Message '" + key + "' deleted.");
                    messages = newMessages;
                }
                else if (imap.SelectedFolder.Count > messages.Count)
                {
                    var newMessages = GetMessages(imap);
                    foreach (var key in newMessages.Keys)
                        if (!messages.ContainsKey(key))
                            Console.WriteLine("Message '" + key + "' received.");
                    messages = newMessages;
                }
                Thread.Sleep(100);
            }
            imap.IdleDisable();
        }
    }

    static Dictionary<string, ImapMessageInfo> GetMessages(ImapClient imap)
    {
        var items = new Dictionary<string, ImapMessageInfo>();
        foreach (ImapMessageInfo info in imap.ListMessages())
            items.Add(info.Uid, info);
        return items;
    }
}

Or as an alternative you could perhaps rely on “SEEN” / “UNSEEN” flags of your emails and use something like the following:

static class Program
{
    static void Main()
    {
        using (var imap = new ImapClient("<HOST>"))
        {
            imap.Connect();
            imap.Authenticate("<USERNAME>", "<PASSWORD>");
            imap.SelectInbox();

            using (var listener = new ImapListener(imap))
            {
                listener.NewMessagesDetected += NewMessagesDetected;
                imap.IdleEnable();
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
                imap.IdleDisable();
                listener.NewMessagesDetected -= NewMessagesDetected;
            }
        }
    }

    static void NewMessagesDetected(object sender, ImapListenerEventArgs e)
    {
        // Do something with e.NewMessages ...
    }

    public class ImapListener : IDisposable
    {
        private readonly ImapClient client;
        private bool run;
        private int count;
        private Thread listenerThread;
        public event EventHandler<ImapListenerEventArgs> NewMessagesDetected;

        public ImapListener(ImapClient client)
        {
            this.client = client;
            this.run = true;
            this.listenerThread = new Thread(Listen);
            this.listenerThread.IsBackground = true;
            this.listenerThread.Start();
        }

        private void Listen()
        {
            this.count = this.client.SelectedFolder.Count;
            while (run)
            {
                if (this.client.SelectedFolder.Count > this.count)
                {
                    var uids = this.client.SearchMessageUids("UNSEEN");
                    if (uids.Count > 0)
                        this.NewMessagesDetected?.Invoke(this, new ImapListenerEventArgs(uids.Select(u => this.client.GetMessage(u)).ToArray()));
                }
                this.count = this.client.SelectedFolder.Count;
                Thread.Sleep(100);
            }
        }
        public void Dispose()
        {
            if (this.listenerThread == null)
                return;
            run = false;
            this.listenerThread.Join(5000);
            this.listenerThread = null;
        }
    }

    public class ImapListenerEventArgs : EventArgs
    {
        public IEnumerable<MailMessage> NewMessages { get; }
        public ImapListenerEventArgs(IEnumerable<MailMessage> newMessages)
        {
            this.NewMessages = newMessages;
        }
    }
}

I hope these examples will be of help to you.

Regards,
Mario