How To Check Email Programmatically - SidePOP

Background

Sending email has long been easy to do with the .NET Framework. There really hasn’t been a facility for checking email though. I recently had a need to be able to check email with and send a response with Bombali (a monitoring tool). I went searching for examples or a solution I could use. I found a few articles on this from a few years ago including the .NET POP3 MIME Client.  I never found anything that was free and I never found anything that was easy to configure. Those who know me know I have a tinge of the NIH (not invented here), especially when there are no free alternatives. So I created my own based on the articles I had read. And in the spirit of chucknorris, I named it SidePOP!

Configuration

Configuration for receiving email should be easy. Feast your eyes on all that is required for configuration (and for those of you who dislike XML, it’s not required – you can configure all in code):

<configSections>
  <section name="sidepop" type="sidepop.configuration.SidePOPConfiguration, sidepop"/>
</configSections>

<!-- 110 is normal POP3 SSL uses port 995-->
<sidepop>
  <accounts>
    <add hostName="mail.somewhere" userName="yep" password="" minutesBetweenChecks=".1" />
    <add name="Number1" description="Main account" enabled="true" hostName="mail.somewhere.net" hostPort="110" useSSL="false" userName="" password="" minutesBetweenChecks="1" timeoutInMinutes="1"  />
  </accounts>
</sidepop>

You see there are two items here. The first one has the required items in it. The second one is the entire set of items to configure.  Notice that we are asking for a password in plaintext. This is where you might think about encrypting this section somehow.

Code Setup

Configuring SidePOP to run is a little more verbose that I might like right now. Looking below you see that it’s still not that much code. I hope to set up a facility to automatically look at the configuration file and configure SidePOP (for those that like XML). If someone wants to send me a patch as well, that would be awesome.

private void configure_mail_watcher()
{
    foreach (AccountConfigurationElement account in SidePOPConfiguration.settings.accounts)
    {
        if (account.enabled)
        {
            SidePopRunner runner = new SidePopRunner(new DefaultPop3Client(account.hostName, account.hostPort,
                                     account.useSSL, account.userName,
                                     account.password), account.minutes_between_checks);
            runner.MessagesReceived += runner_messages_received;
            runner.run();
            Log.bound_to(this).Info("{0} is configured to watch for messages with user {1} at {2} every {3} minutes.", ApplicationParameters.name,
                                    account.userName, account.hostName, account.minutes_between_checks);
        }
    }
}

private void runner_messages_received(object sender, MessageListEventArgs e)
{
    IEnumerable<SidePOPMailMessage> messages = e.Messages;

    const string subject = "Bombali Response";
    TimeSpan up_time_current = up_time.Elapsed;
    string text_message = string.Format("{0} has been up and running for {1} days {2} hours {3} minutes and {4} seconds.", ApplicationParameters.name, up_time_current.Days, up_time_current.Hours, up_time_current.Minutes, up_time_current.Seconds);

    foreach (SidePOPMailMessage message in messages)
    {
        Log.bound_to(this).Info("{0} received a message from {1}. Responding that service is still running.",ApplicationParameters.name,message.From.Address);
    
        SendNotification.from(BombaliConfiguration.settings.email_from).to(message.From.Address).with_subject(
        subject).with_message(text_message).and_use_notification_host(BombaliConfiguration.settings.smtp_host);
    }
}

When I start the service, I call the method configure_mail_watcher(). Because I can have multiple accounts I can check with SidePOP, I am going to loop through the settings and check each one to ensure they are enabled. If so, then I am going to set up a SidePopRunner and subscribe to runner_messages_received (this may not work with multiple accounts, I haven’t yet tested that).  Then I kick off the runner for that account.

I could instead subscribe to runner.MessageReceived (instead of runner.MessagesReceived) for getting an event notification for every message instead of batching it up to a list if I desired.

When a message is received, I find out how long the service has been up. I didn’t show it here, but up_time is a System.Diagnostics.Stopwatch. In the constructor I start it. Now I just capture how long it has been up. Then for each message, I send a response to the sender of the email address telling them how long the service has been up. To add more sophistication, I could very easily add a rules engine here to process the message based on a list of rules looking for keywords in the email.

That’s all I need to do. Now I’m up and ready to rock.

What It Looks Like

Here is what it looks like running with Bombali. I send the service a text message. This is what it logs.

2009-12-07 23:59:05,875 5 [INFO ] - Bombali received a message from someone @ somewhere.net. Responding that service is still running.
2009-12-07 23:59:05,875 5 [INFO ] - Sending email to someone @ somewhere.net with subject "Bombali Response" and message:
Bombali has been up and running for 0 days 0 hours 31 minutes and 22 seconds.

This is what I get from my phone.

Bombali has been up and running for 0 days 0 hours 31 minutes and 22 seconds.

Now I know that my service is still up and running with a simple text. All for the low price of a few lines of code and the sidePOP.dll library.

Conclusion

SidePOP gives me a level of sophistication that I didn’t have before. Now that I have access to get email, I could very easily add rules to do different things based on the content of the email received. How often have you wanted your application to check email and just didn’t want to pay the price for the products out there that can do this? Now it’s completely free with SidePOP.

Download SidePOP

NOTE: This is still early. Any part of the configuration could change. Be sure you take a look at the sample app to always have the newest configuration. Register any bugs you find here: http://code.google.com/p/sidepop/issues/list

WARNING: SidePOP will delete your email when it checks it. That’s how it can be sure it’s only dealing with new messages every time. Do not test on an account you care about. You’ve been warned.

SVN here: http://sidepop.googlecode.com/svn/trunk/

Downloads here: http://code.google.com/p/sidepop/downloads/list


Posted 12-08-2009 12:46 AM by Rob Reynolds
Filed under: , ,

[Advertisement]

Comments

Rob Reynolds wrote re: How To Check Email Programmatically - SidePOP
on 12-08-2009 1:47 PM

This has now been updated to be used with a configurator. This looks something like this:

    private void configure_mail_watcher()
    {
           EmailWatcherConfigurator configurator = new SidePopXmlConfigurator();
           foreach (EmailWatcher emailWatcher in configurator.configure())
           {
               emailWatcher.MessagesReceived += runner_messages_received;
               emailWatcher.start();
           }
      }

I will get a post up to show it soon.

Rob Reynolds - The Fervent Coder wrote Lessons In Building An Email Parser
on 12-18-2009 4:19 AM

The Classic Infinite Email Loop When building an email parser, one must think about validating an email

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)