Skip to content

Jimin/2025 ga #50191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions sdk/communication/Azure.Communication.Chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ Once you initialized a `ChatClient` class, you can do the following chat operati

### Create a thread
```C# Snippet:Azure_Communication_Chat_Tests_Samples_CreateThread_KeyConcepts
CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(topic: "Hello world!", participants: new ChatParticipant[] { });
CreateChatThreadOptions createChatThreadOptions = new CreateChatThreadOptions("Hello world!");

createChatThreadOptions.Metadata.Add("MetadataKey1", "MetadataValue1");
createChatThreadOptions.Metadata.Add("MetadataKey2", "MetadataValue2");

createChatThreadOptions.RetentionPolicy = new ThreadCreationDateRetentionPolicy(40);

CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(createChatThreadOptions);
ChatThreadProperties chatThread = createChatThreadResult.ChatThread;
```
### Get a thread
Expand All @@ -85,9 +92,12 @@ Once you initialized a `ChatThreadClient` class, you can do the following chat o

### Update a thread
```C# Snippet:Azure_Communication_Chat_Tests_Samples_UpdateThread_KeyConcepts
chatThreadClient.UpdateTopic(topic: "Launch meeting");
UpdateChatThreadPropertiesOptions updateChatThreadPropertiesOptions = new UpdateChatThreadPropertiesOptions();
updateChatThreadPropertiesOptions.Topic = "Launch meeting";
updateChatThreadPropertiesOptions.Metadata.Add("UpdateMetadataKey", "UpdateMetadataValue");
updateChatThreadPropertiesOptions.RetentionPolicy = new NoneRetentionPolicy();
await chatThreadClient.UpdatePropertiesAsync(updateChatThreadPropertiesOptions);
```

### Send a message
```C# Snippet:Azure_Communication_Chat_Tests_Samples_SendMessage_KeyConcepts
SendChatMessageResult sendChatMessageResult = chatThreadClient.SendMessage("Let's meet at 11am");
Expand Down Expand Up @@ -179,7 +189,20 @@ var chatParticipant = new ChatParticipant(identifier: kimberly)
{
DisplayName = "Kim"
};
CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(topic: "Hello world!", participants: new[] { chatParticipant });

chatParticipant.Metadata.Add("MetadataKey1", "MetadataValue1");
chatParticipant.Metadata.Add("MetadataKey2", "MetadataValue2");

CreateChatThreadOptions createChatThreadOptions = new CreateChatThreadOptions("Hello world!");

createChatThreadOptions.Participants.Add(chatParticipant);

createChatThreadOptions.Metadata.Add("MetadataKey1", "MetadataValue1");
createChatThreadOptions.Metadata.Add("MetadataKey2", "MetadataValue2");

createChatThreadOptions.RetentionPolicy = new ThreadCreationDateRetentionPolicy(60);

CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(createChatThreadOptions);
string threadId = createChatThreadResult.ChatThread.Id;
ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId);
```
Expand Down Expand Up @@ -215,11 +238,13 @@ await chatClient.DeleteChatThreadAsync(threadId);

### Update a thread

Use `UpdateTopic` to update the chat thread topic.
- `topic` is used to describe the updated topic for the thread.

Use `UpdatePropertiesAsync` to update the chat thread topic or metadata.
```C# Snippet:Azure_Communication_Chat_Tests_Samples_UpdateThread
await chatThreadClient.UpdateTopicAsync(topic: "new topic !");
UpdateChatThreadPropertiesOptions updateChatThreadPropertiesOptions = new UpdateChatThreadPropertiesOptions();
updateChatThreadPropertiesOptions.Topic = "new topic !";
updateChatThreadPropertiesOptions.Metadata.Add("UpdateMetadataKey", "UpdateMetadataValue");
updateChatThreadPropertiesOptions.RetentionPolicy = new ThreadCreationDateRetentionPolicy(60);
await chatThreadClient.UpdatePropertiesAsync(updateChatThreadPropertiesOptions);
```

## Message Operations
Expand Down Expand Up @@ -376,12 +401,12 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m
[coc_contact]: mailto:[email protected]
[nuget]: https://www.nuget.org/
[netstandars2mappings]:https://github.com/dotnet/standard/blob/master/docs/versions.md
[useraccesstokens]:https://learn.microsoft.com/azure/communication-services/quickstarts/access-tokens?pivots=programming-language-csharp
[communication_resource_docs]: https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp
[communication_resource_create_portal]: https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp
[communication_resource_create_power_shell]: https://learn.microsoft.com/powershell/module/az.communication/new-azcommunicationservice
[communication_resource_create_net]: https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-net
[nextsteps]:https://learn.microsoft.com/azure/communication-services/quickstarts/chat/get-started?pivots=programming-language-csharp
[useraccesstokens]:https://docs.microsoft.com/azure/communication-services/quickstarts/access-tokens?pivots=programming-language-csharp
[communication_resource_docs]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp
[communication_resource_create_portal]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp
[communication_resource_create_power_shell]: https://docs.microsoft.com/powershell/module/az.communication/new-azcommunicationservice
[communication_resource_create_net]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-net
[nextsteps]:https://docs.microsoft.com/azure/communication-services/quickstarts/chat/get-started?pivots=programming-language-csharp
[source]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/communication/Azure.Communication.Chat/src
[product_docs]: https://learn.microsoft.com/azure/communication-services/overview
[product_docs]: https://docs.microsoft.com/azure/communication-services/overview
[package]: https://www.nuget.org/packages/Azure.Communication.Chat
66 changes: 63 additions & 3 deletions sdk/communication/Azure.Communication.Chat/src/ChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,57 @@ public virtual async Task<Response<CreateChatThreadResult>> CreateChatThreadAsyn
scope.Start();
try
{
Response<CreateChatThreadResultInternal> createChatThreadResultInternal = await _chatRestClient.CreateChatThreadAsync(topic, idempotencyToken, participants.Select(x => x.ToChatParticipantInternal()), cancellationToken).ConfigureAwait(false);
var createChatThreadOptions = new CreateChatThreadOptions(topic)
{
IdempotencyToken = idempotencyToken,
};

foreach (var value in participants.ToList())
{
createChatThreadOptions.Participants.Add(value);
}

Response<CreateChatThreadResultInternal> createChatThreadResultInternal = await _chatRestClient.CreateChatThreadAsync(createChatThreadOptions, cancellationToken).ConfigureAwait(false);
return Response.FromValue(new CreateChatThreadResult(createChatThreadResultInternal.Value), createChatThreadResultInternal.GetRawResponse());
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
}

/// <summary>Creates a ChatThreadClient asynchronously. <see cref="ChatThreadClient"/>.</summary>
/// <param name = "options" > CreateChatThreadOptions </param>
/// <param name="cancellationToken">The cancellation token for the task.</param>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual async Task<Response<CreateChatThreadResult>> CreateChatThreadAsync(CreateChatThreadOptions options, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ChatClient)}.{nameof(CreateChatThread)}");
scope.Start();
try
{
Response<CreateChatThreadResultInternal> createChatThreadResultInternal = await _chatRestClient.CreateChatThreadAsync(options).ConfigureAwait(false);
return Response.FromValue(new CreateChatThreadResult(createChatThreadResultInternal.Value), createChatThreadResultInternal.GetRawResponse());
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
}

/// <summary>Creates a ChatThreadClient asynchronously. <see cref="ChatThreadClient"/>.</summary>
/// <param name = "options" > CreateChatThread Options</param>
/// <param name="cancellationToken">The cancellation token for the task.</param>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual Response<CreateChatThreadResult> CreateChatThread(CreateChatThreadOptions options, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ChatClient)}.{nameof(CreateChatThread)}");
scope.Start();
try
{
Response<CreateChatThreadResultInternal> createChatThreadResultInternal = _chatRestClient.CreateChatThread(options, cancellationToken);
return Response.FromValue(new CreateChatThreadResult(createChatThreadResultInternal.Value), createChatThreadResultInternal.GetRawResponse());
}
catch (Exception ex)
Expand All @@ -84,7 +134,17 @@ public virtual Response<CreateChatThreadResult> CreateChatThread(string topic, I
scope.Start();
try
{
Response<CreateChatThreadResultInternal> createChatThreadResultInternal = _chatRestClient.CreateChatThread(topic, idempotencyToken,participants.Select(x => x.ToChatParticipantInternal()), cancellationToken);
var createChatThreadOptions = new CreateChatThreadOptions(topic)
{
IdempotencyToken = idempotencyToken,
};

foreach (var value in participants.ToList())
{
createChatThreadOptions.Participants.Add(value);
}

Response<CreateChatThreadResultInternal> createChatThreadResultInternal = _chatRestClient.CreateChatThread(createChatThreadOptions);
return Response.FromValue(new CreateChatThreadResult(createChatThreadResultInternal.Value), createChatThreadResultInternal.GetRawResponse());
}
catch (Exception ex)
Expand Down Expand Up @@ -193,7 +253,7 @@ Page<ChatThreadItem> NextPageFunc(string nextLink, int? pageSizeHint)
throw;
}
}
return PageableHelpers.CreateEnumerable(FirstPageFunc, NextPageFunc);
return PageableHelpers.CreateEnumerable(FirstPageFunc, NextPageFunc);
}

/// <summary> Deletes a thread asynchronously. </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ChatClientOptions : ClientOptions
/// <summary>
/// The latest version of the Chat service.
/// </summary>
internal const ServiceVersion LatestVersion = ServiceVersion.V2024_03_07;
internal const ServiceVersion LatestVersion = ServiceVersion.V2025_03_15;

internal string ApiVersion { get; }

Expand All @@ -29,6 +29,7 @@ public ChatClientOptions(ServiceVersion version = LatestVersion)
ServiceVersion.V2021_09_07 => "2021-09-07",
ServiceVersion.V2023_11_07 => "2023-11-07",
ServiceVersion.V2024_03_07 => "2024-03-07",
ServiceVersion.V2025_03_15 => "2025-03-15",
_ => throw new ArgumentOutOfRangeException(nameof(version)),
};
}
Expand Down Expand Up @@ -57,7 +58,12 @@ public enum ServiceVersion
/// The V2024_03_07 of the Chat service.
/// </summary>
#pragma warning restore CA1707 // Identifiers should not contain underscores
V2024_03_07 = 4
V2024_03_07 = 4,
/// <summary>
/// The V2025_03_15 of the Chat service.
/// </summary>
#pragma warning restore CA1707 // Identifiers should not contain underscores
V2025_03_15 = 5
}
}
}
58 changes: 34 additions & 24 deletions sdk/communication/Azure.Communication.Chat/src/ChatRestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ namespace Azure.Communication.Chat
{
// for backward compatibility, keep the previous method signature which will accept `repeatability-request-id` as a parameter
[CodeGenSuppress("CreateCreateChatThreadRequest", typeof(string), typeof(IEnumerable<ChatParticipantInternal>))]
[CodeGenSuppress("CreateChatThreadAsync", typeof(string), typeof(IEnumerable<ChatParticipantInternal>), typeof(CancellationToken))]
[CodeGenSuppress("CreateChatThread", typeof(string), typeof(IEnumerable<ChatParticipantInternal>), typeof(CancellationToken))]
[CodeGenSuppress("CreateChatThreadAsync", typeof(string), typeof(IEnumerable<ChatParticipantInternal>), typeof(IDictionary<string, string>), typeof(CancellationToken))]
[CodeGenSuppress("CreateChatThread", typeof(string), typeof(IEnumerable<ChatParticipantInternal>), typeof(IDictionary<string, string>), typeof(CancellationToken))]
internal partial class ChatRestClient
{
internal HttpMessage CreateCreateChatThreadRequest(string topic, string repeatabilityRequestId, IEnumerable<ChatParticipantInternal> participants)
internal HttpMessage CreateCreateChatThreadRequest(CreateChatThreadOptions options)
{
var message = _pipeline.CreateMessage();
var request = message.Request;
Expand All @@ -30,17 +30,31 @@ internal HttpMessage CreateCreateChatThreadRequest(string topic, string repeatab
uri.AppendPath("/chat/threads", false);
uri.AppendQuery("api-version", _apiVersion, true);
request.Uri = uri;
request.Headers.Add("repeatability-request-id", repeatabilityRequestId ?? Guid.NewGuid().ToString());
request.Headers.Add("repeatability-request-id", options.IdempotencyToken ?? Guid.NewGuid().ToString());
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Content-Type", "application/json");
CreateChatThreadRequest createChatThreadRequest = new CreateChatThreadRequest(topic);
if (participants != null)
CreateChatThreadRequest createChatThreadRequest = new CreateChatThreadRequest(options.Topic);
if (options.Participants != null)
{
foreach (var value in participants)
foreach (var value in options.Participants)
{
createChatThreadRequest.Participants.Add(value);
createChatThreadRequest.Participants.Add(value.ToChatParticipantInternal());
}
}

if (options.Metadata != null)
{
foreach (var value in options.Metadata)
{
createChatThreadRequest.Metadata.Add(value);
}
}

if (options.RetentionPolicy != null)
{
createChatThreadRequest.RetentionPolicy = options.RetentionPolicy;
}

var model = createChatThreadRequest;
var content = new Utf8JsonRequestContent();
content.JsonWriter.WriteObjectValue(model);
Expand All @@ -49,19 +63,17 @@ internal HttpMessage CreateCreateChatThreadRequest(string topic, string repeatab
}

/// <summary> Creates a chat thread. </summary>
/// <param name="topic"> The chat thread topic. </param>
/// <param name="repeatabilityRequestId"> If specified, the client directs that the request is repeatable; that is, that the client can make the request multiple times with the same Repeatability-Request-Id and get back an appropriate response without the server executing the request multiple times. The value of the Repeatability-Request-Id is an opaque string representing a client-generated, globally unique for all time, identifier for the request. It is recommended to use version 4 (random) UUIDs. </param>
/// <param name="participants"> Participants to be added to the chat thread. </param>
/// <param name="options"> Participants to be added to the chat thread. </param>
/// <param name="cancellationToken"> The cancellation token to use. </param>
/// <exception cref="ArgumentNullException"> <paramref name="topic"/> is null. </exception>
public async Task<Response<CreateChatThreadResultInternal>> CreateChatThreadAsync(string topic, string repeatabilityRequestId = null, IEnumerable<ChatParticipantInternal> participants = null, CancellationToken cancellationToken = default)
/// <exception cref="ArgumentNullException"> <paramref name="options.Topic"/> is null. </exception>
public async Task<Response<CreateChatThreadResultInternal>> CreateChatThreadAsync(CreateChatThreadOptions options, CancellationToken cancellationToken = default)
{
if (topic == null)
if (options?.Topic == null)
{
throw new ArgumentNullException(nameof(topic));
throw new ArgumentNullException(nameof(options.Topic));
}

using var message = CreateCreateChatThreadRequest(topic, repeatabilityRequestId, participants);
using var message = CreateCreateChatThreadRequest(options);
await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false);
switch (message.Response.Status)
{
Expand All @@ -78,19 +90,17 @@ public async Task<Response<CreateChatThreadResultInternal>> CreateChatThreadAsyn
}

/// <summary> Creates a chat thread. </summary>
/// <param name="topic"> The chat thread topic. </param>
/// <param name="repeatabilityRequestId"> If specified, the client directs that the request is repeatable; that is, that the client can make the request multiple times with the same Repeatability-Request-Id and get back an appropriate response without the server executing the request multiple times. The value of the Repeatability-Request-Id is an opaque string representing a client-generated, globally unique for all time, identifier for the request. It is recommended to use version 4 (random) UUIDs. </param>
/// <param name="participants"> Participants to be added to the chat thread. </param>
/// <param name="options"> Participants to be added to the chat thread. </param>
/// <param name="cancellationToken"> The cancellation token to use. </param>
/// <exception cref="ArgumentNullException"> <paramref name="topic"/> is null. </exception>
public Response<CreateChatThreadResultInternal> CreateChatThread(string topic, string repeatabilityRequestId = null, IEnumerable<ChatParticipantInternal> participants = null, CancellationToken cancellationToken = default)
/// <exception cref="ArgumentNullException"> <paramref name="options.Topic"/> is null. </exception>
public Response<CreateChatThreadResultInternal> CreateChatThread(CreateChatThreadOptions options, CancellationToken cancellationToken = default)
{
if (topic == null)
if (options.Topic == null)
{
throw new ArgumentNullException(nameof(topic));
throw new ArgumentNullException(nameof(options.Topic));
}

using var message = CreateCreateChatThreadRequest(topic, repeatabilityRequestId, participants);
using var message = CreateCreateChatThreadRequest(options);
_pipeline.Send(message, cancellationToken);
switch (message.Response.Status)
{
Expand Down
Loading
Loading