diff --git a/samples/DocsExamples/ExportingChannels.cs b/samples/DocsExamples/ExportingChannels.cs new file mode 100644 index 0000000..74e831a --- /dev/null +++ b/samples/DocsExamples/ExportingChannels.cs @@ -0,0 +1,40 @@ +using StreamChat.Clients; +using StreamChat.Models; + +namespace DocsExamples; + +/// +/// Code examples for +/// +internal class ExportingChannels +{ + private readonly IUserClient _userClient; + private readonly ITaskClient _taskClient; + + public ExportingChannels() + { + var factory = new StreamClientFactory("{{ api_key }}", "{{ api_secret }}"); + _userClient = factory.GetUserClient(); + _taskClient = factory.GetTaskClient(); + } + + public async Task ExportUsersAsync() + { + var exportResponse = await _userClient.ExportUsersAsync(new[] { "user-id-1", "user-id-2" }); + var taskId = exportResponse.TaskId; + } + + public async Task RetrievingTaskStatusAsync() + { + var taskId = string.Empty; + + // ITaskClient can provide the status of the export operation + var taskStatus = await _taskClient.GetTaskStatusAsync(taskId); + if (taskStatus.Status == AsyncTaskStatus.Completed) + { + // The export operation is completed + // Result object contains the export file URL + var exportedFileUrl = taskStatus.Result.Values.First().ToString(); + } + } +} \ No newline at end of file diff --git a/src/Clients/IUserClient.cs b/src/Clients/IUserClient.cs index 8adba3e..13d4ad5 100644 --- a/src/Clients/IUserClient.cs +++ b/src/Clients/IUserClient.cs @@ -150,11 +150,19 @@ public interface IUserClient Task ReactivateAsync(string id, bool restoreMessages = false, string name = null, string createdById = null); /// - /// Exports a user and returns an object containing all of it's data. + /// Exports a user and returns an object containing all of its data. /// /// https://getstream.io/chat/docs/dotnet-csharp/update_users/?language=csharp#exporting-users Task ExportAsync(string userId); + /// + /// Schedules user export task for a list of users + /// + /// user IDs to export + /// returns task ID that you can use to get export status (see ) + /// https://getstream.io/chat/docs/dotnet-csharp/exporting_users/?language=csharp + Task ExportUsersAsync(IEnumerable userIds); + /// /// Shadow bans a user. /// When a user is shadow banned, they will still be allowed to post messages, diff --git a/src/Clients/UserClient.cs b/src/Clients/UserClient.cs index 78fab0e..bcca8e3 100644 --- a/src/Clients/UserClient.cs +++ b/src/Clients/UserClient.cs @@ -109,6 +109,15 @@ public async Task ExportAsync(string userId) HttpMethod.GET, HttpStatusCode.OK); + public async Task ExportUsersAsync(IEnumerable userIds) + => await ExecuteRequestAsync("export/users", + HttpMethod.POST, + HttpStatusCode.Created, + body: new + { + user_ids = userIds, + }); + public async Task ShadowBanAsync(ShadowBanRequest shadowBanRequest) => await BanAsync(shadowBanRequest.ToBanRequest()); diff --git a/tests/UserClientTests.cs b/tests/UserClientTests.cs index 4b1489c..7098a94 100644 --- a/tests/UserClientTests.cs +++ b/tests/UserClientTests.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using FluentAssertions; using Newtonsoft.Json.Linq; using NUnit.Framework; -using StreamChat; +using StreamChat.Clients; using StreamChat.Exceptions; using StreamChat.Models; @@ -344,7 +346,7 @@ public async Task TestManyRevokeTokenAsync() } [Test] - public async Task TestQueryBannedUsers() + public async Task TestQueryBannedUsersAsync() { await _userClient.BanAsync(new BanRequest { @@ -364,5 +366,36 @@ await _userClient.BanAsync(new BanRequest resp.Bans.Should().NotBeEmpty(); } + + [Test] + public async Task TestExportUsersAsync() + { + var resp = await _userClient.ExportUsersAsync(new[] { _user1.Id, _user2.Id }); + + resp.TaskId.Should().NotBeNullOrEmpty(); + + AsyncTaskStatusResponse status = null; + await WaitForAsync(async () => + { + status = await _taskClient.GetTaskStatusAsync(resp.TaskId); + + return status.Status == AsyncTaskStatus.Completed; + }, timeout: 10000); + + status.Should().NotBeNull(); + status.Status.Should().Be(AsyncTaskStatus.Completed); + status.CreatedAt.Should().NotBeNull(); + status.Result.Should().NotBeNullOrEmpty(); + var exportUrl = status.Result.Values.First().ToString(); + exportUrl.Should().Contain("exports/users"); + + using var client = new HttpClient(); + using var response = await client.GetAsync(exportUrl); + response.EnsureSuccessStatusCode(); + + var exportFile = await response.Content.ReadAsStringAsync(); + exportFile.Should().Contain(_user1.Id); + exportFile.Should().Contain(_user2.Id); + } } } \ No newline at end of file