private static async Task RunAsync() { AuthenticationConfig config = AuthenticationConfig.ReadFromJsonFile("appsettings.json"); // You can run this sample using ClientSecret or Certificate. The code will differ only when instantiating the IConfidentialClientApplication bool isUsingClientSecret = AppUsesClientSecret(config); // Even if this is a console application here, a daemon application is a confidential client application IConfidentialClientApplication app; if (isUsingClientSecret) { app = ConfidentialClientApplicationBuilder.Create(config.ClientId) .WithClientSecret(config.ClientSecret) .WithAuthority(new Uri(config.Authority)) .Build(); } else { X509Certificate2 certificate = ReadCertificate(config.CertificateName); app = ConfidentialClientApplicationBuilder.Create(config.ClientId) .WithCertificate(certificate) .WithAuthority(new Uri(config.Authority)) .Build(); } // With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the // application permissions need to be set statically (in the portal or by PowerShell), and then granted by // a tenant administrator. string[] scopes = new string[] { $"{config.ApiUrl}.default" }; AuthenticationResult result = null; try { result = await app.AcquireTokenForClient(scopes) .ExecuteAsync(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Token acquired"); Console.ResetColor(); } catch (MsalServiceException ex) when(ex.Message.Contains("AADSTS70011")) { // Invalid scope. The scope has to be of the form "https://resourceurl/.default" // Mitigation: change the scope to be as expected Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Scope provided is not supported"); Console.ResetColor(); } if (result != null) { var httpClient = new HttpClient(); var apiCaller = new ProtectedApiCallHelper(httpClient); //await apiCaller.CallWebApiAndProcessResultASync($"https://teamsgraph.teams.microsoft.com/beta/teams('250dfa22-2334-4d15-a7c0-7d3bb9303e36')/channels", result.AccessToken, Display); //await apiCaller.CallWebApiAndProcessResultASync($"https://graph.microsoft.com/beta/teams", result.AccessToken, Display); //Create Team with migration mode set - Copy the teamId from Response Header CreateTeam newTeam = new CreateTeam { teamCreationMode = "migration", bind = "https://graph.microsoft.com/beta/teamsTemplates('standard')", displayName = "MigrationTeam TestXYZ", description = "Migrate data into teams", createdDateTime = "2021-03-14T11:22:17.043Z" }; var data = new StringContent(JsonConvert.SerializeObject(newTeam), Encoding.UTF8, "application/json"); var response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams", result.AccessToken, Display, data); var location = response.Headers.Location?.ToString(); var teamId = ((location.Split('/')[1]).Remove(0, 7)).Remove(36, 2); var channelId = ""; CreateChannelRequest newChannel = new CreateChannelRequest { channelCreationMode = "migration", displayName = "Migration Channel TestXYZ", description = "New channel", membershipType = "standard", createdDateTime = "2021-03-14T11:22:17.043Z" }; data = new StringContent(JsonConvert.SerializeObject(newChannel), Encoding.UTF8, "application/json"); response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels", result.AccessToken, Display, data); if (response.IsSuccessStatusCode) { string json = await response.Content.ReadAsStringAsync(); channelId = JObject.Parse(json)["id"].ToString(); Console.WriteLine("ChannelId - " + channelId); } else { throw new Exception("Channel creation failed"); } if (channelId == "") { throw new Exception("Channel creation failed"); } ChatMessageRequest newMessage = new ChatMessageRequest { createdDateTime = "2021-03-12T11:22:17.043Z", from = new From { user = new User { id = "39c07c8d-ff89-4ef6-9855-2ec466148fe2", displayName = "*****@*****.**", userIdentityType = "aadUser" } }, body = new ItemBody { content = "Automated migrated msg", contentType = "html" } }; var str = JsonConvert.SerializeObject(newMessage); data = new StringContent(JsonConvert.SerializeObject(newMessage), Encoding.UTF8, "application/json"); response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/messages", result.AccessToken, Display, data); if (response.IsSuccessStatusCode) { Console.WriteLine("Posted msg"); } else { throw new Exception("Posting msg failed"); } response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/completeMigration", result.AccessToken, Display, null); if (response.IsSuccessStatusCode) { Console.WriteLine("Completed migration for channel"); } else { throw new Exception("Completing migration for channel failed"); } //Need to get the 'General' channel Id and complete migration TODO response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/completeMigration", result.AccessToken, Display, null); if (response.IsSuccessStatusCode) { Console.WriteLine("Completed migration for team"); } else { throw new Exception("Completing migration for team failed"); } //Add owner AddMemberToTeam member = new AddMemberToTeam { type = "#microsoft.graph.aadUserConversationMember", roles = new string[] { "owner" }, bind = "https://graph.microsoft.com/beta/users/39c07c8d-ff89-4ef6-9855-2ec466148fe2" }; data = new StringContent(JsonConvert.SerializeObject(member), Encoding.UTF8, "application/json"); await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/members", result.AccessToken, Display, data); } }
public async Task <bool> HandleMessageAsync(AbstractMessage message) { this._authenticateResult = await this._graphAuthService.GetGraphAuthResult(); try { if (this._authenticateResult != null) { var channelAddedMessage = (ChannelAddedMessage)message; var messages = await this._repository.GetChannelMessagesForChannelId(channelAddedMessage.ZoomChannelId); var channel = await this._repository.GetChannel(channelAddedMessage.ZoomChannelId); var apiCaller = new ProtectedApiCallHelper(_httpClient); //await apiCaller.CallWebApiAndProcessResultASync($"https://teamsgraph.teams.microsoft.com/beta/teams('250dfa22-2334-4d15-a7c0-7d3bb9303e36')/channels", result.AccessToken, Display); //await apiCaller.CallWebApiAndProcessResultASync($"https://graph.microsoft.com/beta/teams", result.AccessToken, Display); string currentTime = DateTime.Now.ToString("yyyy-mm-ddThh:mm:ss") + ".043Z"; string channelCreationTime = DateTime.Now.ToString("yyyy-mm-ddThh:mm:ss") + ".053Z"; //Create Team with migration mode set - Copy the teamId from Response Header CreateTeam newTeam = new CreateTeam { teamCreationMode = "migration", bind = "https://graph.microsoft.com/beta/teamsTemplates('standard')", displayName = "FromZoom" + channel.Name, description = channel.Name, createdDateTime = "2021-03-12T11:22:17.043Z" }; var data = new StringContent(JsonConvert.SerializeObject(newTeam), Encoding.UTF8, "application/json"); var response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams", this._authenticateResult.AccessToken, Display, data); var location = response.Headers.Location?.ToString(); var teamId = ((location.Split('/')[1]).Remove(0, 7)).Remove(36, 2); var channelId = ""; CreateChannelRequest newChannel = new CreateChannelRequest { channelCreationMode = "migration", displayName = channel.Name + "Test", description = channel.Name, membershipType = "standard", createdDateTime = "2021-03-12T11:22:17.053Z" }; data = new StringContent(JsonConvert.SerializeObject(newChannel), Encoding.UTF8, "application/json"); response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels", this._authenticateResult.AccessToken, Display, data); if (response.IsSuccessStatusCode) { string json = await response.Content.ReadAsStringAsync(); channelId = JObject.Parse(json)["id"].ToString(); Console.WriteLine("ChannelId - " + channelId); } else { throw new Exception("Channel creation failed"); } if (channelId == "") { throw new Exception("Channel creation failed"); } if (messages != null && messages.Count > 0) { foreach (ChannelMessage textMessage in messages) { DateTimeOffset timeOffset = DateTimeOffset.FromUnixTimeMilliseconds(textMessage.EpochTime); DateTime msgTime = timeOffset.DateTime; //textMessage.Sender var user = await this._repository.GetUserByZoomMailId(textMessage.Sender); if (user == null) { Console.WriteLine($"Zoom user {textMessage.Sender} did not login yet, so skipping message"); continue; } ChatMessageRequest newMessage = new ChatMessageRequest { createdDateTime = msgTime.ToString("yyyy-MM-ddThh:mm:ss") + ".053Z", from = new From { user = new User { id = user.AadUser.Id, displayName = user.AadUser.DisplayName, userIdentityType = "aadUser" } }, body = new ItemBody { content = textMessage.Message, contentType = "html" } }; var str = JsonConvert.SerializeObject(newMessage); data = new StringContent(JsonConvert.SerializeObject(newMessage), Encoding.UTF8, "application/json"); response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/messages", _authenticateResult.AccessToken, Display, data); if (response.IsSuccessStatusCode) { Console.WriteLine("Posted msg"); } else { throw new Exception("Posting msg failed"); } Thread.Sleep(100); } } response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/completeMigration", _authenticateResult.AccessToken, Display, null); if (response.IsSuccessStatusCode) { Console.WriteLine("Completed migration for newly created channel"); } else { throw new Exception("Completing migration for channel failed"); } string channelListResponse = await apiCaller.CallWebApiAndProcessResultASync($"https://graph.microsoft.com/v1.0/teams/{teamId}/channels", _authenticateResult.AccessToken); var teamsChannels = JsonConvert.DeserializeObject <TeamsChannelList>(channelListResponse); TeamsChannel generalChannel = teamsChannels.channels.Where(channel => channel.DisplayName.Equals("General")).First(); //Need to get the 'General' channel Id and complete migration TODO response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/channels/{generalChannel.Id}/completeMigration", _authenticateResult.AccessToken, Display, null); if (response.IsSuccessStatusCode) { Console.WriteLine("Completed migration for newly created channel"); } else { throw new Exception("Completing migration for channel failed"); } response = await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/completeMigration", _authenticateResult.AccessToken, Display, null); if (response.IsSuccessStatusCode) { Console.WriteLine("Completed migration for team"); } else { throw new Exception("Completing migration for team failed"); } //Add owner List <TodoListAPI.BusinessModels.User> owners = await _repository.GetOwnerOfZoomChannel(channelAddedMessage.ZoomChannelId); foreach (BusinessModels.User user in owners) { AddMemberToTeam member = new AddMemberToTeam { type = "#microsoft.graph.aadUserConversationMember", roles = new string[] { "owner" }, bind = $"https://graph.microsoft.com/beta/users/{user.AadUser.Id}" }; data = new StringContent(JsonConvert.SerializeObject(member), Encoding.UTF8, "application/json"); await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/members", _authenticateResult.AccessToken, Display, data); } // Add Member List <TodoListAPI.BusinessModels.User> members = await _repository.GetMembersOfZoomChannel(channelAddedMessage.ZoomChannelId); foreach (BusinessModels.User user in members) { AddMemberToTeam member = new AddMemberToTeam { type = "#microsoft.graph.aadUserConversationMember", roles = new string[] { }, bind = $"https://graph.microsoft.com/beta/users/{user.AadUser.Id}" }; data = new StringContent(JsonConvert.SerializeObject(member), Encoding.UTF8, "application/json"); await apiCaller.CallWebApiPostAndProcessResultASync($"https://graph.microsoft.com/beta/teams/{teamId}/members", _authenticateResult.AccessToken, Display, data); } } } catch (Exception) { message.RetryCount++; this._notifier.Notify(message); } return(true); }