Moderation

Stream Chat supports several moderation actions that you can surface in your Flutter app, including flagging messages or users, muting users, and banning users from channels or the application.

For server-side moderation configuration and the full moderation feature set, refer to the Chat Moderation guide.

Flagging a message

Users can flag a message to report it to moderators. The "Flag" action appears in the default message actions menu. You can also trigger it programmatically:

await StreamChat.of(context).client.flagMessage(messageId);

Flagging a user

await StreamChat.of(context).client.flagUser(userId);

Muting a user

Muting a user suppresses their messages for the current user. The muted user still sends messages, but the current user does not see them.

// Mute a user
await StreamChat.of(context).client.muteUser(userId);

// Unmute a user
await StreamChat.of(context).client.unmuteUser(userId);

// Check if a user is muted
final isMuted = StreamChat.of(context).currentUser?.mutes
  .any((mute) => mute.target.id == userId) ?? false;

Muting a channel

Users can mute an entire channel to stop receiving push notifications from it.

// Mute a channel
await channel.mute();

// Unmute a channel
await channel.unmute();

// Check if the channel is muted
final isMuted = channel.isMuted;

Banning users

Banning requires moderator permissions. You can ban a user from a specific channel or from the entire application.

// Ban from a channel
await channel.banMember(userId, {
  'reason': 'Violated community guidelines',
  'timeout': 60, // optional: ban duration in minutes
});

// Unban from a channel
await channel.unbanMember(userId);

Application-level bans are managed server-side or via the Stream Dashboard.

Shadow banning

A shadow-banned user can still send messages, but they are only visible to themselves and moderators. This is useful for gradually removing disruptive users without alerting them.

// Shadow ban from a channel
await channel.shadowBan(userId, {
  'reason': 'Spam',
});

// Remove shadow ban
await channel.removeShadowBan(userId);

Removing a message

Moderators can hard-delete a message on behalf of the channel:

// Soft delete (shows "Message deleted" placeholder)
await StreamChat.of(context).client.deleteMessage(messageId);

// Hard delete (removes entirely, requires moderation permissions)
await StreamChat.of(context).client.deleteMessage(messageId, hard: true);

Custom moderation UI

To add moderation-specific actions to the message actions menu, use actionsBuilder on StreamMessageItemProps:

StreamMessageListView(
  messageBuilder: (context, message, defaultProps) {
    return StreamMessageItem.fromProps(
      props: defaultProps.copyWith(
        actionsBuilder: (context, defaultActions) => [
          ...defaultActions,
          if (currentUserIsModerator)
            StreamContextMenuAction(
              leading: const Icon(Icons.block),
              label: const Text('Ban user'),
              onTap: () => _banUser(message.user!.id),
            ),
        ],
      ),
    );
  },
)