Skip to main content
Version: v6

Moderation

Moderation consists of features that you can use to moderate a channel by detecting unwanted content and restricting the users that create the unwanted content. Several actions are supported, such as banning, flagging, muting and shadow banning. More information about the available low-level client moderation tools can be found here.

You can moderate flagged messages and users by using the moderation dashboard.

Moderation Categories

For each channel type (messaging, for example), you can enable AI moderation. There are four moderation categories:

  • Semantic Filters
  • Commercial Spam
  • Platform Circumvention
  • Blocklists

Dashboard moderation categories

For each moderation category, you can configure an action that will be performed after a message falls into that category.

The available actions are:

  • Flag
  • Block
  • Bounce
  • Bounce then flag
  • Bounce then block

Message Moderation Details

You can check if a message was moderated by checking the moderationDetails property in the Message class, which is null for regular messages.

If a message was moderated, moderationDetails will have the following values:

  • originalText - the original text of the message
  • action - the action that was performed (flag, block or bounce).

SDK Moderation Actions

Flagging a Message or a User

Any user is allowed to flag a message or a user. Flagging does not perform any particular action on the chat. The API will only trigger the related webhook event and make the message appear on your Dashboard Chat Moderation view.

client.flagMessage("message-id").enqueue { result -> 
if (result.isSuccess) {
// Message was flagged
val flag: Flag = result.data()
} else {
// Handle result.error()
}
}

client.flagUser("user-id").enqueue { result ->
if (result.isSuccess) {
// User was flagged
val flag: Flag = result.data()
} else {
// Handle result.error()
}
}

Muting a User

Any user is allowed to mute another user. Mutes are stored at user level and returned with the rest of the user information when connectUser is called. A user will be muted until the user is unmuted or the mute is expired.

client.muteUser("user-id").enqueue { result -> 
if (result.isSuccess) {
// User was muted
val mute: Mute = result.data()
} else {
// Handle result.error()
}
}

// Mute user for 60 minutes
client.muteUser("user-id", timeout = 60)
.enqueue { result: Result<Unit> ->
if (result.isSuccess) {
// User was muted
val mute: Mute = result.data()
} else {
// Handle result.error()
}
}

client.unmuteUser("user-id").enqueue { result ->
if (result.isSuccess) {
// User was unmuted
} else {
// Handle result.error()
}
}

After muting a user messages will still be delivered via web-socket. Implementing business logic such as hiding messages from muted users or display them differently is left to the developer to implement.

note

Messages from muted users are not delivered via push (APN/Firebase)

Banning Users

Users can be banned from an app entirely or just from a single channel. When a user is banned, they will not be allowed to post messages until the ban is removed or expired but they will be able to connect to Chat and to channels as before.

note

In most cases, only admins or moderators are allowed to ban other users from a channel.

NameTypeDescriptionDefaultOptional
timeoutIntThe timeout in minutes until the ban is automatically expired.no limit
reasonStringThe reason that the ban was created.
note

Banning a user from all channels can only be done using server-side auth.

// Ban user for 60 minutes from a channel 
channelClient.banUser(targetId = "user-id", reason = "Bad words", timeout = 60).enqueue { result ->
if (result.isSuccess) {
// User was banned
} else {
// Handle result.error()
}
}

channelClient.unBanUser(targetId = "user-id").enqueue { result ->
if (result.isSuccess) {
// User was unbanned
} else {
// Handle result.error()
}
}
Shadow Banning a User

Users can be shadow banned from an app entirely or just from a single channel. When a user is shadow banned, they will still be allowed to post messages, but any message sent during, will have shadowed: true field.

note

It's up to the client-side implementation to handle shadowed messages appropriately.

// Shadow ban user for 60 minutes from a channel 
channelClient.shadowBanUser(targetId = "user-id", reason = "Bad words", timeout = 60).enqueue { result ->
if (result.isSuccess) {
// User was shadow banned
} else {
// Handle result.error()
}
}

channelClient.removeShadowBan("user-id").enqueue { result ->
if (result.isSuccess) {
// Shadow ban was removed
} else {
// Handle result.error()
}
}
note

Administrators can view shadow banned user status in queryChannels(), queryMembers() and queryUsers().

Retrieving Banned Users

Banned users can be retrieved in different ways:

  1. Using the dedicated query bans endpoint
  2. User Search: you can add the banned:true condition to your search. Please note that this will only return users that were banned at the app-level and not the ones that were banned only in channels.
// retrieve the list of banned users 
client.queryUsers(
QueryUsersRequest(
filter = Filters.eq("banned", true),
offset = 0,
limit = 10,
)
).enqueue { result ->
if (result.isSuccess) {
val users: List<User> = result.data()
} else {
// Handle result.error()
}
}

// Query for banned members from one channel
client.queryBannedUsers(filter = Filters.eq("channel_cid", "ChannelType:ChannelId")).enqueue { result ->
if (result.isSuccess) {
val bannedUsers: List<BannedUser> = result.data()
} else {
// Handle result.error()
}
}
Retrieving Banned Users From Specific Channels

You can list banned users from a specific channel using the query banned users endpoint which allows you to get paginated results:

// Get the bans for channel livestream:123 in descending order
channelClient.queryBannedUsers(
sort = QuerySort.desc(BannedUsersSort::createdAt),
).enqueue { result ->
if (result.isSuccess) {
val bannedUsers: List<BannedUser> = result.data()
} else {
// Handle result.error()
}
}

// Get the page of bans which where created before or equal date for the same channel
client.queryBannedUsers(
filter = Filters.eq("channel_cid", "livestream:123"),
sort = QuerySort.desc(BannedUsersSort::createdAt),
createdAtBeforeOrEqual = Date(),
).enqueue { result ->
if (result.isSuccess) {
val bannedUsers: List<BannedUser> = result.data()
} else {
// Handle result.error()
}
}

You can also use in filter to query banned users from multiple channels:

client.queryBannedUsers(
filter = Filters.`in`("channel_cid", listOf("livestream:123", "livestream:456")),
sort = QuerySort.desc(BannedUsersSort::createdAt),
createdAtBeforeOrEqual = Date(),
).enqueue { result ->
if (result.isSuccess) {
val bannedUsers: List<BannedUser> = result.data()
} else {
// Handle result.error()
}
}

Did you find this page helpful?