Pascal
Pascal

Reputation: 1305

Get appointments from coworker via EWS only with "Free / Busy time, subject, location" permission level

I would like to get all appointments which are in a certain date range from my coworker by his email. I can access his calendar through outlook. I only want to know if he has set an appointment as "Free", "Busy" or "OOF". The code works with "Full Details" permission, but not with the "Free / Busy time, subject, location" permission level.

My coworker shouldn't change the permission level to "Full details". It should stay on "Free/Busy time, subject, location" like this:

enter image description here

I have the following code:

private static void GetAllCalendarItems()
{
        ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
        service.UseDefaultCredentials = true;
        service.Url = new Uri("https://example.com/EWS/Exchange.asmx");

        FolderId cfolderid = new FolderId(WellKnownFolderName.Calendar, "[email protected]");
        Folder TargetFolder = Folder.Bind(service, cfolderid);
        CalendarFolder calendar = CalendarFolder.Bind(service, cfolderid);

        CalendarView cView = new CalendarView(DateTime.Now, DateTime.Now.AddDays(30), 5);

        cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.LegacyFreeBusyStatus);

        FindItemsResults<Appointment> appointments = null;
        try
        {
            appointments = calendar.FindAppointments(cView);
        }
        catch (ServiceResponseException ex)
        {
            Debug.WriteLine("Error code: " + ex.ErrorCode);
            Debug.WriteLine("Error message: " + ex.Message);
            Debug.WriteLine("Response: " + ex.Response);
        }

        foreach (Appointment a in appointments)
        {
            Debug.Write("Subject: " + a.Subject.ToString() + "\t\t\t");
            Debug.Write("Status: " + a.LegacyFreeBusyStatus.ToString() + "\t\t\t");
            Debug.WriteLine("");
        }

 }

This code works fine with my email. But not with the one from my coworker. I get the following exception in my try-catch-block:

Exception thrown: 'Microsoft.Exchange.WebServices.Data.ServiceResponseException' in Microsoft.Exchange.WebServices.dll
Error code: ErrorAccessDenied
Error message: Access is denied. Check credentials and try again.
Response: Microsoft.Exchange.WebServices.Data.FindItemResponse`1[Microsoft.Exchange.WebServices.Data.Appointment]

I have access to his calendar with the given permissions, because I can see his appointments in outlook, so how can I get the appointments with the status from my coworker by his email?

Upvotes: 2

Views: 2138

Answers (2)

Scrobi
Scrobi

Reputation: 1200

If this works with Reviewer permissions and not the Free/Busy setting I can only presume that you need Reviewer permission level to read the calendar.

An alternative what to get the Free / Busy time would be to use ExchangeService.GetUserAvailability

Please see the below resources:

https://msdn.microsoft.com/en-us/library/office/dn643673(v=exchg.150).aspx https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeservice.getuseravailability(v=exchg.80).aspx

Code from the above link incase the break in the future:

// Create a collection of attendees. 
List<AttendeeInfo> attendees = new List<AttendeeInfo>(); 

attendees.Add(new AttendeeInfo() 
{ 
    SmtpAddress = "[email protected]", 
    AttendeeType = MeetingAttendeeType.Organizer 
}); 

attendees.Add(new AttendeeInfo() 
{ 
    SmtpAddress = "[email protected]", 
    AttendeeType = MeetingAttendeeType.Required 
}); 

// Specify options to request free/busy information and suggested meeting times.
AvailabilityOptions availabilityOptions = new AvailabilityOptions(); 
availabilityOptions.GoodSuggestionThreshold = 49; 
availabilityOptions.MaximumNonWorkHoursSuggestionsPerDay = 0;
availabilityOptions.MaximumSuggestionsPerDay = 2;
// Note that 60 minutes is the default value for MeetingDuration, but setting it explicitly for demonstration purposes.
availabilityOptions.MeetingDuration = 60; 
availabilityOptions.MinimumSuggestionQuality = SuggestionQuality.Good; 
availabilityOptions.DetailedSuggestionsWindow = new TimeWindow(DateTime.Now.AddDays(1), DateTime.Now.AddDays(2));
availabilityOptions.RequestedFreeBusyView = FreeBusyViewType.FreeBusy;

// Return free/busy information and a set of suggested meeting times. 
// This method results in a GetUserAvailabilityRequest call to EWS.
GetUserAvailabilityResults results = service.GetUserAvailability(attendees, 
                                                                 availabilityOptions.DetailedSuggestionsWindow, 
                                                                 AvailabilityData.FreeBusyAndSuggestions, 
                                                                 availabilityOptions); 

Upvotes: 2

NotTelling
NotTelling

Reputation: 462

Doesn't your compiler throw an error on this line?

FolderId cfolderid = new FolderId(WellKnownFolderName.Calendar, "[email protected]");

It should be like this:

FolderId cfolderid = new FolderId(WellKnownFolderName.Calendar, new Mailbox("[email protected]"));

MSDN source

Please also mind that by using only the CalendarView for your date range, you are wasting ressouces. Try using a SearchFilter instead or additionally.

Upvotes: 0

Related Questions