Second Life of a Hungarian SharePoint Geek

January 13, 2010

Creating a simple email receiver for a document library

Filed under: Incoming email, SharePoint — Tags: , — Peter Holpar @ 17:58

Creating an email receiver is not an over-documented area of SharePoint development, although it may be very useful when one needs to provide a custom collaboration solution or mail integration, so I decided to share some of my experiences on this field. Before creating the receiver, it is important to configure the incoming mail feature on your system. There are several excellent documents on the web that describe how to set up SharePoint 2007 for incoming mails. I usually use the following white papers to configure this feature:

How to configure Email Enabled Lists in Moss2007 RTM using Exchange 2003
How to configure Email Enabled Lists in Moss2007 RTM using Exchange 2007

The class of the event receiver should be derived from the SPEmailEventReceiver class and override the EmailReceived method. This method has three parameters. The first parameter is an SPList, it is the list instance the event receiver is registered for. The second parameter is an SPEmailMessage, it contains the data related to the incoming email, and is the most important parameter for us. The last parameter is a String, that is the value of the Data property specified for the event receiver in the related SPEventReceiverDefinition instance.

The Headers property of the SPEmailMessage contains several interesting mail properties. This collection is populated based on the headers of the raw message. A few of the headers are directly mapped to SPEmailMessage properties, like the Sender property is mapped to the From header.

If you have to know what headers the message has you can test that by including the following code snippet in the receiver method. Don’t forget to include a using directive for the System.Diagnostics namespace. You should know that the types of the headers may vary by the mail type, for example, an invitation may contain extra headers.

  1. foreach (SPEmailHeader header in emailMessage.Headers)
  2. {
  3.     Trace.TraceInformation("EmailReceived emailMessage header {0}, {1}", header.Name, header.Value);
  4. }

We will test our receiver on a standard document library. Let’s create the From, To, Subject, Body and Sent fields as illustrated on the following picture.

image

In the code, we will get the binary content of the mail first and store it into the list. We create the file name based on the mail subject, overwriting possible former files having the same name. It means that if you expecting multiple mails with the same subject – that is very likely – you should extend this logic a bit, for example, by including the date of the mail or some kind of numbering.

Next, we set the From, To, Subject, Body and Sent properties for the list item using the mail properties.

  1. public class MailProcessor : SPEmailEventReceiver
  2. {
  3.     public override void EmailReceived(SPList list, SPEmailMessage emailMessage, string receiverData)
  4.     {
  5.         try
  6.         {
  7.             SPFolder folder = list.RootFolder;
  8.             String folderUrl = folder.Url;
  9.             String url = String.Format(@"{0}/{1}.eml", folderUrl, emailMessage.Headers["Subject"]);
  10.  
  11.             byte[] binaryContent = null;
  12.             String mailContent = String.Empty;
  13.  
  14.             using (Stream stream = emailMessage.GetMessageStream())
  15.             {
  16.                 using (StreamReader sr = new StreamReader(stream))
  17.                 {
  18.                     mailContent = sr.ReadToEnd();
  19.                     sr.Close();
  20.                 }
  21.  
  22.                 binaryContent = Encoding.UTF8.GetBytes(mailContent);
  23.                 stream.Close();
  24.             }
  25.  
  26.             // we overwrite previous files with the same name
  27.             SPFile file = folder.Files.Add(url, binaryContent, true);
  28.  
  29.             SPItem item = file.Item;
  30.             item["From"] = emailMessage.Sender;
  31.             item["To"] = emailMessage.Headers["To"];
  32.             item["Subject"] = emailMessage.Headers["Subject"];
  33.             item["Body"] = emailMessage.PlainTextBody;
  34.             item["Sent"] = DateTime.Parse(emailMessage.Headers["Date"]);
  35.             item.Update();
  36.             list.Update();
  37.  
  38.         }
  39.         catch(Exception ex)
  40.         {
  41.             Trace.TraceInformation("MailProcessor exception: {0}", ex.Message);
  42.         }
  43.  
  44.     }
  45. }

The following step is to build the project and to register the receiver. If you need info about the registration, you can find several methods of that on Brian Wilson’s blog:

Registering Event Handlers plus Site Settings – Manage Event Handlers

Personally, I use the Event Handler Explorer most of the time.

Let’s test the receiver by sending a few mails to the mail address specified for the document library.

image

Be sure that the Windows SharePoint Services Timer service (OWSTIMER.EXE) is running. Also, if you create and deploy a new version of the receiver, restart the service, and attach to this process if you need to debug the receiver.

The picture below illustrates the document library after sending a few mails.

image

Advertisements

3 Comments »

  1. I am getting this error:
    “To add an item to a document library, use SPFileCollection.Add()”
    when I debug this eventreceiver in VS 2010.
    I am working in SP 2010, have created a doc lib and deployed this eventreceiver. I tried attaching it to OWSTimer and got it to break in the code.
    But it gave me the above error at the line sr.Close()
    Is there any specific change that I need to do for 2010.
    Any help is appreciated.
    Thanks.
    Zullu

    Comment by Zullu — November 1, 2010 @ 22:23

    • Hi Zulu,

      I’ve tested it only on MOSS 2007, but that error is a bit strange. We add the file to the folder a few lines below the line sr.Close(), using the SPFileCollection.Add() method, exactly as requested in the error message.

      Peter

      Comment by Peter Holpar — December 2, 2010 @ 22:17

  2. need an help in Visual studio 2010….same code required in VS2010….If any help it will be Appreciatable..Thanks in Advance

    Comment by bobby — April 25, 2013 @ 06:43


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: