public async Task<ActionResult> Register(string notificationUrl) { try { // Get an access token to use when calling the Outlook REST APIs. var token = await TokenHelper.GetTokenForApplicationAsync(TokenHelper.OutlookResourceID); var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); // Create and send a subscription message for newly created calendar events. var response = await httpClient.PostAsJsonAsync(TokenHelper.OutlookResourceID + "api/v2.0/me/subscriptions", new PushSubscriptionModel { NotificationURL = notificationUrl, Resource = TokenHelper.OutlookResourceID + "api/v2.0/me/events", ChangeType = "Created", ClientState = Guid.NewGuid() }); if (!response.IsSuccessStatusCode) { // Return to error page. return View("Error"); } // Deserialize the response. var responseString = await response.Content.ReadAsStringAsync(); var subscription = JsonConvert.DeserializeObject<PushSubscriptionModel>(responseString); // Save the subscription ID to map with the current user. var entities = new ApplicationDbContext(); entities.SubscriptionList.Add(new Subscription { SubscriptionId = subscription.Id, SubscriptionExpirationDateTime = subscription.SubscriptionExpirationDateTime, SignedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value, TenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value, UserObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value }); await entities.SaveChangesAsync(); return View("Success"); } catch (AdalException) { // Return to error page. return View("Error"); } // If the above failed, the user needs to explicitly re-authenticate for // the app to obtain the required token. catch (Exception) { return View("Relogin"); } }
/// <summary> /// Responds to requests generated by subscriptions registered with /// the Outlook Notifications REST API. /// </summary> /// <param name="validationToken">The validation token sent by Outlook when /// validating the Notification URL for the subscription.</param> public async Task<HttpResponseMessage> Post(string validationToken = null) { // If a validation token is present, we need to respond within 5 seconds. if (validationToken != null) { var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(validationToken); return response; } // Present only if the client specified the ClientState property in the // subscription request. IEnumerable<string> clientStateValues; Request.Headers.TryGetValues("ClientState", out clientStateValues); if (clientStateValues != null) { var clientState = clientStateValues.ToList().FirstOrDefault(); if (clientState != null) { // TODO: Use the client state to verify the legitimacy of the notification. } } // Read and parse the request body. var content = await Request.Content.ReadAsStringAsync(); var notifications = JsonConvert.DeserializeObject<ResponseModel<NotificationModel>>(content).Value; // TODO: Do something with the notification. var entities = new ApplicationDbContext(); foreach (var notification in notifications) { // Get the subscription from the database in order to locate the // user identifiers. This is used to tap the token cache. var subscription = entities.SubscriptionList.FirstOrDefault(s => s.SubscriptionId == notification.SubscriptionId); try { // Get an access token to use when calling the Outlook REST APIs. var token = await TokenHelper.GetTokenForApplicationAsync( subscription.SignedInUserID, subscription.TenantID, subscription.UserObjectID, TokenHelper.OutlookResourceID); var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); // Send a GET call to the monitored event. var responseString = await httpClient.GetStringAsync(notification.Resource); var calendarEvent = JsonConvert.DeserializeObject<CalendarEventModel>(responseString); // TODO: Do something with the calendar event. } catch (AdalException) { // TODO: Handle token error. } // If the above failed, the user needs to explicitly re-authenticate for // the app to obtain the required token. catch (Exception) { // TODO: Handle exception. } } return new HttpResponseMessage(HttpStatusCode.OK); }