Showing posts with label .net ews MANAGED API. Show all posts
Showing posts with label .net ews MANAGED API. Show all posts

Monday, March 26, 2018

Integration of Exchange using EWS-Managed API


/*Only for reference    NOT A WORKING SAMPLE*/


using Microsoft.Exchange.WebServices.Data;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.Exchange.WebServices.Data.SearchFilter;

namespace  exchangeConsole
{
    class Program

    {

        private static string ContentsSyncState;
        private static string FolderSyncState;

        private static ChangeCollection<ItemChange> ItemChangeCollection;
        private static ChangeCollection<FolderChange> FolderChangeCollection;
        private static AutoResetEvent Signal;
        private static StreamingSubscription StreamingSubscription;
        private static PullSubscription PullSubscription;
        private static string PullSubscriptionId;
        private static string WaterMark;
        static bool FirstPull = false;
        private static int WaitTime = 3;

        static ExchangeService service = EService.ConnectToService(UserDataFromConsole.GetUserData(true));

        // Set the root folder to sync. This must be one of the WellKnownFolderName values.
        private static FolderId RootSyncFolder = WellKnownFolderName.Calendar;
        static DbContext dbContext = new demoentitees();



        static void Main(string[] args)
        {


            var syncStates = dbContext.Set<SyncState>();

            if (syncStates.Count() != 0 && syncStates.Where(x => x.IsFolder == true && x.CreatedBy != "testxxx") != null && syncStates.Where(x => x.IsFolder == true && x.CreatedBy != "testxxx").Count() > 0)
            {
             
                FolderSyncState = syncStates.Where(x => x.IsFolder == true && x.CreatedBy != "testxxx").OrderByDescending(x => x.Id).FirstOrDefault().SyncString;
                ContentsSyncState = syncStates.Where(x => x.IsFolder == false && x.CreatedBy != "testxxx").OrderByDescending(x => x.Id).FirstOrDefault().SyncString;
            }

            else
            {
                FirstPull = true;
                FolderSyncState = null;
                ContentsSyncState = null;
            }



         

            // Retrieve the initial folder hierarchy, using rootSyncFolder as the root folder.
            FolderSyncState = SyncFolders(service, FolderSyncState, RootSyncFolder);

            //  Retrieve the initial contents of the rootSyncFolder.
            ContentsSyncState = SyncContents(service, ContentsSyncState, RootSyncFolder);



            // After the initial sync, wait for notifications of new or changed items.
            // StreamingSubscription = SetStreamingNotifications(service, ContentsSyncState, RootSyncFolder);
            //Restart:
            //do
            //{
            //    SetPullNotifications(service, WaterMark, RootSyncFolder);
            //} while (PullSubscription.MoreEventsAvailable.HasValue && !PullSubscription.MoreEventsAvailable.HasValue);

            //Signal = new AutoResetEvent(false);
            //PullSubscription.Unsubscribe();
            // Wait for the application to exit.
            // Signal.WaitOne();

            //Console.WriteLine("Enter 'y' or 'N' ");

            //string key = Console.ReadLine();
            //if (key == "y"|| key=="Y")
            //    goto Restart;

            Console.Read();

        }


        // Synchronize the contents of the rootSyncFolder folder.
        static string SyncContents(ExchangeService service, string cSyncState, FolderId rootSyncFolder)
        {
            //Console.WriteLine("--------");
            //Console.WriteLine("Starting content sync on the following folder");
            //Console.WriteLine("FolderId: {0}", rootSyncFolder);
            //Console.WriteLine("--------");

            bool moreChangesAvailable = false;

            do
            {

                // Get a change collection of all items in the rootSyncFolder by calling SyncFolderItems
                // repeatedly until no more changes are available.
                // The folderId parameter must be set to the same folder ID as the previous synchronization call.
                // The propertySet parameter is set to IdOnly to reduce calls to the Exchange database,
                // because any additional properties result in another call to the Exchange database.
                // The ignoredItemIds parameter is set to null, so no items are ignored.
                // The maxChangesReturned parameter is set to return a maximum of 500 items (512 is the default).
                // The syncScope parameter is set to Normal items, so associated items will not be returned.
                // The syncState parameter is set to the content sync state. When this method is called
                // on a new or empty mailbox, the value is null. If the method has been called before,
                // the cSyncState value contains the value previously returned by the server.
                ItemChangeCollection = service.SyncFolderItems(rootSyncFolder, PropertySet.IdOnly, null, 500, SyncFolderItemsScope.NormalItems, cSyncState);


                // Save the sync state for use in future SyncFolderItems requests.
                // The sync state is used by the server to determine what changes to report
                // to the client.
                cSyncState = ItemChangeCollection.SyncState;

                // If the count of changes is zero, there are no changes to synchronize.
                if (ItemChangeCollection.Count == 0)
                {
                    //Console.WriteLine("There are no items to synchronize.");
                    Console.WriteLine("--------");


                }

                // Otherwise, write all the changes included in the response
                // to the console.
                else
                {

                    foreach (ItemChange ic in ItemChangeCollection)
                    {
                        //Console.WriteLine("ItemChange.ChangeType: " + ic.ChangeType.ToString());
                        //Console.WriteLine("ItemChange.ItemId: " + ic.ItemId.UniqueId);
                        //Console.WriteLine("--------");


                        using (var ctx = new demoEntities())
                        {
                            var std = new SyncState()
                            {
                                 //save
                            };
                            ctx.SyncStates.Add(std);
                            ctx.SaveChanges();


                        }

                    }
                }

                // Determine whether more changes are available on the server.
                moreChangesAvailable = ItemChangeCollection.MoreChangesAvailable;

                // Send the ItemChangeCollection to ProcessItems to actually retrieve the messages and changes.
                ProcessItems(ItemChangeCollection);
            }

            while (moreChangesAvailable);

            Console.WriteLine("Finished content sync on the following folder");
            Console.WriteLine("FolderId: {0}", rootSyncFolder);
            Console.WriteLine("--------");

            return cSyncState;
        }

        static string ItemIdSearch(string Id, string subject, DateTime sent)
        {
            ItemView view = new ItemView(1000);

            //List<SearchFilter> searchANDFilterCollection = new List<SearchFilter>();
       
            //////searchANDFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema., ".Note.Exchange"));
            ////searchANDFilterCollection.Add(new SearchFilter.ContainsSubstring(EmailMessageSchema.Subject, subject));
            ////searchANDFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.MeetingRequestWasSent,true));

            ////searchANDFilterCollection.Add(new SearchFilter.IsGreaterThanOrEqualTo(EmailMessageSchema.DateTimeSent, sent));
            ////searchANDFilterCollection.Add(new SearchFilter.IsLessThanOrEqualTo(EmailMessageSchema.DateTimeSent, sent.AddHours(24)));

            string id = string.Empty;

         //   SearchFilter searchANDFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchANDFilterCollection.ToArray());


            var results = service.FindItems(WellKnownFolderName.Calendar, view);
            foreach (var item in results)
            {
                var synstatesid = dbContext.Set<SyncState>().ToList().Where(x => x.SyncString == ContentsSyncState && x.Id == item.Id.UniqueId && x.IsFolder == false)
                    .OrderByDescending(x => x.Id).FirstOrDefault();
                if (synstatesid != null)

                    id = synstatesid.EWSId;
            }

            return id;
        }

        private CalendarFolder FindNamedCalendarFolder(string name)
        {
            FolderView view = new FolderView(100);
            view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
            view.PropertySet.Add(FolderSchema.DisplayName);
            view.Traversal = FolderTraversal.Deep;

            SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.FolderClass, "1ppointment");

            FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.Root, sfSearchFilter, view);
            return findFolderResults.Where(f => f.DisplayName == name).Cast<CalendarFolder>().FirstOrDefault();
        }


        static void ESave(string ItemId, string type = "email")
        {


            if (type == "email")
            {
                var msg = Item.Bind(service, ItemId);
                using (var ctx = new EWS_DemoEntities())
                {

                    var std = new EmailMessasge()
                    {
                        ///asave
                    };
                    ctx.EmailMessasges.Add(std);
                    ctx.SaveChanges();

                }
            }
            else
            {
                Appointment met = Appointment.Bind(service, ItemId);
                using (var ctx = new demoEntities())
                {

                    var std = new Meeting()
                    {
//                        save

                    };
                    ctx.Meetings.Add(std);
                    ctx.SaveChanges();

                }

            }



        }

        // Get the items and changes in the root folder.
        static void ProcessItems(ChangeCollection<ItemChange> icc)
        {

            // Create a variable for all the new items in the ItemChangeCollection.
            var newItems = from ic in icc
                           where ic.ChangeType == ChangeType.Create
                           select ic.Item;

            // Get the properties for each item, so that they can be created on the client.
            foreach (var item in newItems)
            {
                service.LoadPropertiesForItems(newItems, PropertySet.FirstClassProperties);
                //Console.WriteLine("New item, all properties loaded");
                //Console.WriteLine("Subject: {0}", item.Subject);
                //Console.WriteLine("ParentFolderId: {0}", item.ParentFolderId);
                //Console.WriteLine("DateTimeCreated: {0}", item.DateTimeCreated);
                //Console.WriteLine("--------");
                // TODO: Create the messages on the client by using the properties
                // returned from LoadPropertiesForItems.

                string fid = ItemIdSearch(item.Id.UniqueId, "test", new DateTime(2018, 03, 14));
                if (!string.IsNullOrEmpty(fid))
                {
                     Save(fid);
                }

            }

            // Create a variable for all the deleted items in the ItemChangeCollection.
            var deleteItems = from ic in icc
                              where ic.ChangeType == ChangeType.Delete
                              select ic.ItemId;

            // Display the ItemIds to be deleted on the client.
            foreach (var item in deleteItems)
            {
                Console.WriteLine("Delete ItemId: {0}", item);
                Console.WriteLine("--------");
                // TODO: Delete messages on the client by using the ItemIds in deleteItems. 
            }

            // Create a variable for all the items with read state changes in the ItemChangeCollection.
            var readFlagChangeItems = from ic in icc
                                      where ic.ChangeType == ChangeType.ReadFlagChange
                                      select ic.ItemId;

            // Display the ItemIds that have read state changes.
            foreach (var item in readFlagChangeItems)
            {
                //Console.WriteLine("Read flag change to ItemId: {0}", item);
                //Console.WriteLine("--------");
                // TODO: Change the read state of the item saved on the client
                // by using the ItemIds in readFlagChangeItems.
                string fid = ItemIdSearch(item.UniqueId, "ouu", new DateTime(2018, 03, 14));
                if (!string.IsNullOrEmpty(fid))
                {

                     save(fid);
                }
            }

            // Create a variable for all the updated items in the ItemChangeCollection.
            var updateItems = from ic in icc
                              where ic.ChangeType == ChangeType.Update
                              select ic.Item;

            // Display the subject for each updated item.
            foreach (var item in updateItems)
            {
                service.LoadPropertiesForItems(updateItems, PropertySet.FirstClassProperties);
                //Console.WriteLine("Updated item, all properties loaded");
                //Console.WriteLine("Subject: {0}", item.Subject);
                //Console.WriteLine("ParentFolderId: {0}", item.ParentFolderId);
                //Console.WriteLine("DateTimeCreated: {0}", item.DateTimeCreated);
                //Console.WriteLine("--------");
                // TODO: Compare the properties retrieved from LoadPropertiesForItems to the
                // properties on the client and update the client properties accordingly.

                string fid = ItemIdSearch(item.Id.UniqueId, "ouu", new DateTime(2018, 03, 14));
                if (!string.IsNullOrEmpty(fid))
                {
                     save(fid);
                }
            }
        }

        // Get the folder changes in the root folder.
        static void ProcessFolders(ChangeCollection<FolderChange> fcc)
        {

            // Create a variable for all the new folders in the FolderChange ChangeCollection.
            var newFolders = from fc in fcc
                             where fc.ChangeType == ChangeType.Create
                             select fc.FolderId;

            // Get the properties for each folder, so that they can be created on the client.
            foreach (var item in newFolders)
            {
                Folder newFolder = new Folder(service);
                newFolder = Folder.Bind(service, item);
                newFolder.Load();
                //Console.WriteLine("New folder, all properties loaded");
                //Console.WriteLine("Display name: {0}", newFolder.DisplayName);
                //Console.WriteLine("Parent Folder Id: {0}", newFolder.ParentFolderId);
                //Console.WriteLine("--------");

                // TODO: Create the folder on the client by using the properties
                // returned from Load.

                // Call SyncContents and SetStreamingNotifications on the new child folders.
                string ccSyncState = SyncContents(service, null, newFolder.Id);
                //SetStreamingNotifications(service, ccSyncState, newFolder.Id);

            }

            // Create a variable for all the deleted folders in the FolderChange ChangeCollection.
            var deleteFolders = from fc in fcc
                                where fc.ChangeType == ChangeType.Delete
                                select fc.FolderId;

            // Display the FolderIds to be deleted on the client.
            foreach (var item in deleteFolders)
            {
                Console.WriteLine("Delete FolderId: {0}", item);
                Console.WriteLine("--------");
                // TODO: Delete messages on the client by using the FolderIds in deleteFolders.
            }

            // Create a variable for all the updated folders in the FolderChange ChangeCollection.
            var updateFolders = from fc in fcc
                                where fc.ChangeType == ChangeType.Update
                                select fc.Folder;

            // Display the display name for each updated folder.
            foreach (var item in updateFolders)
            {
                Folder folder = Folder.Bind(service, item.Id);
                folder.Load();
                //Console.WriteLine("Updated folder, all properties loaded.");
                //Console.WriteLine("Parent Folder Id: {0}", item.ParentFolderId);
                //Console.WriteLine("Display name: {0}", item.DisplayName);
                //Console.WriteLine("--------");
                // TODO: Compare the properties retrieved from Load to the
                // properties on the client and update the client properties accordingly.
            }
        }

        // When the subscription connection expires, determine whether the subscription should be kept open.
        static private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            // Cast the sender as a StreamingSubscriptionConnection object.         
            StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;

            // Ask the user if they want to reconnect or close the subscription.
            ConsoleKeyInfo cki;
            Console.WriteLine("The StreamingSubscriptionConnection has expired.");
            Console.WriteLine("\r\n");
            Console.WriteLine("Do you want to reconnect to the subscription? Enter Y or N");
            Console.WriteLine("\r\n");
            while (true)
            {
                cki = Console.ReadKey(true);
                {
                    if (cki.Key == ConsoleKey.Y)
                    {
                        connection.Open();
                        Console.WriteLine("Connection open.");
                        Console.WriteLine("\r\n");
                        break;
                    }
                    else if (cki.Key == ConsoleKey.N)
                    {
                        Signal.Set();

                        // Unsubscribe from the notification subscription.
                        StreamingSubscription.Unsubscribe();

                        // Close the connection.
                        connection.Close();
                        break;
                    }
                }
            }
        }

        // Catch and display notification events.
        static void OnNotificationEvent(object sender, NotificationEventArgs args)
        {
            bool callSyncContents = false;
            bool callSyncFolders = false;

            StreamingSubscription subscription = args.Subscription;

            // Loop through all item-related events.
            foreach (NotificationEvent notification in args.Events)
            {

                switch (notification.EventType)
                {
                    case EventType.NewMail:
                        Console.WriteLine("Notification: New mail created");
                        break;
                    case EventType.Created:
                        Console.WriteLine("Notification: Item or folder created");
                        break;
                    case EventType.Deleted:
                        Console.WriteLine("Notification: Item or folder deleted");
                        break;
                    case EventType.Modified:
                        Console.WriteLine("Notification: Item or folder modified");
                        break;
                    case EventType.Moved:
                        Console.WriteLine("Notification: Item or folder moved");
                        break;
                    case EventType.Copied:
                        Console.WriteLine("Notification: Item or folder copied");
                        break;
                }
                // Display the notification identifier.
                if (notification is ItemEvent)
                {
                    ItemEvent itemEvent = (ItemEvent)notification;
                    Console.WriteLine("Notification ItemId: " + itemEvent.ItemId.UniqueId);
                    Console.WriteLine("--------");
                    callSyncContents = true;
                }
                else
                {
                    FolderEvent folderEvent = (FolderEvent)notification;
                    Console.WriteLine("Notification FolderId: " + folderEvent.FolderId.UniqueId);
                    Console.WriteLine("--------");
                    callSyncFolders = true;
                }
            }

            // Delay calling SyncContents and SyncFolders until all notifications have been processed.
            // This will reduce the number of calls to the Exchange database by batching more changes
            // into a single sync call.
            if (callSyncContents == true)
            {
                ContentsSyncState = SyncContents(service, ContentsSyncState, RootSyncFolder);
            }

            if (callSyncFolders == true)
            {
                FolderSyncState = SyncFolders(service, FolderSyncState, RootSyncFolder);
            }
        }


        // Synchronize the folders in the specified root folder.
        static string SyncFolders(ExchangeService service, string FolderSyncState, FolderId rootSyncFolder)
        {
            //Console.WriteLine("Starting folder sync on the following folder");
            //Console.WriteLine("FolderId: {0}", rootSyncFolder);
            //Console.WriteLine("--------");

            // Get a list of all folders under the rootSyncFolder by calling SyncFolderHierarchy.
            // The folderId parameter is the root folder to synchronize.
            // The propertySet parameter is set to IdOnly to reduce calls to the Exchange database,
            // because any additional properties result in another call to the Exchange database.
            // The syncState parameter is set to the folder sync state. When this method is called
            // on a new or empty mailbox, the value is null. If the method has been called before,
            // the FolderSyncState value contains the value previously returned by the server.
            FolderChangeCollection = service.SyncFolderHierarchy(rootSyncFolder, PropertySet.IdOnly, FolderSyncState);

            // Save the sync state for use in future SyncFolderItems requests.
            // The sync state is used by the server to determine what changes to report
            // to the client.
            FolderSyncState = FolderChangeCollection.SyncState;

            // If the count of changes is zero, there are no changes to synchronize.
            if (FolderChangeCollection.Count == 0)
            {
                //Console.WriteLine("There are no new folders to synchronize.");
                //Console.WriteLine("--------");
            }

            // Otherwise, write all the changes included in the response
            // to the console.
            // For the initial synchronization, all the changes will be of type
            // ChangeType.Create.
            else
            {
                foreach (FolderChange fc in FolderChangeCollection)
                {
                    //Console.WriteLine("FolderChange.ChangeType: " + fc.ChangeType.ToString());
                    //Console.WriteLine("FolderChange.FolderId: " + fc.FolderId);
                    //Console.WriteLine("--------");


                    using (var ctx = new DemoEntities())
                    {
                        var std = new SyncState()
                        {
                            //save
                        };
                        ctx.SyncStates.Add(std);
                        ctx.SaveChanges();

                    }
                }

            }

            // Send the FolderChangeCollection to ProcessItems to actually retrieve the messages and changes.
            ProcessFolders(FolderChangeCollection);

            //Console.WriteLine("Finished folder sync on the following folder");
            //Console.WriteLine("FolderId: {0}", rootSyncFolder);
            //Console.WriteLine("--------");

            return FolderSyncState;

        }

        //Subscribe to streaming notifications for all folder and item events in the root folder.
        static StreamingSubscription SetStreamingNotifications(ExchangeService service, string cSyncState, FolderId rootSyncFolder)
        {
            // Subscribe to streaming notifications on the rootSyncFolder and listen
            // for events.
            StreamingSubscription = service.SubscribeToStreamingNotifications(
                new FolderId[] { rootSyncFolder },
                EventType.NewMail,
                EventType.Created,
                EventType.Deleted,
                EventType.Modified,
                EventType.Moved,
                EventType.Copied
                );

            StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(service, WaitTime);
            connection.AddSubscription(StreamingSubscription);
            connection.OnNotificationEvent += OnNotificationEvent;
            connection.OnDisconnect += OnDisconnect;
            connection.Open();

            Console.WriteLine("Now waiting for notifications on the following folder");
            Console.WriteLine("FolderId: {0}", rootSyncFolder);
            Console.WriteLine("--------");

            return StreamingSubscription;

        }

        //Subscribe to streaming notifications for all folder and item events in the root folder.
        static PullSubscription SetPullNotifications(ExchangeService service, string watermark, FolderId rootSyncFolder)
        {


            // Subscribe to streaming notifications on the rootSyncFolder and listen
            // for events.
            PullAgain:
            PullSubscription = service.SubscribeToPullNotifications(
                new FolderId[] { rootSyncFolder }, WaitTime, watermark,
                EventType.NewMail,
                EventType.Created,
                EventType.Deleted,
                EventType.Modified,
                EventType.Moved,
                EventType.Copied
                );
            var events = PullSubscription.GetEvents();

            PullSubscriptionId = PullSubscription.Id;
            if (WaterMark != PullSubscription.Watermark)
            {
                WaterMark = PullSubscription.Watermark;
                goto PullAgain;

            }






            if (events.ItemEvents.Count() > 0)
            {
                // Handle the results of the GetEvents method.
                foreach (ItemEvent itemEvent in events.ItemEvents)
                {

                    switch (itemEvent.EventType)
                    {
                        case EventType.NewMail:
                            EmailMessage message = EmailMessage.Bind(service, itemEvent.ItemId);
                            message.Load();
                            Console.WriteLine("Item new mail: " + message.Subject);
                            //Console.WriteLine("Item Id:" + message.Id);
                            break;
                        case EventType.Created:
                            Item item = Item.Bind(service, itemEvent.ItemId);
                            item.Load();
                            Console.WriteLine("Item Created: " + item.Subject);
                            // Console.WriteLine("Item Id:" + item.Id);
                            break;
                        case EventType.Deleted:
                            Item d = Item.Bind(service, itemEvent.ItemId);
                            d.Load();
                            Console.WriteLine("Item deleted: " + d.Subject);
                            break;

                        case EventType.Moved:
                            Item d1 = Item.Bind(service, itemEvent.ItemId);
                            d1.Load();
                            Console.WriteLine("Item deleted: " + d1.Subject);
                            break;
                        case EventType.Modified:
                            Item tem = Item.Bind(service, itemEvent.ItemId);
                            tem.Load();
                            Console.WriteLine("Item Modified: " + tem.Subject);
                            // Console.WriteLine("Item Id:" + tem.Id);
                            break;
                    }
                }

            }
            else
            {

                Console.WriteLine("No Events");
            }
            NoEvents:
            Console.WriteLine("Now waiting for pull notifications on the following folder");
            Console.WriteLine("FolderId: {0}", rootSyncFolder);
            Console.WriteLine("--------");


            return PullSubscription;

        }




        // Catch and display errors.
        static void OnError(object sender, SubscriptionErrorEventArgs args)
        {
            // Handle error conditions.
            Exception e = args.Exception;
            Console.WriteLine("\n-------------Error ---" + e.Message + "-------------");
        }

    }
}