Click here to Skip to main content
Click here to Skip to main content

EWS Mail Notifier

, 19 Apr 2010
Rate this:
Please Sign up or sign in to vote.
Simple mail notifier for Exchange

Introduction

Recently I have been working on a project that consists of a real-time new mails notifier for Exchange 2010. To do this, I have used the Exchange Web Services API, and web server skeleton of our friend Rodolfo Ortega also available on CodeProject.

Requirements

How This Works?

The program creates a push subscription through EWS API, and then, I use the web server skeleton to listen to the SOAP messages that will send me Exchange. To deserialize the Exchange's notifications contained in the SOAP message, I needed to generate the class from Exchange's schema files, and then, I used WSE 3.0 to deserialize the SOAP message.

Generating Classes

To generate the class for deserialize Exchange's notifications, we will use "messages.xsd" and "types.xsd" schema files, located in the EWS directory of our server:

xsd /c /language:CS /namespace:EWSConsoleNotify messages.xsd types.xsd 

Deserializing Exchange SOAP Message

To deserialize the SOAP message sent by Exchange and received through our web server skeleton, we will use WSE to deserialize it by passing the XML message to the serializer:

SoapEnvelope soapEnvelope = new SoapEnvelope();
                   
soapEnvelope.InnerXml = Body;
           
Type type = typeof(SendNotificationResponseType);

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "SendNotification";
xRoot.Namespace = "http://schemas.microsoft.com/exchange/services/2006/messages";
XmlSerializer serializer = new XmlSerializer(type, xRoot);
XmlNodeReader reader = new XmlNodeReader(soapEnvelope.Body.FirstChild);

SendNotificationResponseType obj = 
	(SendNotificationResponseType)serializer.Deserialize(reader);

Processing Exchange Notifications

Once we have our deserialized message, this method processes all notifications contained in the SOAP message sent by Exchange. Note that inside of the buckle, I check for new mail events only, because Exchange also send me "Status" messages:

    public SendNotificationResultType ProcessNotification
		(SendNotificationResponseType SendNotification)
    {          
        SendNotificationResultType result = 
		new SendNotificationResultType(); // Notification's result
        bool unsubscribe = false; 
        ResponseMessageType[] responseMessages = 
		SendNotification.ResponseMessages.Items; // Response messages
        foreach (ResponseMessageType responseMessage in responseMessages)
        {
            if (responseMessage.ResponseCode != ResponseCodeType.NoError)
            {
                
                result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
                return result;
            }
            NotificationType notification = 
		((SendNotificationResponseMessageType)responseMessage).Notification;
            string subscriptionId = notification.SubscriptionId;
          
            // If subscription Id is not the current subscription Id, unsubscribe
            if (subscriptionId != _parent.SubscriptionId)
            {
                unsubscribe = true;
            }
            else
            {
                for (int c = 0; c < notification.Items.Length; c++)
                {
                    // Get only new mail events
                    if (notification.ItemsElementName[c].ToString() == "NewMailEvent")
                    {
                        BaseObjectChangedEventType bocet = 
			(BaseObjectChangedEventType)notification.Items[c];
                        _parent.ShowMessage(((ItemIdType)bocet.Item).Id);
                    }
                }
            }           
        }
        if (unsubscribe)
        {
            result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
        }
        else
        {
            result.SubscriptionStatus = SubscriptionStatusType.OK;
        }
        return result;
    }
}        

Creating the Subscription for Push Notifications using EWS API

This method creates the push subscription, and starts the thread with our web server skeleton for listening to the incoming connections:

public void Start()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(
        Object obj,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors errors)
    {
        return true;
        // TODO: check for a valid certificate
    };
    
    // Create the subscription
    _service = new ExchangeService();
    // Set credentials: user, password and domain
    _service.Credentials = new WebCredentials("user", "password", "domain");
    // URL of the EWS
    _service.Url = new Uri("https://exchange_server/ews/exchange.asmx");
    
    PushSubscription ps = 
      _service.SubscribeToPushNotificationsOnAllFolders(new Uri("http://your_IP:5050"),
        5 // Every 5 minutes Exchange will send us a status message
        , null, EventType.NewMail);
        
    SubscriptionId = ps.Id;
    
    // Listen on port 5050
    _listener = new TcpListener(5050);
    _listener.Start();
    
    _th = new Thread(new ThreadStart(ProcessIncomingMessages));
    _th.Start();
    
    WriteLog("Listening for incoming messages...");
}

Showing the New Mail Received

To show the new mail received, we need to bind to the item Id sent in the notification:

public void ShowMessage(string UniqueId)
{
    EmailMessage mail = ((EmailMessage)Item.Bind(_service, new ItemId(UniqueId)));

    Console.WriteLine("New mail from: {0}, Subject: {1}", mail.From.Name, mail.Subject);
}

Screenshot

screenshot.jpg

Remarks

This sample has been tested on Exchange 2010, I don't know if it will work on previous versions. Probably would be made using WCF, but in the tests that I have made, it did not work for me, for these reasons I have used the Rodolfo's web server skeleton to listen to SOAP messages sent by Exchange.

I hope this sample will help you. Wink | ;-)

Recommended Links

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

avg360
Software Developer
Spain Spain
MCTS: .NET Framework 3.5 ASP.NET Applications

Comments and Discussions

 
GeneralBeware of memory leaks Pinmemberthomashove31-Mar-11 23:18 
AnswerRe: Beware of memory leaks Pinmemberavg3603-Apr-11 21:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 19 Apr 2010
Article Copyright 2010 by avg360
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid