C# - Read emails from exchange online mailbox (Office 365) into SQL Server

months ago by Danny Riebeek

Situation

You have an Office 365 mailbox. You want to use C# to read those mails and save them to SQLServer.

Requirements

  • Office365 mailbox
  • SQLServer
  • Exchange WebServices
  • C# (visual studio)

Exchange WebServices

Applies to: EWS Managed API | Exchange Online | Exchange Server 2013 | Office 365 There is 1 step you need to take and that is to install Exchange Webservices (MIT License). Download EWS Managed API via nuget. This step is very easy and does not require more then download/install via a nuget package. This only has to be done on your Development Machine. Once you want to release your product for production release all you need to include is the Microsoft.Exchange.WebServices.dll and you're all set.

Implemented Solution

using System;
using Microsoft.Exchange.WebServices.Data;
using System.Data.SqlClient;

namespace ReadOffice365Mailbox
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeService _service;

            try
            {
                Console.WriteLine("Registering Exchange connection");

                _service = new ExchangeService
                {
                    Credentials = new WebCredentials("yourmailbox@email.com", "*******")
                };
            }
            catch
            {
                Console.WriteLine("new ExchangeService failed. Press enter to exit:");
                return;
            }

            // This is the office365 webservice URL
            _service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

            // Prepare seperate class for writing email to the database
            try
            {
                Write2DB db = new Write2DB();

                Console.WriteLine("Reading mail");

                // Read 100 mails
                foreach (EmailMessage email in _service.FindItems(WellKnownFolderName.Inbox, new ItemView(100)))
                {
                    db.Save(email);

                }

                Console.WriteLine("Exiting");
            }
            catch (Exception e)
            {
                Console.WriteLine("An error has occured. \n:" + e.Message);
            }
        }
    }
}
 
...
using Microsoft.Exchange.WebServices.Data;
...

namespace ReadOffice365Mailbox
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeService _service;
            _service = new ExchangeService
                {
                    Credentials = new WebCredentials("yourmailbox@email.com", "*******")
                };
...
Instantiate a new ExchangeService and provide your mailbox credentials.
            // This is the official office365 webservice URL
            _service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

            // Read 100 mails
            foreach (EmailMessage email in _service.FindItems(WellKnownFolderName.Inbox, new ItemView(100)))

...
Then, because you want to call an Webservice (ExchangeWebService EWS) you provide the webservice URL and you call the function FindItems( , ). This call will connect to your mailbox (if you've provided the correct credentials) and start reading (in this case 100 mail headers) After that you can read all the basic email properties like subject, from and to. Microsoft has implemented a lightweight EWS so that if you want to read more properties like Htmlbody or TextBody, you have to send an instruction to load that extra information with the following command:
           
       // Read 100 mails
       foreach (EmailMessage email in _service.FindItems(WellKnownFolderName.Inbox, new ItemView(100)))
       {
            email.Load(new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.TextBody));

            // Then you can retrieve extra information like this:
            string recipients = "";

            foreach (EmailAddress emailAddress in email.CcRecipients)
            {
                recipients += ";" + emailAddress.Address.ToString();
            }
            cmd.Parameters.AddWithValue("@message_id", email.InternetMessageId);
            cmd.Parameters.AddWithValue("@from", email.From.Address);
            cmd.Parameters.AddWithValue("@body", email.TextBody.ToString());
            cmd.Parameters.AddWithValue("@cc", recipients);
            cmd.Parameters.AddWithValue("@subject", email.Subject);
            cmd.Parameters.AddWithValue("@received_time", email.DateTimeReceived.ToUniversalTime().ToString());

            recipients = "";
            foreach (EmailAddress emailAddress in email.ToRecipients)
            {
                recipients += ";" + emailAddress.Address.ToString();
            }
            cmd.Parameters.AddWithValue("@to", recipients);
            }
...

Save your emails to the database

           
class Write2DB
    {
        SqlConnection conn = null;

        public Write2DB()
        {
            Console.WriteLine("Connecting to SQL Server");
            try
            {
                conn = new SqlConnection("Server=*******;DataBase=***********;uid=******;pwd=**********");
                conn.Open();
                Console.WriteLine("Connected");
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw (e);
            }
        }

        public void Save(EmailMessage email)
        {
            email.Load(new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.TextBody));

            SqlCommand cmd = new SqlCommand("dbo.usp_servicedesk_savemail", conn)
            {
                CommandType = System.Data.CommandType.StoredProcedure,
                CommandTimeout = 1500

            };

            string recipients = "";

            foreach (EmailAddress emailAddress in email.CcRecipients)
            {
                recipients += ";" + emailAddress.Address.ToString();
            }
            cmd.Parameters.AddWithValue("@message_id", email.InternetMessageId);
            cmd.Parameters.AddWithValue("@from", email.From.Address);
            cmd.Parameters.AddWithValue("@body", email.TextBody.ToString());
            cmd.Parameters.AddWithValue("@cc", recipients);
            cmd.Parameters.AddWithValue("@subject", email.Subject);
            cmd.Parameters.AddWithValue("@received_time", email.DateTimeReceived.ToUniversalTime().ToString());

            recipients = "";
            foreach (EmailAddress emailAddress in email.ToRecipients)
            {
                recipients += ";" + emailAddress.Address.ToString();
            }
            cmd.Parameters.AddWithValue("@to", recipients);

            // Execute the procedure
            cmd.ExecuteNonQuery();
        }
        ~Write2DB()
        {
            Console.WriteLine("Disconnecting from SQLServer");
        }
    }
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[usp_servicedesk_savemail]  @message_id varchar(50),@to varchar(512), @from varchar(256), @cc varchar(256)=null,@subject varchar(256),  @body varchar(max), @received_time datetime
as
begin
	IF NOT EXISTS( SELECT 1 from mnit_email where param1 = @message_id )
		insert into mnit_email( created_datetime, type, [from], [to], cc, [subject], body, param1 )
		values( @received_time, 'receive_supportmail', @from, @to, @cc,  @subject, @body, @message_id)
end
GO
The complete visual studio solution can be downloaded here. ReadOffice365MailAndSaveToSQL

About us

Over the years, SQLTreeo gained precious know-how which we transformed into customer support, managed database services and database solutions. In order to express our knowledge and experiences, we tend to work with anything less than the best-trained staff and that is the key to success and the biggest asset of our company. Thus, all our database management services are controlled by high level skilled and Senior database administrators. We can help you in every aspect of SQL Server.

LEAVE A REPLY