Moderation
March 11, 2026 ยท View on GitHub
This guide shows how to migrate moderation operations from stream-chat-net to getstream-net.
Add Moderators
Before (stream-chat-net):
using StreamChat.Clients;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var channelClient = clientFactory.GetChannelClient();
await channelClient.AddModeratorsAsync("messaging", "general", new[] { "jane", "june" });
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var chatClient = new ChatClient(client);
await chatClient.UpdateChannelAsync("messaging", "general", new UpdateChannelRequest
{
AddModerators = new List<string> { "jane", "june" }
});
Key changes:
- Dedicated
AddModeratorsAsync()is replaced byUpdateChannelAsync()with theAddModeratorsproperty - Same pattern applies for
DemoteModeratorsAsync()using theDemoteModeratorsproperty
Demote Moderators
Before (stream-chat-net):
using StreamChat.Clients;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var channelClient = clientFactory.GetChannelClient();
await channelClient.DemoteModeratorsAsync("messaging", "general", new[] { "jane" });
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var chatClient = new ChatClient(client);
await chatClient.UpdateChannelAsync("messaging", "general", new UpdateChannelRequest
{
DemoteModerators = new List<string> { "jane" }
});
Key changes:
- Uses
UpdateChannelAsync()withDemoteModeratorslist instead of a dedicated method
Ban a User (App-level)
Before (stream-chat-net):
using StreamChat.Clients;
using StreamChat.Models;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.BanAsync(new BanRequest
{
TargetUserId = "bad-user",
UserId = "admin-user",
Reason = "spamming",
Timeout = 60 // minutes
});
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.BanAsync(new BanRequest
{
TargetUserID = "bad-user",
BannedByID = "admin-user",
Reason = "spamming",
Timeout = 60
});
Key changes:
BanAsync()moves fromIUserClienttoModerationClientUserIdbecomesBannedByID;TargetUserIdbecomesTargetUserID(note the uppercaseIDsuffix)
Ban a User (Channel-level)
Before (stream-chat-net):
using StreamChat.Clients;
using StreamChat.Models;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.BanAsync(new BanRequest
{
TargetUserId = "bad-user",
UserId = "admin-user",
Type = "messaging",
Id = "general",
Reason = "off-topic"
});
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.BanAsync(new BanRequest
{
TargetUserID = "bad-user",
BannedByID = "admin-user",
ChannelCid = "messaging:general",
Reason = "off-topic"
});
Key changes:
- Separate
TypeandIdfields become a singleChannelCidintype:idformat
Unban a User
Before (stream-chat-net):
using StreamChat.Clients;
using StreamChat.Models;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.UnbanAsync(new BanRequest
{
TargetUserId = "bad-user",
Type = "messaging",
Id = "general"
});
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.UnbanAsync(new UnbanRequest
{
TargetUserID = "bad-user",
ChannelCid = "messaging:general"
});
Key changes:
UnbanAsync()uses its ownUnbanRequesttype instead of reusingBanRequest- Moves from
IUserClienttoModerationClient
Shadow Ban
Before (stream-chat-net):
using StreamChat.Clients;
using StreamChat.Models;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.ShadowBanAsync(new ShadowBanRequest
{
TargetUserId = "bad-user",
UserId = "admin-user"
});
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.BanAsync(new BanRequest
{
TargetUserID = "bad-user",
BannedByID = "admin-user",
Shadow = true
});
Key changes:
- No separate
ShadowBanAsync()method; useBanAsync()withShadow = true - Same applies for removing shadow bans: use
UnbanAsync()instead ofRemoveShadowBanAsync()
Mute a User
Before (stream-chat-net):
using StreamChat.Clients;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.MuteAsync("noisy-user", "admin-user");
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.MuteAsync(new MuteRequest
{
TargetIds = new List<string> { "noisy-user" },
UserID = "admin-user"
});
Key changes:
MuteAsync()moves fromIUserClienttoModerationClient- Takes a
MuteRequestwithTargetIdslist (supports batch muting) instead of two string arguments
Unmute a User
Before (stream-chat-net):
using StreamChat.Clients;
var clientFactory = new StreamClientFactory("your-api-key", "your-api-secret");
var userClient = clientFactory.GetUserClient();
await userClient.UnmuteAsync("noisy-user", "admin-user");
After (getstream-net):
using GetStream;
using GetStream.Models;
var client = new StreamClient(apiKey: "your-api-key", apiSecret: "your-api-secret");
var moderationClient = new ModerationClient(client);
await moderationClient.UnmuteAsync(new UnmuteRequest
{
TargetIds = new List<string> { "noisy-user" },
UserID = "admin-user"
});
Key changes:
UnmuteAsync()moves fromIUserClienttoModerationClient- Uses
UnmuteRequestwithTargetIdslist
Method Mapping Summary
| Operation | stream-chat-net | getstream-net |
|---|---|---|
| Add moderators | channelClient.AddModeratorsAsync() | chatClient.UpdateChannelAsync() with AddModerators |
| Demote moderators | channelClient.DemoteModeratorsAsync() | chatClient.UpdateChannelAsync() with DemoteModerators |
| Ban user | userClient.BanAsync() | moderationClient.BanAsync() |
| Unban user | userClient.UnbanAsync() | moderationClient.UnbanAsync() |
| Shadow ban | userClient.ShadowBanAsync() | moderationClient.BanAsync() with Shadow = true |
| Remove shadow ban | userClient.RemoveShadowBanAsync() | moderationClient.UnbanAsync() |
| Mute user | userClient.MuteAsync() | moderationClient.MuteAsync() |
| Unmute user | userClient.UnmuteAsync() | moderationClient.UnmuteAsync() |