public async Task AddParticipantsShouldExposePartialErrors()
        {
            //arrange
            var threadId = "19:[email protected]";
            var uri      = new Uri("https://localHostTest");
            var communicationTokenCredential = new CommunicationTokenCredential(ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue);
            var mockResponse = new MockResponse(201);

            mockResponse.SetContent(AddParticipantsdWithErrorsApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(mockResponse)
            };

            //act
            var chatClient = new ChatClient(uri, communicationTokenCredential, chatClientOptions);
            ChatThreadClient          chatThreadClient          = chatClient.GetChatThreadClient(threadId);
            AddChatParticipantsResult addChatParticipantsResult = await chatThreadClient.AddParticipantsAsync(new List <ChatParticipant>());

            //assert
            AsssertParticipantError(addChatParticipantsResult.Errors.InvalidParticipants.First(x => x.Code == "401"), "Authentication failed", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345678");
            AsssertParticipantError(addChatParticipantsResult.Errors.InvalidParticipants.First(x => x.Code == "403"), "Permissions check failed", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345679");
            AsssertParticipantError(addChatParticipantsResult.Errors.InvalidParticipants.First(x => x.Code == "404"), "Not found", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345677");
            Assert.AreEqual(3, addChatParticipantsResult.Errors.InvalidParticipants.Count);
        }
Ejemplo n.º 2
0
        private static HttpPipeline CreatePipelineFromOptions(ChatClientOptions options, CommunicationUserCredential communicationUserCredential)
        {
            var tokenCredential      = new CommunicationTokenCredential(communicationUserCredential);
            var authenticationPolicy = new BearerTokenAuthenticationPolicy(tokenCredential, "");

            return(HttpPipelineBuilder.Build(options, authenticationPolicy));
        }
        public async Task CreateChatThreadShouldExposePartialErrors()
        {
            //arrange
            var uri = new Uri("https://localHostTest");
            var communicationTokenCredential = new CommunicationTokenCredential(ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue);
            var mockResponse = new MockResponse(201);

            mockResponse.SetContent(CreateChatThreadWithErrorsApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(mockResponse)
            };

            //act
            var chatClient = new ChatClient(uri, communicationTokenCredential, chatClientOptions);
            CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync("", new List <ChatParticipant>());

            //assert
            AsssertParticipantError(createChatThreadResult.Errors.InvalidParticipants.First(x => x.Code == "401"), "Authentication failed", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345678");
            AsssertParticipantError(createChatThreadResult.Errors.InvalidParticipants.First(x => x.Code == "403"), "Permissions check failed", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345679");
            AsssertParticipantError(createChatThreadResult.Errors.InvalidParticipants.First(x => x.Code == "404"), "Not found", "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-1234-1234-1234-223a12345677");

            Assert.AreEqual(3, createChatThreadResult.Errors.InvalidParticipants.Count);
            Assert.AreEqual("8:acs:46849534-eb08-4ab7-bde7-c36928cd1547_00000007-165c-9b10-b0b7-3a3a0d00076c", createChatThreadResult.ChatThread.CreatedBy.Id);
            Assert.AreEqual("Topic for testing errors", createChatThreadResult.ChatThread.Topic);
            Assert.AreEqual("19:[email protected]", createChatThreadResult.ChatThread.Id);
        }
        public async Task OrderInGetReadReceiptsIteratorIsNotAltered()
        {
            //arrange
            var threadId         = "19:[email protected]";
            var baseSenderId     = "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-0464-274b-b274-5a3a0d00010";
            var baseReadOnDate   = DateTimeOffset.Parse("2020-12-15T00:00:00Z");
            var uri              = new Uri("https://localHostTest");
            var responseAllItems = new MockResponse(200);

            responseAllItems.SetContent(AllReadReceiptsApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(responseAllItems)
            };

            //act
            var communicationTokenCredential = new CommunicationTokenCredential(ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue);
            var chatClient = new ChatClient(uri, communicationTokenCredential, chatClientOptions);
            ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId);

            AsyncPageable <ChatMessageReadReceipt> allReadReceipts = chatThreadClient.GetReadReceiptsAsync();

            //assert
            int idCounter = 0;

            await foreach (ChatMessageReadReceipt readReceipt in allReadReceipts)
            {
                idCounter++;
                Assert.AreEqual($"{idCounter}", readReceipt.ChatMessageId);
                Assert.AreEqual($"{baseSenderId}{idCounter}", readReceipt.SenderId);
                Assert.AreEqual(baseReadOnDate.AddSeconds(idCounter), readReceipt.ReadOn);
            }
            Assert.AreEqual(5, idCounter);
        }
Ejemplo n.º 5
0
 /// <summary>Initializes a new instance of <see cref="ChatClient"/> for mocking.</summary>
 protected ChatClient()
 {
     _clientDiagnostics            = null !;
     _chatRestClient               = null !;
     _endpointUrl                  = null !;
     _communicationTokenCredential = null !;
     _chatClientOptions            = null !;
 }
        public async Task <bool> Init(string token)
        {
            var credentials = new CommunicationTokenCredential(token);

            _callClient = new CallClient();
            _callAgent  = (CallAgent)await _callClient.CreateCallAgent(Application.Context, credentials).GetAsync();

            _deviceManager = (DeviceManager)await _callClient.DeviceManager.GetAsync();

            return(true);
        }
Ejemplo n.º 7
0
        public async Task <bool> Init(string token)
        {
            var credentials = new CommunicationTokenCredential(token);

            _callClient = new CallClient();
            var callOptions = new CallAgentOptions();

            _callAgent     = Com.Laerdal.Azurecommunicationhelper.CallClientHelper.GetCallAgent(_callClient, Application.Context, credentials);
            _deviceManager = Com.Laerdal.Azurecommunicationhelper.CallClientHelper.GetDeviceManager(_callClient, Application.Context);
            return(true);
        }
        /// <summary>
        /// Creates a <see cref="ChatClient" /> with a static token and instruments it to make use of
        /// the Azure Core Test Framework functionalities.
        /// </summary>
        /// <returns>The instrumented <see cref="ChatClient" />.</returns>
        protected ChatClient CreateInstrumentedChatClient(string token)
        {
            if (Mode == RecordedTestMode.Playback)
            {
                token = ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue;
            }

            CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(token);

            return(InstrumentClient(new ChatClient(TestEnvironment.LiveTestDynamicEndpoint, communicationTokenCredential,
                                                   CreateChatClientOptionsWithCorrelationVectorLogs())));
        }
Ejemplo n.º 9
0
        /// <summary> Initializes a new instance of <see cref="ChatThreadClient"/>.</summary>
        /// <param name="threadId"></param>
        /// <param name="endpointUrl">The uri for the Azure Communication Services Chat.</param>
        /// <param name="communicationTokenCredential">Instance of <see cref="CommunicationTokenCredential"/>.</param>
        /// <param name="options">Chat client options exposing <see cref="ClientOptions.Diagnostics"/>, <see cref="ClientOptions.Retry"/>, <see cref="ClientOptions.Transport"/>, etc.</param>
        /// <exception cref="ArgumentNullException"> This occurs when one of the required arguments is null. </exception>
        internal ChatThreadClient(string threadId, Uri endpointUrl, CommunicationTokenCredential communicationTokenCredential, ChatClientOptions?options = default)
        {
            Argument.AssertNotNull(threadId, nameof(threadId));
            Argument.AssertNotNull(communicationTokenCredential, nameof(communicationTokenCredential));
            Argument.AssertNotNull(endpointUrl, nameof(endpointUrl));
            options ??= new ChatClientOptions();
            Id = threadId;
            _clientDiagnostics = new ClientDiagnostics(options);
            HttpPipeline pipeline = CreatePipelineFromOptions(options, communicationTokenCredential);

            _chatRestClient = new ChatRestClient(_clientDiagnostics, pipeline, endpointUrl.AbsoluteUri, options.ApiVersion);
        }
Ejemplo n.º 10
0
        /// <summary> Initializes a new instance of <see cref="ChatClient"/>.</summary>
        /// <param name="endpointUrl">The uri for the Azure Communication Services Chat.</param>
        /// <param name="communicationTokenCredential">Instance of <see cref="CommunicationTokenCredential"/>.</param>
        /// <param name="options">Chat client options exposing <see cref="ClientOptions.Diagnostics"/>, <see cref="ClientOptions.Retry"/>, <see cref="ClientOptions.Transport"/>, etc.</param>
        public ChatClient(Uri endpointUrl, CommunicationTokenCredential communicationTokenCredential, ChatClientOptions?options = default)
        {
            Argument.AssertNotNull(communicationTokenCredential, nameof(communicationTokenCredential));
            Argument.AssertNotNull(endpointUrl, nameof(endpointUrl));
            _chatClientOptions            = options ?? new ChatClientOptions();
            _communicationTokenCredential = communicationTokenCredential;
            _endpointUrl       = endpointUrl;
            _clientDiagnostics = new ClientDiagnostics(_chatClientOptions);
            HttpPipeline pipeline = CreatePipelineFromOptions(_chatClientOptions, communicationTokenCredential);

            _chatRestClient = new ChatRestClient(_clientDiagnostics, pipeline, endpointUrl.AbsoluteUri, _chatClientOptions.ApiVersion);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Creates a <see cref="ChatClient" /> with a static token and instruments it to make use of
        /// the Azure Core Test Framework functionalities.
        /// </summary>
        /// <returns>The instrumented <see cref="ChatClient" />.</returns>
        protected ChatClient CreateInstrumentedChatClient(string token)
        {
            if (Mode == RecordedTestMode.Playback)
            {
                token = ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue;
            }

            CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(token);

            return(InstrumentClient(new ChatClient(new Uri(TestEnvironment.ChatApiUrl()), communicationTokenCredential,
                                                   InstrumentClientOptions(new ChatClientOptions()))));
        }
Ejemplo n.º 12
0
        public async Task OrderInGetMessagesIteratorIsNotAlteredByPaging()
        {
            //arrange
            var threadId = "19:[email protected]";
            var uri      = new Uri("https://localHostTest");

            var responseItemsPage1 = new MockResponse(200);

            responseItemsPage1.SetContent(Page1MessagesApiResponsePayload);

            var responseItemsPage2 = new MockResponse(200);

            responseItemsPage2.SetContent(Page2MessagesApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(responseItemsPage1, responseItemsPage2)
            };

            //act
            var communicationTokenCredential = new CommunicationTokenCredential(ChatLiveTestBase.SanitizedUnsignedUserTokenValue);
            var chatClient = new ChatClient(uri, communicationTokenCredential, chatClientOptions);
            ChatThreadClient            chatThreadClient = chatClient.GetChatThreadClient(threadId);
            AsyncPageable <ChatMessage> allMessages      = chatThreadClient.GetMessagesAsync();

            //assert
            int pages               = 0;
            int idCounter           = 0;
            int textMessagesCounter = 0;

            await foreach (Page <ChatMessage> page in allMessages.AsPages(pageSizeHint: 4))
            {
                pages++;
                foreach (ChatMessage message in page.Values)
                {
                    idCounter++;
                    Assert.AreEqual($"{idCounter}", message.Id);
                    Assert.AreEqual($"{idCounter}", message.Version);
                    if (message.Type == "text")
                    {
                        textMessagesCounter++;
                        Assert.AreEqual($"Content for async message{idCounter}", message.Content.Message);
                    }
                }
            }
            Assert.AreEqual(2, pages);
            Assert.AreEqual(8, idCounter);
            Assert.AreEqual(5, textMessagesCounter);
        }
Ejemplo n.º 13
0
        public async Task OrderInGetReadReceiptsIteratorIsNotAlteredByPaging()
        {
            //arrange
            var threadId       = "19:[email protected]";
            var uri            = new Uri("https://localHostTest");
            var baseSenderId   = "8:acs:1b5cc06b-f352-4571-b1e6-d9b259b7c776_00000007-0464-274b-b274-5a3a0d00010";
            var baseReadOnDate = DateTimeOffset.Parse("2020-12-15T00:00:00Z");

            var responseItemsPage1 = new MockResponse(200);

            responseItemsPage1.SetContent(Page1ReadReceiptsApiResponsePayload);

            var responseItemsPage2 = new MockResponse(200);

            responseItemsPage2.SetContent(Page2ReadReceiptsApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(responseItemsPage1, responseItemsPage2)
            };

            //act
            var communicationTokenCredential = new CommunicationTokenCredential(ChatLiveTestBase.SanitizedUnsignedUserTokenValue);
            var chatClient = new ChatClient(uri, communicationTokenCredential, chatClientOptions);
            ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId);
            AsyncPageable <ChatMessageReadReceipt> allreadReceipts = chatThreadClient.GetReadReceiptsAsync();

            //assert
            int pages     = 0;
            int idCounter = 0;

            //string? continuationToken = null;
            await foreach (Page <ChatMessageReadReceipt> page in allreadReceipts.AsPages(pageSizeHint: 3))
            {
                pages++;
                foreach (ChatMessageReadReceipt readReceipt in page.Values)
                {
                    idCounter++;
                    Assert.AreEqual($"{idCounter}", readReceipt.ChatMessageId);
                    Assert.AreEqual($"{baseSenderId}{idCounter}", ((UnknownIdentifier)readReceipt.Sender).Id);
                    Assert.AreEqual(baseReadOnDate.AddSeconds(idCounter), readReceipt.ReadOn);
                }
                //continuationToken = page.ContinuationToken;
            }
            Assert.AreEqual(2, pages);
            Assert.AreEqual(5, idCounter);
        }
        public async Task <IActionResult> User(InputMessage input)
        {
            User   user             = new User();
            string connectionString = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING");
            var    client           = new CommunicationIdentityClient(connectionString);
            var    identity         = new Azure.Communication.CommunicationUserIdentifier(user.UserID);
            var    tokenResponse    = await client.GetTokenAsync(identity, scopes : new[] { CommunicationTokenScope.Chat });

            user.AccessToken = tokenResponse.Value.Token;
            Console.WriteLine(user.AccessToken);

            Uri endpoint = new Uri("https://haroldtest.communication.azure.com");
            CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(user.AccessToken);
            ChatClient chatClient = new ChatClient(endpoint, communicationTokenCredential);

            Azure.Pageable <ChatThreadItem> threadItems = chatClient.GetChatThreads();
            List <ChatThreadClient>         ctclients   = new List <ChatThreadClient>();

            foreach (ChatThreadItem item in threadItems)
            {
                ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(item.Id);
                ctclients.Add(chatThreadClient);
            }

            SendChatMessageResult sendChatMessageResult = await ctclients[input.ThreadIndex].SendMessageAsync(content: input.Message, type: ChatMessageType.Text, senderDisplayName: user.Name);
            string messageId = sendChatMessageResult.Id;

            Console.WriteLine(messageId);

            foreach (ChatThreadItem item in threadItems)
            {
                ChatThreadClient             chatThreadClient = chatClient.GetChatThreadClient(item.Id);
                Azure.Pageable <ChatMessage> messages         = chatThreadClient.GetMessages();
                List <ChatMessage>           messageList      = new List <ChatMessage>();
                foreach (ChatMessage message in messages)
                {
                    messageList.Add(message);
                }
                ChatThread thread = new ChatThread(item.Id, item.Topic, messageList);
                user.Threads.Add(thread);
            }
            Console.WriteLine(user.Threads[0].Topic);
            Console.WriteLine(user.Threads[1].Topic);
            ViewBag.user = user;
            return(View());
        }
Ejemplo n.º 15
0
        private ChatClient CreateMockChatClient(int responseCode, string?responseContent = null)
        {
            var uri = new Uri("https://localHostTest");
            var communicationTokenCredential = new CommunicationTokenCredential(ChatLiveTestBase.SanitizedUnsignedUserTokenValue);
            var mockResponse = new MockResponse(responseCode);

            if (responseContent != null)
            {
                mockResponse.SetContent(responseContent);
            }

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(mockResponse)
            };

            return(new ChatClient(uri, communicationTokenCredential, chatClientOptions));
        }
        public async Task <IActionResult> User()
        {
            User user = new User();
            async System.Threading.Tasks.Task UserThreads()
            {
                string connectionString = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING");
                var    client           = new CommunicationIdentityClient(connectionString);
                //var identityResponse = await client.CreateUserAsync();
                //var identity = identityResponse.Value;
                //Console.WriteLine(identity);
                var identity      = new Azure.Communication.CommunicationUserIdentifier(user.UserID);
                var tokenResponse = await client.GetTokenAsync(identity, scopes : new[] { CommunicationTokenScope.Chat });

                user.AccessToken = tokenResponse.Value.Token;
                Console.WriteLine(user.AccessToken);

                Uri endpoint = new Uri("https://haroldtest.communication.azure.com");
                CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(user.AccessToken);
                ChatClient chatClient = new ChatClient(endpoint, communicationTokenCredential);

                Azure.Pageable <ChatThreadItem> threadItems = chatClient.GetChatThreads();
                foreach (ChatThreadItem item in threadItems)
                {
                    ChatThreadClient             chatThreadClient = chatClient.GetChatThreadClient(item.Id);
                    Azure.Pageable <ChatMessage> messages         = chatThreadClient.GetMessages();
                    List <ChatMessage>           messageList      = new List <ChatMessage>();
                    foreach (ChatMessage message in messages)
                    {
                        messageList.Add(message);
                    }
                    ChatThread thread = new ChatThread(item.Id, item.Topic, messageList);
                    user.Threads.Add(thread);
                }
                Console.WriteLine(user.Threads[0].Topic);
                Console.WriteLine(user.Threads[1].Topic);
            }

            await UserThreads();

            Console.WriteLine(user.Threads[0].Topic);
            ViewBag.user = user;
            return(View());
        }
        private async void CallButton_ClickAsync(object sender, RoutedEventArgs e)
        {
            CommunicationTokenCredential token_credential = new CommunicationTokenCredential("<USER_ACCESS_TOKEN>");

            call_client_ = new CallClient();

            CallAgentOptions callAgentOptions = new CallAgentOptions()
            {
                DisplayName = "<YOUR_DISPLAY_NAME>"
            };

            call_agent_ = await call_client_.CreateCallAgent(token_credential, callAgentOptions);

            StartCallOptions startCallOptions = new StartCallOptions();

            ICommunicationIdentifier[] callees = new ICommunicationIdentifier[1]
            {
                new CommunicationUserIdentifier(CalleeTextBox.Text)
            };

            call_ = await call_agent_.StartCallAsync(callees, startCallOptions);
        }
Ejemplo n.º 18
0
        public async Task OrderInGetMessagesIteratorIsNotAltered()
        {
            //arrange
            var threadId         = "19:[email protected]";
            var uri              = new Uri("https://localHostTest");
            var responseAllItems = new MockResponse(200);

            responseAllItems.SetContent(_allMessagesApiResponsePayload);

            var chatClientOptions = new ChatClientOptions
            {
                Transport = new MockTransport(responseAllItems)
            };

            //act
            var communicationTokenCredential        = new CommunicationTokenCredential(ChatRecordedTestSanitizer.SanitizedUnsignedUserTokenValue);
            var chatThreadClient                    = new ChatThreadClient(threadId, uri, communicationTokenCredential, chatClientOptions);
            AsyncPageable <ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();

            //assert
            int idCounter           = 0;
            int textMessagesCounter = 0;

            await foreach (ChatMessage message in allMessages)
            {
                idCounter++;
                Assert.AreEqual($"{idCounter}", message.Id);
                Assert.AreEqual($"{idCounter}", message.Version);
                if (message.Type == "Text")
                {
                    textMessagesCounter++;
                    Assert.AreEqual($"Content for async message {idCounter}", message.Content);
                }
            }
            Assert.AreEqual(8, idCounter);
            Assert.AreEqual(5, textMessagesCounter);
        }
Ejemplo n.º 19
0
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            Uri endpoint = new Uri("https://<RESOURCE_NAME>.communication.azure.com");

            CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential("<Access_Token>");
            ChatClient chatClient = new ChatClient(endpoint, communicationTokenCredential);

            // <Start a chat thread>
            var chatParticipant = new ChatParticipant(identifier: new CommunicationUserIdentifier(id: "<Access_ID>"))
            {
                DisplayName = "UserDisplayName"
            };
            CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(topic : "Hello world!", participants : new[] { chatParticipant });

            // <Get a chat thread client>
            ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId: createChatThreadResult.ChatThread.Id);
            string           threadId         = chatThreadClient.Id;

            // <List all chat threads>
            AsyncPageable <ChatThreadItem> chatThreadItems = chatClient.GetChatThreadsAsync();

            await foreach (ChatThreadItem chatThreadItem in chatThreadItems)
            {
                Console.WriteLine($"{ chatThreadItem.Id}");
            }

            // <Send a message to a chat thread>
            SendChatMessageResult sendChatMessageResult = await chatThreadClient.SendMessageAsync(content : "hello world", type : ChatMessageType.Text);

            string messageId = sendChatMessageResult.Id;

            // <Receive chat messages from a chat thread>
            AsyncPageable <ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();

            await foreach (ChatMessage message in allMessages)
            {
                Console.WriteLine($"{message.Id}:{message.Content.Message}");
            }

            // <Add a user as a participant to the chat thread>
            var josh   = new CommunicationUserIdentifier(id: "<Access_ID_For_Josh>");
            var gloria = new CommunicationUserIdentifier(id: "<Access_ID_For_Gloria>");
            var amy    = new CommunicationUserIdentifier(id: "<Access_ID_For_Amy>");

            var participants = new[]
            {
                new ChatParticipant(josh)
                {
                    DisplayName = "Josh"
                },
                new ChatParticipant(gloria)
                {
                    DisplayName = "Gloria"
                },
                new ChatParticipant(amy)
                {
                    DisplayName = "Amy"
                }
            };
            await chatThreadClient.AddParticipantsAsync(participants : participants);

            // <Get thread participants>
            AsyncPageable <ChatParticipant> allParticipants = chatThreadClient.GetParticipantsAsync();

            await foreach (ChatParticipant participant in allParticipants)
            {
                Console.WriteLine($"{((CommunicationUserIdentifier)participant.User).Id}:{participant.DisplayName}:{participant.ShareHistoryTime}");
            }

            // <Send read receipt>
            await chatThreadClient.SendReadReceiptAsync(messageId : messageId);
        }