0
votes

I'm trying to create a bot that can book meetings. In order to do that i need to access the calendar of an employee to get FreeBusy info to ultimately book a meeting. I'm trying to avoid hardcoding the email and password and for that I want to use an access token from Azure AD to call EWS. I set the properties for

public static ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);

using this method:

       public static async System.Threading.Tasks.Task UseExchangeService(IDialogContext context, string userEmailAddress, SecureString     userPassword)
         {
        string authority = ConfigurationManager.AppSettings["authority"];
        string clientID = ConfigurationManager.AppSettings["clientID"];
         string resource = ConfigurationManager.AppSettings["resource"];
        string appKey = ConfigurationManager.AppSettings["appkey"];

        AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
        ClientCredential clientCred = new ClientCredential(clientID, appKey);
        AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientCred);
        service.Url = new Uri(ConfigurationManager.AppSettings["serverName"] + "/ews/exchange.asmx");
        service.TraceEnabled = true;
        service.TraceFlags = TraceFlags.All;
        service.Credentials = new OAuthCredentials(authenticationResult.AccessToken);


        // USING THIS LINE IT WORKS FINE!
        // service.Credentials = new NetworkCredential(userEmailAddress, userPassword); // VIRKER

    }

I do get the access token from Azure AD and I have granted the permission for the application in Azure AD.

I use this method to extract the freebusytimes, it contains other more code to display the times as buttons on a herocard, but this is the call to EWS:

       List<AttendeeInfo> attendees = new List<AttendeeInfo>();
        attendees.Add(new AttendeeInfo()
        {
            SmtpAddress = "MyEMAIL",
            AttendeeType = MeetingAttendeeType.Organizer
        });

        attendees.Add(new AttendeeInfo()
        {
            SmtpAddress = BookersEmail,
            AttendeeType = MeetingAttendeeType.Required
        });
        //DateTime date1 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day.Ad, 7, 0, 0)
        // Specify options to request free/busy information and suggested meeting times.
        AvailabilityOptions availabilityOptions = new AvailabilityOptions();
        availabilityOptions.GoodSuggestionThreshold = 49;
        availabilityOptions.MaximumNonWorkHoursSuggestionsPerDay = 0;
        availabilityOptions.MaximumSuggestionsPerDay = 20;
        // Note that 60 minutes is the default value for MeetingDuration, but setting it explicitly for demonstration purposes.
        availabilityOptions.MeetingDuration = 60;
        availabilityOptions.MinimumSuggestionQuality = SuggestionQuality.Excellent;

        //TimeWindow hej = new TimeWindow();
        DateTime StartDay = DateTime.Now.AddDays(1);
        TimeSpan ts = new TimeSpan(9, 0, 0);
        DateTime StartTime = StartDay.Date + ts;

        availabilityOptions.DetailedSuggestionsWindow = new TimeWindow(StartTime, DateTime.Now.AddDays(4));
        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);

I have created the application in Azure AD and I have granted the following permissions: Office 365 Exchange Online:

Use Exchange Web Services with full access to all mailboxes

Read and write calendars in all mailboxes

Read and write user and shared calendars

Access mailboxes as the signed-in user via Exchange Web Services

I've tried other answers i found on stackoverflow, however they do not do the trick for me. Hope You can help

1
Can you edit your post with a question. I'm not sure what you're asking.Daniel Dobalian

1 Answers

1
votes

I am not familiar with EWS, however as far as I know that the Microsoft Graph also provide the similar feature for find the available meeting time using the rest below( refer here):

POST /me/findMeetingTimes

And if you want to using this REST for the web application so that your web app can delegate the sign-in user to perform the operation for Exchange, we can use the OAuth 2.0 code grant flow. And for how to use this flow to integrate with Microsoft Graph, you can refer the links below:

Get started with Microsoft Graph in an ASP.NET 4.6 MVC app

And here is the detail for this flow:

Authorize access to web applications using OAuth 2.0 and Azure Active Directory

Hope it is helpful.