public static async Task <string> GetUsersWithDelta(GraphServiceClient client, string deltaLink, ITargetBlock <User> target, CancellationToken token) { IUserDeltaCollectionPage page = new UserDeltaCollectionPage(); page.InitializeNextPageRequest(client, deltaLink); return(await GraphHelperUsers.GetUsersWithDelta(page, target, token)); }
public static IEnumerable <User> UsersDeltaQueryEfficient(RequestManager requestManager) { // Step 1: make a request to get the latest delta token, without returning any results. The goal is to obtain the current token, and later download the current resource state - efficiently string latestDeltaTokenUrl = $"{requestManager.GraphClient.BaseUrl}/users/delta?$deltaToken=latest"; var page = new UserDeltaCollectionPage(); page.InitializeNextPageRequest(requestManager.GraphClient, latestDeltaTokenUrl); var emptyPage = page.NextPageRequest.GetAsync().Result; var firstDeltaRequest = GetNextDeltaRequest(emptyPage, requestManager.GraphClient); // Step 2: download the current state of the User collection, efficiently var currentStateDict = UserScenarios.GetAllUsers(requestManager).ToDictionary(u => u.Id); // Step 3: pick up delta changes since before we downloaded the current state var changesSinceCurrentState = ExecuteDeltaCycle(firstDeltaRequest); // Step 4: merge changes into current state foreach (var change in changesSinceCurrentState) { currentStateDict[change.Id] = change; } // Step 5: we now have current state, get the delta link for future changes var deltaRequest = GetNextDeltaRequest(changesSinceCurrentState, requestManager.GraphClient); return(WaitForDeltaChanges(deltaRequest)); }
private static IUserDeltaCollectionPage ExecuteDeltaCycle(IUserDeltaRequest request) { IUserDeltaCollectionPage currentUserState = new UserDeltaCollectionPage(); IUserDeltaCollectionPage currentPage; do { currentPage = request.GetAsync().Result; foreach (var user in currentPage) { currentUserState.Add(user); } request = currentPage.NextPageRequest; } while (request != null); currentUserState.AdditionalData = currentPage.AdditionalData; return(currentUserState); }
/// <inheritdoc/> public async Task <(IEnumerable <User>, string)> GetAllUsersAsync(string deltaLink = null) { var users = new List <User>(); IUserDeltaCollectionPage collectionPage; if (string.IsNullOrEmpty(deltaLink)) { collectionPage = await this.graphServiceClient .Users .Delta() .Request() .Select("id, displayName, userPrincipalName, userType") .Top(GraphConstants.MaxPageSize) .WithMaxRetry(GraphConstants.MaxRetry) .GetAsync(); } else { collectionPage = new UserDeltaCollectionPage(); collectionPage.InitializeNextPageRequest(this.graphServiceClient, deltaLink); collectionPage = await collectionPage .NextPageRequest .WithMaxRetry(GraphConstants.MaxRetry) .GetAsync(); } users.AddRange(collectionPage); while (collectionPage.NextPageRequest != null) { collectionPage = await collectionPage .NextPageRequest .WithMaxRetry(GraphConstants.MaxRetry) .GetAsync(); users.AddRange(collectionPage); } collectionPage.AdditionalData.TryGetValue("@odata.deltaLink", out object delta); return(users, delta as string); }
public static async Task <List <string> > GetUsersAsync(GraphServiceClient graphClient, HttpContext httpContext) { IUserDeltaCollectionPage userPage = new UserDeltaCollectionPage(); userPage.InitializeNextPageRequest( graphClient, graphClient. Users. Delta(). Request(). Select("Id,displayName,userPrincipalName,mail"). RequestUrl); var pageRequestCount = 0; var userIds = new List <string>(); do { userPage = await userPage.NextPageRequest.GetAsync(CancellationToken.None); userPage .Where(_ => _.DisplayName != null) .ForEach(_ => { if (Startup.IsCosmosDbGraphEnabled) { CosmosDbGraphHelper.Users(_); userIds.Add(_.Id); } }); pageRequestCount++; }while (userPage.NextPageRequest != null && pageRequestCount < _maxPageRequestsPerTenant); return(userIds); }
public static async Task Run([TimerTrigger("0 */10 * * * *")] TimerInfo timer, ILogger log) { // アプリケーション設定を取得します var appConfig = new ConfigurationBuilder().AddEnvironmentVariables().Build(); var graphTenantId = appConfig.GetValue <string>("GraphTenantId"); var graphAuthority = appConfig.GetValue <string>("GraphAuthority"); var graphClientId = appConfig.GetValue <string>("GraphClientId"); var graphClientSecret = appConfig.GetValue <string>("GraphClientSecret"); var graphRedirectUrl = appConfig.GetValue <string>("GraphRedirectUrl"); var graphScope = appConfig.GetValue <string>("GraphScope"); var blobStorage = appConfig.GetValue <string>("BlobStorage"); var blobContainerName = appConfig.GetValue <string>("BlobContainerName"); var blobFileName = appConfig.GetValue <string>("BlobFileName"); var teamsGroupId = appConfig.GetValue <string>("TeamsGroupId"); var eventSenderId = appConfig.GetValue <string>("EventSenderId"); try { // OAuth の Access Token を取得します var clientCredential = new ClientCredential(graphClientSecret); var clientApplication = new ConfidentialClientApplication( graphClientId, graphAuthority + "/" + graphTenantId, graphRedirectUrl, clientCredential, null, null); var authenticationResult = await clientApplication.AcquireTokenForClientAsync(graphScope.Split(", ")); // Microsoft Graph Service Client を初期化します var graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(async msg => { await Task.Run(() => { msg.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken); }); })); // BLOB ストレージにファイルが存在するかどうかを確認します var storageAccount = CloudStorageAccount.Parse(blobStorage); var blobClient = storageAccount.CreateCloudBlobClient(); var blobContainer = blobClient.GetContainerReference(blobContainerName); var blobFile = blobContainer.GetBlockBlobReference(blobFileName); var userDeltaCollectionPage = default(IUserDeltaCollectionPage); if (await blobFile.ExistsAsync()) { // ファイルがある場合、前回からの差分のユーザーを取得します userDeltaCollectionPage = new UserDeltaCollectionPage(); userDeltaCollectionPage.InitializeNextPageRequest(graphClient, await blobFile.DownloadTextAsync()); userDeltaCollectionPage = await userDeltaCollectionPage.NextPageRequest.GetAsync(); } else { // ファイルがない場合、すべての差分を取得します userDeltaCollectionPage = await graphClient.Users.Delta().Request().GetAsync(); } // ページングして対象のユーザーのみをフィルターします var targetUsers = new List <User>(); while (true) { foreach (var user in userDeltaCollectionPage) { // 削除済みユーザーを除外します if (user.AdditionalData?.ContainsKey("@removed") != true) { // ライセンスのないユーザーを除外します var licenseDetails = await graphClient.Users[user.Id].LicenseDetails.Request().GetAsync(); var servicePlans = licenseDetails.SelectMany(ld => ld.ServicePlans).ToList(); if (servicePlans.Any(sp => sp.ServicePlanId == TeamsServicePlanId) && servicePlans.Any(sp => sp.ServicePlanId == ExchangeStandardServicePlanId || sp.ServicePlanId == ExchangeEnterpriseServicePlanId)) { targetUsers.Add(user); } } } // 次のページがない場合は処理を抜けます if (userDeltaCollectionPage.NextPageRequest == null) { break; } // 次のページを取得します userDeltaCollectionPage = await userDeltaCollectionPage.NextPageRequest.GetAsync(); } // ユーザーを Teams のメンバーとして追加します foreach (var user in targetUsers) { try { await graphClient.Groups[teamsGroupId].Members.References.Request().AddAsync(user); } catch (Exception) { // 追加済みの場合があるためエラーは無視します } } // ユーザーに会議出席依頼を送付します if (targetUsers.Any()) { await graphClient.Users[eventSenderId].Events.Request().AddAsync(new Event() { Attendees = targetUsers.Select(user => new Attendee() { EmailAddress = new EmailAddress() { Address = user.Mail, Name = user.DisplayName }, Type = AttendeeType.Required }), Subject = "新入社員向け説明会", Body = new ItemBody() { ContentType = BodyType.Html, Content = "<p>お疲れさまです。</p>" + "<p>新入社員向け説明会を開催しますのでご参集ください。</p>" + "<p>よろしくお願いします。</p>", }, Start = new DateTimeTimeZone() { DateTime = DateTime.Today.AddDays(2).AddHours(9).ToString("s"), TimeZone = "Tokyo Standard Time" }, End = new DateTimeTimeZone() { DateTime = DateTime.Today.AddDays(2).AddHours(18).ToString("s"), TimeZone = "Tokyo Standard Time" }, }); } // deltaLink を BLOB ストレージに保存します if (userDeltaCollectionPage.AdditionalData.TryGetValue("@odata.deltaLink", out var deltaLink)) { await blobContainer.CreateIfNotExistsAsync(); await blobFile.UploadTextAsync(deltaLink.ToString()); } } catch (Exception ex) { log.LogError(ex.ToString()); } }