Skip to content

feat: chat moderation tools for streamers #370

@davedumto

Description

@davedumto

Overview

Streamers need basic moderation before real communities form. Without it, a single bad actor can ruin a stream's chat. Covers slow mode, timeouts, bans, follower-only mode, and link blocking.

Moderation actions

Action Who Duration
Delete message Streamer, mods Permanent
Timeout user Streamer, mods 1 / 5 / 10 / 60 min
Ban user Streamer Permanent
Unban user Streamer

Stream chat settings

Setting Options
Slow mode Off / 3s / 5s / 10s / 30s between messages
Follower-only Only followers can chat
Link blocking Auto-reject messages containing URLs

DB schema

CREATE TABLE chat_bans (
  id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  stream_owner TEXT REFERENCES users(username),
  banned_user  TEXT NOT NULL,
  banned_at    TIMESTAMPTZ DEFAULT now(),
  expires_at   TIMESTAMPTZ,   -- NULL = permanent ban
  reason       TEXT
);

ALTER TABLE creators ADD COLUMN IF NOT EXISTS slow_mode_seconds INT DEFAULT 0;
ALTER TABLE creators ADD COLUMN IF NOT EXISTS follower_only_chat BOOLEAN DEFAULT false;
ALTER TABLE creators ADD COLUMN IF NOT EXISTS link_blocking BOOLEAN DEFAULT false;

API routes

Method Route Description
DELETE /api/streams/chat/:messageId Delete message
POST /api/streams/chat/ban Ban or timeout a user
DELETE /api/streams/chat/ban/:username Unban
GET /api/streams/chat/bans List active bans
PATCH /api/streams/settings Update slow mode / follower-only / link-blocking

All moderation routes verify requester is stream owner.

Enforcement in POST /api/streams/chat

Add server-side guards in order:

  1. Check chat_bans — reject if permanently banned
  2. Check chat_bans.expires_at — reject with retry-after if timed out
  3. If slow_mode_seconds > 0 — check last message timestamp, enforce delay
  4. If follower_only_chat — verify sender follows the streamer
  5. If link_blocking — reject messages matching URL regex

UI

Message context menu (chat-section.tsx, streamer view only)

  • Right-click / long-press on a message → context menu:
    • Delete message
    • Timeout (submenu: 1m / 5m / 10m / 1h)
    • Ban user
  • Deleted messages show "Message deleted" placeholder
  • Timed-out users see "You are timed out for X minutes" in place of chat input
  • Banned users see "You are banned from this chat"

Stream manager chat settings panel

In app/dashboard/stream-manager/ — add a "Chat" settings tab:

  • Slow mode selector
  • Follower-only toggle
  • Link blocking toggle
  • Active bans list with unban buttons

Acceptance criteria

  • Stream owner can delete any message (reflected for all viewers)
  • Timeout enforced server-side (rejected messages return 429 + retry_after)
  • Permanent ban enforced server-side
  • Slow mode enforced server-side per user
  • Follower-only enforced server-side
  • Link blocking regex applied server-side
  • Context menu visible on messages to stream owner only
  • Moderation settings UI in stream manager dashboard
  • Banned/timed-out users see clear error messaging

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions