/// <summary> /// Returns a list of emails which were sent on a given date /// </summary> /// <param name="date"></param> /// <returns></returns> public async Task <long> GetNumberOfEmailsSent(DateTimeOffset date) { if (await ConnectionToApiFailing()) { return(Settings.NoValueDefault); } try { var dtStart = date.Date.ToUniversalTime(); var dtEnd = date.Date.AddDays(1).ToUniversalTime(); var options = new List <QueryOption> { new QueryOption("$filter", "sentDateTime ge " + dtStart.ToString(DateTimeToFormatString) + " and sentDateTime le " + dtEnd.ToString(DateTimeToFormatString)), new QueryOption("$count", "true") }; var result = await _client.Me.MailFolders.SentItems.Messages.Request(options).GetAsync(); var numberEmailsSent = GetResultCount(result); return(numberEmailsSent); } catch (Exception e) { Logger.WriteToLogFile(e); return(Settings.NoValueDefault); } }
/// <summary> /// Returns the total number of emails currently in the inbox (read and unread) /// </summary> /// <returns>number of items, -1 in case of an error</returns> public async Task <long> GetTotalNumberOfEmailsInInbox() { if (await ConnectionToApiFailing()) { return(Settings.NoValueDefault); } try { var options = new List <QueryOption> { //new QueryOption("$filter", "isRead eq false"), // we want the total list new QueryOption("$count", "true") }; var result = await _client.Me.MailFolders.Inbox.Messages.Request(options).GetAsync(); var inboxSize = GetResultCount(result); return(inboxSize); } catch (Exception e) { Logger.WriteToLogFile(e); return(Settings.NoValueDefault); } }
/// <summary> /// force MSAL to prompt the user for credentials by specifying PromptBehavior.Always. /// MSAL will get a token and cache it /// </summary> private async Task <bool> SignIn() { try { _authResult = await _app.AcquireTokenAsync(Settings.Scopes); return(true); } catch (MsalException ex) { // If MSAL cannot get a token, it will throw an exception. // If the user canceled the login, it will result in the // error code 'authentication_canceled'. if (ex.ErrorCode == "authentication_canceled") { //MessageBox.Show("We could not connect to your Office 365 account as you canceled the authentication process. Please try again later."); Database.GetInstance().LogWarning("Office 365 sign in was canceled by the user"); return(false); } else { // An unexpected error occurred. Logger.WriteToLogFile(ex); return(false); } } catch (Exception ex) { Logger.WriteToLogFile(ex); return(false); } }
/// <summary> /// This method is called from a method if the user is not properly signed in yet /// and to check if the user can be authenticated /// (also checks for an active internet connection) /// </summary> private async Task <bool> TrySilentAuthentication() { // check for internet connection if (!IsInternetAvailable()) { return(false); } try { // receive API client ID if (_clientId == null) { _clientId = GetOffice365ApiClientId(); if (_clientId == null) { return(false); } } // register app (if not yet done) if (_app == null) { _app = new PublicClientApplication(_clientId, _authority, FileCache.GetUserCache()); } // Here, we try to get an access token to call the service without invoking any UI prompt. //_authResult = await _app.AcquireTokenAsync(_scopes, "", UIBehavior.ForceLogin, ""); _authResult = await _app.AcquireTokenSilentAsync(Settings.Scopes, _app.Users.FirstOrDefault()); // prepare outlook services client (if not yet ready) if (_client == null) { _client = new GraphServiceClient(new DelegateAuthenticationProvider(requestMessage => { requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", _authResult.AccessToken); return(Task.FromResult(0)); })); //_client.BaseUrl = Settings.GraphApiEndpoint; } return(true); } catch (MsalUiRequiredException) { // MSAL couldn't get a token silently, so show the user a message and let them click the Sign-In button. var res = await SignIn(); return(res); } catch (Exception e) { Logger.WriteToLogFile(e); return(false); } }
/// <summary> /// Loads all meetings from the user's main calendar for the given date /// </summary> /// <param name="date"></param> /// <returns></returns> public async Task <List <Event> > LoadMeetings(DateTimeOffset date) { var meetings = new List <Event>(); if (await ConnectionToApiFailing()) { return(meetings); } try { var dtStart = date.Date.AddSeconds(1).ToUniversalTime(); var dtEnd = date.Date.AddDays(1).AddSeconds(-1).ToUniversalTime(); var options = new List <QueryOption> { new QueryOption("startDateTime", dtStart.ToString(DateTimeToFormatString)), new QueryOption("endDateTime", dtEnd.ToString(DateTimeToFormatString)), //new QueryOption("select", "subject,body,bodyPreview,organizer,attendees,start,end,location"), }; var result = await _client.Me.CalendarView.Request(options).GetAsync(); //var calendar = await _client.Me.Calendar.CalendarView.Request(options).GetAsync(); if (result?.Count > 0) { var meetingsUnfiltered = new List <Event>(); meetingsUnfiltered.AddRange(result.CurrentPage); while (result.NextPageRequest != null) { result = await result.NextPageRequest.GetAsync(); meetingsUnfiltered.AddRange(result.CurrentPage); } // remove unneeded meetings meetings = meetingsUnfiltered.Where( m => (m.IsCancelled != null && m.IsCancelled.Value == false) // && // meeting is not cancelled //(m.IsOrganizer != null && !m.IsOrganizer.Value && (m.ResponseStatus.Response == ResponseType.Accepted || m.ResponseStatus.Response == ResponseType.TentativelyAccepted))) // user attends meeting ).ToList(); } } catch (Exception e) { Logger.WriteToLogFile(e); } return(meetings); }
/// <summary> /// clear the MSAL token cache /// It's also necessary to clear the cookies from the browser' control so the next user has a chance to sign in. /// </summary> public void SignOut() { if (!_app.Users.Any()) { return; } try { _app.Remove(_app.Users.FirstOrDefault()); } catch (MsalException ex) { Logger.WriteToLogFile(ex); } }
/// <summary> /// Loads a list of folders to find the Ids of folders that should not be considered /// (Spam, Sent, Clutter, Deleted, etc.) /// Also caches it after first instantiation. /// </summary> /// <returns></returns> private async Task <List <string> > GetFoldersToIgnoreIds() { if (_emailFoldersToIgnore != null) { return(_emailFoldersToIgnore); } _emailFoldersToIgnore = new List <string>(); try { var folders = await _client.Me.MailFolders.Request().GetAsync(); // get all mailbox-folders var folderList = new List <MailFolder>(); folderList.AddRange(folders.CurrentPage); while (folders.NextPageRequest != null) { folders = await folders.NextPageRequest.GetAsync(); folderList.AddRange(folders.CurrentPage); } // filter folders we want to ignore var foldersToIgnore = new List <string> { "deleted", "junk", "spam", "sent", "draft", "outbox", "clutter", "archive" }; foreach (var item in folderList) { foreach (var ignoreFolder in foldersToIgnore) { if (!item.DisplayName.ToLower().Contains(ignoreFolder)) { continue; } _emailFoldersToIgnore.Add(item.Id); } } } catch (Exception ex) { Logger.WriteToLogFile(ex); } return(_emailFoldersToIgnore); }
/// <summary> /// This method fetches the OFfice 365 API client secret from the PA-service server /// TODO: store it /// </summary> /// <returns></returns> private string GetOffice365ApiClientId() { try { AccessDataService.AccessDataClient client = new AccessDataService.AccessDataClient(); string clientId = client.GetOffice365ClientId(); if (clientId != null) { return(clientId); } } catch (Exception e) { Logger.WriteToLogFile(e); } return(null); }
/// <summary> /// Returns a list of emails which were received on a given date /// </summary> /// <param name="date"></param> /// <returns></returns> public async Task <int> GetTotalNumberOfEmailsReceived(DateTimeOffset date) { if (await ConnectionToApiFailing()) { return(Settings.NoValueDefault); } try { var dtStart = date.Date.ToUniversalTime(); var dtEnd = date.Date.AddDays(1).ToUniversalTime(); var options = new List <QueryOption> { new QueryOption("$filter", "receivedDateTime ge " + dtStart.ToString(DateTimeToFormatString) + " and receivedDateTime le " + dtEnd.ToString(DateTimeToFormatString)), }; var result = await _client.Me.Messages.Request(options).GetAsync(); if (result?.Count > 0) { var receivedUnfilter = new List <Message>(); receivedUnfilter.AddRange(result.CurrentPage); while (result.NextPageRequest != null) { result = await result.NextPageRequest.GetAsync(); receivedUnfilter.AddRange(result.CurrentPage); } // delete emails in IgnoreFolders and Drafts and IM-copies from S4B/Teams var ignoreFolders = await GetFoldersToIgnoreIds(); var emailsReceived = receivedUnfilter.Count(m => m.IsDraft == false && !ignoreFolders.Contains(m.ParentFolderId) && m.Subject != "IM"); return(emailsReceived); } return(0); } catch (Exception e) { Logger.WriteToLogFile(e); } return(Settings.NoValueDefault); }