Search code examples
c#exchangewebservicesimpersonation

EWS API multiple streaming subscriptions confusion


I have "managed" to subscribe to multiple calendars' change events via the OnNotificationEvent delegate but I don't know how to determine which account sent the event. OnNotificationEvent => sender returns the last impersonation id and if I want to read the contents of the args->item.unqueid I need to know who (which smtp account) to read it as.

static void Main(string[] args)
        {
            var service = EWService();

            service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]");

            var StreamingSubscription = service.SubscribeToStreamingNotifications(
                new FolderId[] { WellKnownFolderName.Calendar },                
                EventType.FreeBusyChanged);
            
            StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(service, 30);
            connection.AddSubscription(StreamingSubscription);
            connection.OnNotificationEvent += OnNotificationEvent;
            connection.OnDisconnect += OnDisconnect;
            connection.OnSubscriptionError += OnSubscriptionError;            
            connection.Open();


            service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]");

            var StreamingSubscription2 = service.SubscribeToStreamingNotifications(
                new FolderId[] { WellKnownFolderName.Calendar },  
                EventType.FreeBusyChanged);

            StreamingSubscriptionConnection connection2 = new StreamingSubscriptionConnection(service, 30);
            connection2.AddSubscription(StreamingSubscription2);
            connection2.OnNotificationEvent += OnNotificationEvent;
            connection2.OnDisconnect += OnDisconnect;
            connection2.OnSubscriptionError += OnSubscriptionError;
            connection2.Open();

            Console.WriteLine("Waiting...");

            while (isRunning ==true)
            {

            }

            StreamingSubscription.Unsubscribe();
            connection.Close();

            StreamingSubscription2.Unsubscribe();
            connection2.Close();

        }

private static void OnNotificationEvent(object sender, NotificationEventArgs args)
{
    foreach (var item in ((StreamingSubscriptionConnection)sender).CurrentSubscriptions)
    {
        var id = item.Service.ImpersonatedUserId.Id;
        Console.WriteLine($"Event for: {id} ");
    }           

    foreach (var item in args.Events)
    {
        Console.WriteLine(item.EventType);
        if (item.EventType == EventType.FreeBusyChanged)
        {
            Console.WriteLine(((ItemEvent)item).ItemId);
        }
    }
}

Solution

  • Generally the best way to do it is when you create the Subscription you track the SubscriptionId that is retuned to the Mailbox you created it against. Exchange only returns the SubscriptionId is the Streaming request. The other workaround is to use the ParentFolderId of the items (or folder) that has changed and then get the StoreId which you can then decode the LegacyExchangeDn from that and resolve that to the SMTP Address of the Mailbox. But this takes multiple web requests so your better just doing it at the time you create Subscription.