Sunday, 25 November 2018

EWS Managed API integrate and pass email information to another system

In this blog i'm only explaining the important aspects when reading using EWS API. I read from a child folder from root mailbox. Use WellKnownFolderName.Root it will show all folders of my Inbox.Then using web services i call the 3rd party tool and pass the information read from the specific mail box. Below i'm showing only the flow of the process but this will help you to figure our the code level commands.

public static void RunProcess()
        {
            DateTime dateTime = DateTime.Now;


            service.Credentials = new NetworkCredential(Settings.Default.EmailAddress, Settings.Default.EmailPassword);

            if (Settings.Default.ExchangeUseAutodiscover == true)
            {
                if (isDebugEnabled)
                {
                    logger.Debug("Finding Autodiscover URL.");
                }
                service.AutodiscoverUrl(Settings.Default.EmailAddress, RedirectionCallback);
            }
            else
            {
                service.Url = new System.Uri(Settings.Default.ExchangeWebServicesEndpoint);
            }

            if (isDebugEnabled)
            {
                logger.Debug(String.Format("EWS Endpoint: {0}", service.Url));
            }

            BindMailboxFolders();
            ProcessEmail();
        }

        static bool RedirectionCallback(string url)
        {
            return url.ToLower().StartsWith("https://");
        }

 static void BindMailboxFolders()
        {
            FolderView view = new FolderView(100);
            view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
            view.PropertySet.Add(FolderSchema.DisplayName);
            view.Traversal = FolderTraversal.Deep;
            FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.Root, view);

            foreach (Folder folder in findFolderResults)
            {
                if (folder.DisplayName.Equals(Settings.Default.CaseCreatedMailFolderName))
                    caseCreatedMailFolder = Folder.Bind(service, folder.Id);

                if (folder.DisplayName.Equals(Settings.Default.ErrorMailFolderName))
                    errorMailFolder = Folder.Bind(service, folder.Id);

                if (folder.DisplayName.Equals(Settings.Default.UnknownMailFolderName))
                    unknownMailFolder = Folder.Bind(service, folder.Id);
            }
        }

        static void ProcessEmail()
        {
            PropertySet emailPropertySet = new PropertySet(BasePropertySet.FirstClassProperties, EmailMessageSchema.IsRead);
            emailPropertySet.RequestedBodyType = BodyType.Text;
            ItemView itemView = new ItemView(1000);
            itemView.PropertySet = emailPropertySet;

            //Get unread email only
            SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
            FindItemsResults<Item> findEmailResults = service.FindItems(WellKnownFolderName.Inbox, filter, itemView);

             int emailCount = 1;
            Dictionary<int, Dictionary<string, string>> emails = new Dictionary<int, Dictionary<string, string>>();

            foreach (EmailMessage email in findEmailResults.Items.Where(i => i is EmailMessage))
            {
                email.Load(emailPropertySet);
                EmailData emailData = new EmailData();
                emailData.fromAddress = email.From.ToString();
                emailData.sent = email.DateTimeSent.ToString();
                emailData.toAddress = email.DisplayTo.ToString();
                emailData.mailSubject = email.Subject.ToString();

                if (isDebugEnabled)
                {
                    logger.Debug("-----------------------------------------------");
                    logger.Debug("From: " + email.LastModifiedName);
                    logger.Debug("To: " + email.DisplayTo);
                    logger.Debug("CC: " + email.DisplayCc);
                    logger.Debug("Subject: " + email.Subject);
                    logger.Debug("-----------------------------------------------");
                }

                emails.Add(emailCount, new Dictionary<string, string>());
                email.Body.ToString().Split('\n');
                foreach (string line in email.Body.ToString().Split('\n'))
                {
                    if (Regex.IsMatch(line, "^.*:{1}.*$"))
                    {
                        //Split only on first occurance of ":"
                        string[] values = line.Split(new[] { ":" }, 2, StringSplitOptions.None);
                        emails[emailCount].Add(values[0].Trim(), values[1].Trim());

                        if (isDebugEnabled)
                        {
                            logger.Debug(values[0].Trim() + " - " + values[1].Trim());
                        }
                    }
                }

                //Attempt to create case with web services here, then move into folder based on result of web services call
               
                // Get the Dictionary for the current email
                Dictionary<string, string> emailDictionary = emails[1];
                bool dataComplete = VerifyEmailProperties(emailData, emailDictionary);

                // Get the process to create the Case for
                Process process = processFactory.getProcess(emailData);

                // Create Case in 3rd party system by calling it's web service
                try
                {
                    createCase.processRequest(process);

                    //Mark as read and move to appropriate folder
                    email.IsRead = true;
                    email.Update(ConflictResolutionMode.AutoResolve);
                    if (isDebugEnabled)
                    {
                        logger.Debug("MARKED AS READ...");
                    }
                    email.Move(caseCreatedMailFolder.Id);
                    if (isDebugEnabled)
                    {
                        logger.Debug("MOVED TO FOLDER...");
                    }

                    emailData = null;
                }
                catch (Exception e)
                {
                    email.IsRead = true;
                    email.Update(ConflictResolutionMode.AutoResolve);
                    if (isErrorEnabled)
                    {
                        logger.Error("Failed to Process...MARKED AS READ..." + Environment.NewLine
                            + emailData.ToString() + Environment.NewLine + e.InnerException.StackTrace);
                    }
                }

                emailData = null;
                emailCount++;
            }
        }

Wednesday, 21 November 2018

How to send email from a trigger when a record is inserted

Setting up a trigger using sp_send_dbmail is easier than you think. If you have set up your SQL server to send out emails then it's matter of setting up your email template in the trigger. Have a look at below trigger i have created. 
In this trigger i have first create email body querying from a database query. Then i embed it and send to the recipient that is again queried out from the DB. 
I believe this trigger will save your time :)


USE [Database Name]
GO
/****** Object:  Trigger [dbo].[NotificationEmail]  ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[NotificationEmail]
ON [dbo].[logEvents]
AFTER INSERT 
AS

--Initiation

declare @email varchar(200), @ID varchar(12), @emailBody varchar(500), @emailSubject varchar(150)

--Select email and note

select @email = A.EMAIL, @ID = A.ID
from <DB TABLE> A
      
--Create email strings

set @emailBody = 'A new note has been added to ' + @ID + ', which has triggered an email to ' + @email 
+ char(13) + char(10) + char(10) + 
+'As this ID has been assigned to you, please review the updated information.'+char(10) + char(10) 
+'Thank You'

set @emailSubject = 'New note added to ' + @ID

if @email is not null
begin

--Send email

      EXEC msdb.dbo.sp_send_dbmail
            @profile_name = 'emails',
            @recipients = @email,
            --@recipients = 'sarasidias@test.com',
            @body = @emailBody,
            @subject = @emailSubject
end