{"id":13414867,"url":"https://github.com/GetStream/stream-chat-net","last_synced_at":"2025-03-14T22:32:25.651Z","repository":{"id":34863668,"uuid":"184221666","full_name":"GetStream/stream-chat-net","owner":"GetStream","description":"Stream Chat official .NET API Client","archived":false,"fork":false,"pushed_at":"2024-07-22T09:43:24.000Z","size":385,"stargazers_count":62,"open_issues_count":3,"forks_count":12,"subscribers_count":34,"default_branch":"master","last_synced_at":"2024-10-12T13:55:54.936Z","etag":null,"topics":["chat","chat-api","csharp","rest"],"latest_commit_sha":null,"homepage":"https://getstream.io/chat/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetStream.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-30T08:21:08.000Z","updated_at":"2024-09-30T16:50:45.000Z","dependencies_parsed_at":"2024-01-05T20:51:21.994Z","dependency_job_id":"c6bf0881-3b73-4481-abfe-f5548d923ad9","html_url":"https://github.com/GetStream/stream-chat-net","commit_stats":null,"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-chat-net","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-chat-net/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-chat-net/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-chat-net/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetStream","download_url":"https://codeload.github.com/GetStream/stream-chat-net/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221513933,"owners_count":16835746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","chat-api","csharp","rest"],"created_at":"2024-07-30T21:00:38.886Z","updated_at":"2024-10-26T08:30:41.759Z","avatar_url":"https://github.com/GetStream.png","language":"C#","readme":"# Official .NET SDK for [Stream Chat](https://getstream.io/chat/)\n\n[![.github/workflows/ci.yaml](https://github.com/GetStream/stream-chat-net/actions/workflows/ci.yaml/badge.svg)](https://github.com/GetStream/stream-chat-net/actions/workflows/ci.yaml) [![NuGet Badge](https://buildstats.info/nuget/stream-chat-net)](https://www.nuget.org/packages/stream-chat-net/)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./assets/logo.svg\" width=\"50%\" height=\"50%\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    Official .NET API client for Stream Chat, a service for building chat applications.\n    \u003cbr /\u003e\n    \u003ca href=\"https://getstream.io/chat/docs/\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://github.com/GetStream/stream-chat-net/tree/master/samples\"\u003eCode Samples\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/GetStream/stream-chat-net/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/GetStream/stream-chat-net/issues\"\u003eRequest Feature\u003c/a\u003e\n\u003c/p\u003e\n\n## 📝 About Stream\n\nYou can sign up for a Stream account at our [Get Started](https://getstream.io/chat/get_started/) page.\n\nYou can use this library to access chat API endpoints server-side.\n\nFor the client-side integrations (web and mobile) have a look at the JavaScript, iOS and Android SDK libraries ([docs](https://getstream.io/chat/)).\n\n---\n\u003e ## 🚨 Breaking changes in v1.0 \u003c\n\u003e The library received many changes in v1.0 to make it easier to use and more maintanable in the future.\n\u003e The main change is that both [`Channel`](https://github.com/GetStream/stream-chat-net/blob/0.26.0/src/stream-chat-net/Channel.cs) and [`Client`](https://github.com/GetStream/stream-chat-net/blob/0.26.0/src/stream-chat-net/Client.cs) classes have been separated into small modules that we call clients. (This resambles the [structure of our Java library](https://github.com/GetStream/stream-chat-java/tree/1.5.0/src/main/java/io/getstream/chat/java/services) as well.)\n\u003e Main changes:\n\u003e - `Channel` and `Client` classes are gone, and have been organized into smaller clients in `StreamChat.Clients` namespace.\n\u003e - These clients do not maintain state as `Channel` used to did earlier where [it kept the `channelType` and `channelId` in the memory](https://github.com/GetStream/stream-chat-net/blob/0.26.0/src/stream-chat-net/Channel.cs#L34-#L35). So this means that you'll need to pass in `channelType` and `channelId` to a lot of method calls in `IChannelClient`.\n\u003e - Async method names have `Async` suffix now.\n\u003e - All public methods and classes have documentation.\n\u003e - Identifiers has been renamed from `ID` to `Id` to follow [Microsoft's naming guide](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions). Such as `userID` -\u003e `userId`.\n\u003e - A lot of data classes have been renamed to make more sense. Such as `ChannelObject` -\u003e `Channel`.\n\u003e - Data classes have been moved to `StreamChat.Models` namespace.\n\u003e - Full feature parity: all backend APIs are available.\n\u003e - Returned values are type of `ApiResponse` and expose rate limit informaiton with `GetRateLimit()` method.\n\u003e - The folder structure of the project has been reorganized to follow [Microsoft's recommendation](https://gist.github.com/davidfowl/ed7564297c61fe9ab814).\n\u003e - Unit tests have been improved. They are smaller, more focused and have cleanup methods.\n\u003e - Added .NET 6.0 support.\n\u003e\n\u003e The proper usage of the library:\n\u003e ```csharp\n\u003e var clientFactory = new StreamClientFactory(\"YourApiKey\", \"YourApiSecret\");\n\u003e // Note: all client instances can be used as a singleton for the lifetime\n\u003e // of your application as they don't maintain state.\n\u003e var userClient = clientFactory.GetUserClient();\n\u003e var channelClient = clientFactory.GetChannelClient();\n\u003e var messageClient = clientFactory.GetMessageClient();\n\u003e var reactionClient = clientFactory.GetReactionClient();\n\u003e\n\u003e var jamesBond = await userClient.UpsertAsync(new UserRequest { Id = \"james_bond\" });\n\u003e var agentM = await userClient.UpsertAsync(new UserRequest { Id = \"agent_m\" });\n\u003e\n\u003e var channel = await channelClient.GetOrCreateAsync(\"messaging\", \"superHeroChannel\", createdBy: jamesBond.Id);\n\u003e await channelClient.AddMembersAsync(channel.Type, channel.Id, jamesBond.Id, agentM.Id);\n\u003e\n\u003e var message = await messageClient.SendMessageAsync(channel.Type, channel.Id, jamesBond.Id, \"I need a new quest Agent M.\");\n\u003e await reactionClient.SendReactionAsync(message.Id, \"like\", agentM.Id);\n\u003e ```\n\n---\n\n## ⚙️ Installation\n\n```bash\n$ dotnet add package stream-chat-net\n```\n\n\u003e 💡 Tip: you can find code samples in the [samples](./samples) folder.\n\n## ✨ Getting started\n\n### Import\n\n```c#\nusing StreamChat.Clients;\n```\n\n### Initialize client\n\n```c#\n// Client factory instantiation.\nvar clientFactory = new StreamClientFactory(\"YourApiKey\", \"YourApiSecret\");\n\n// Or you can configure some options such as custom HttpClient, HTTP timeouts etc.\nvar clientFactory = new StreamClientFactory(\"YourApiKey\", \"YourApiSecret\", opts =\u003e opts.Timeout = TimeSpan.FromSeconds(5));\n\n// Get clients from client factory. Note: all clients can be used as a singleton in your application.\nvar channelClient = clientFactory.GetChannelClient();\nvar messageClient = clientFactory.GetMessageClient();\n```\n\n### Generate a token for client-side usage\n\n```c#\nvar userClient = clientFactory.GetUserClient();\n\n// Without expiration\nvar token = userClient.CreateToken(\"bob-1\");\n\n// With expiration\nvar token = userClient.CreateToken(\"bob-1\", expiration: DateTimeOffset.UtcNow.AddHours(1));\n```\n\n### Create/Update users\n\n```c#\nvar userClient = clientFactory.GetUserClient();\n\nvar bob = new UserRequest\n{\n    Id = \"bob-1\",\n    Role = Role.Admin,\n    Teams = new[] { \"red\", \"blue\" } // if multi-tenant enabled\n};\nbob.SetData(\"age\", 27);\n\nawait userClient.UpsertAsync(bob);\n\n// Batch update is also supported\nvar jane = new UserRequest { Id = \"jane\"};\nvar june = new UserRequest { Id = \"june\"};\nvar users = await userClient.UpsertManyAsync(new[] { bob, jane, june });\n```\n\n### GDPR-like User endpoints\n\n```c#\nvar userClient = clientFactory.GetUserClient();\n\nawait userClient.ExportAsync(\"bob-1\");\nawait userClient.DeactivateAsync(\"bob-1\");\nawait userClient.ReactivateAsync(\"bob-1\");\nawait userClient.DeleteAsync(\"bob-1\");\n```\n\n### Channel types\n\n```c#\nvar channelTypeClient = clientFactory.GetChannelTypeClient();\n\nvar chanTypeConf = new ChannelTypeWithStringCommands\n{\n    Name = \"livechat\",\n    Automod = Automod.Disabled,\n    Commands = new List\u003cstring\u003e { Commands.Ban },\n    Mutes = true\n};\nvar chanType = await channelTypeClient.CreateChannelTypeAsync(chanTypeConf);\n\nvar allChanTypes = await channelTypeClient.ListChannelTypesAsync();\n```\n\n### Channels\n\n```c#\nvar channelClient = clientFactory.GetChannelClient();\n\n// Create a channel with members from the start, Bob is the creator\nvar channel = channelClient.GetOrCreateAsync(\"messaging\", \"bob-and-jane\", bob.Id, bob.Id, jane.Id);\n\n// Create channel and then add members, Mike is the creator\nvar channel = channelClient.GetOrCreateAsync(\"messaging\", \"bob-and-jane\", mike.Id);\nchannelClient.AddMembersAsync(channel.Type, channel.Id, bob.Id, jane.Id, joe.Id);\n```\n### Messaging\n```c#\nvar messageClient = clientFactory.GetMessageClient();\n\n// Only text\nmessageClient.SendMessageAsync(channel.Type, channel.Id, bob.Id, \"Hey, I'm Bob!\");\n\n// With custom data\nvar msgReq = new MessageRequest { Text = \"Hi june!\" };\nmsgReq.SetData(\"location\", \"amsterdam\");\n\nvar bobMessageResp = await messageClient.SendMessageAsync(channelType, channel.Id, msgReq, bob.Id);\n\n// Threads\nvar juneReply = new MessageRequest { Text = \"Long time no see!\" };\nvar juneReplyMessage = await messageClient.SendMessageToThreadAsync(channel.Type, channel.Id, juneReply, june.Id, bobMessageResp.Message.Id)\n```\n\n### Reactions\n```c#\nvar reactionClient = clientFactory.GetReactionClient();\n\nawait reactionClient.SendReactionAsync(message.Id, \"like\", bob.Id);\n\nvar allReactions = await reactionClient.GetReactionsAsync(message.Id);\n```\n\n### Moderation\n```c#\nvar channelClient = clientFactory.GetChannelClient();\nvar userClient = clientFactory.GetUserClient();\nvar flagClient = clientFactory.GetFlagClient();\n\nawait channelClient.AddModeratorsAsync(channel.Type, channel.Id, new[] { jane.Id });\n\nawait userClient.BanAsync(new BanRequest\n{\n    Type = channel.Type,\n    Id = channel.Id,\n    Reason = \"reason\",\n    TargetUserId = bob.Id,\n    UserId = jane.Id\n});\n\nawait flagClient.FlagUserAsync(bob.Id, jane.Id);\n```\n### Permissions\n```c#\nvar permissionClient = clientFactory.GetPermissionClient();\n\nawait permissionClient.CreateRoleAsync(\"channel-boss\");\n\n// Assign users to roles (optional message)\nawait channelClient.AssignRolesAsync(new AssignRoleRequest\n{\n    AssignRoles = new List\u003cRoleAssignment\u003e\n    {\n        new RoleAssignment { UserId = bob.ID, ChannelRole = Role.ChannelModerator },\n        new RoleAssignment { UserId = june.ID, ChannelRole = \"channel-boss\" }\n    },\n    Message = new MessageRequest { Text = \"Bob and June just became mods\", User = bob }\n});\n```\n\n### Devices\n\n```c#\nvar deviceClient = clientFactory.GetDeviceClient();\n\nvar junePhone = new Device\n{\n    ID = \"iOS Device Token\",\n    PushProvider = PushProvider.APN,\n    UserId = june.ID\n};\n\nawait deviceClient.AddDeviceAsync(junePhone);\n\nvar devices = await deviceClient.GetDevicesAsync(june.Id);\n```\n\n### Export Channels\n\n```c#\nvar channelClient = clientFactory.GetChannelClient();\nvar taskClient = clientFactory.GetTaskClient();\n\nvar taskResponse = channelClient.ExportChannelAsync(new ExportChannelRequest { Id = channel.Id, Type = channel.Type });\n\n// Wait for the completion\nvar complete = false;\nvar iterations = 0;\nAsyncTaskStatusResponse resp = null;\nwhile (!complete \u0026\u0026 iterations \u003c 1000)\n{\n    resp = await taskClient.GetTaskStatusAsync(taskResponse.TaskId);\n    if (resp.Status == AsyncTaskStatus.Completed)\n    {\n        complete = true;\n        break;\n    }\n    iterations++;\n    await Task.Delay(100);\n}\n\nif (complete)\n{\n    Console.WriteLine(resp.Result[\"url\"]);\n}\n```\n\n## ✍️ Contributing\n\nWe welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. See our [license file](./LICENSE) for more details.\n\nHead over to [CONTRIBUTING.md](./CONTRIBUTING.md) for some development tips.\n\n## 🧑‍💻 We are hiring!\n\nWe've recently closed a [$38 million Series B funding round](https://techcrunch.com/2021/03/04/stream-raises-38m-as-its-chat-and-activity-feed-apis-power-communications-for-1b-users/) and we keep actively growing.\nOur APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world.\n\nCheck out our current openings and apply via [Stream's website](https://getstream.io/team/#jobs).\n","funding_links":[],"categories":["Calendar","Chat"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetStream%2Fstream-chat-net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGetStream%2Fstream-chat-net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetStream%2Fstream-chat-net/lists"}