Skip to content

Manage a server

This page covers day-to-day administration once the server is running: roles, channel permissions, who can join, moderation, and media. Most of these tasks happen from a client through protocol commands. For file-level settings, see Configuration.

Test your setup with an ordinary member account. The owner bypasses every permission check, so testing only as the owner can hide a broken setup.

init creates four roles. A role is a named set of permissions. Lower position means more authority.

Position Role Permissions
0 owner owner, administrator
1 admin administrator
2 moderator manage_messages, manage_threads, kick_members, manage_nicknames, mute_members, deafen_members, move_members
3 user create_invite

New members get the roles in DB.users.default.roles, which is ["user"] by default.

init also creates these channels:

Channel Who can post Notes
about owner, admin Everyone can read.
announcements owner, admin Everyone can read.
welcome everyone Default target for welcome messages.
general everyone
random everyone
mods admin Only admin can see it.

Separators split them into three groups.

Each channel starts with these permission lists. Each list names the roles allowed to do one thing.

{
"view": ["user"],
"send": ["user"],
"delete": ["owner", "admin"],
"delete_own": ["user"],
"edit": ["owner"],
"edit_own": ["user"],
"react": ["user"],
"pin": ["owner", "admin", "moderator"],
"create_thread": ["user"]
}

A channel’s permissions object replaces individual lists and keeps the defaults for the rest. How a list is checked:

  • A member with the owner role always passes.
  • A role prefixed with !, such as "!muted", denies that role. Denials are checked first.
  • Otherwise the member passes if they hold any role in the list.
  • A list with no plain role names lets everyone through who isn’t denied.

For example, a staff room that only staff can see or post in:

{
"view": ["admin", "moderator"],
"send": ["admin", "moderator"]
}

Being able to see a channel doesn’t mean being able to post in it. Test each permission separately.

Channels come in four types:

  • text for ordinary conversation.
  • forum for named threads, each with its own members and archive state.
  • voice for live voice, with a text chat alongside.
  • separator for spacing in the channel list.

A channel’s name is its identifier in the protocol and on disk. Keep it stable, and use display_name for what people see. Renaming a channel moves its storage directory.

slow_mode_cooldown sets the seconds a member must wait between messages in a channel. Members with administrator, the admin role, or manage_server skip it. Set it with /slow or channel_update.

max_message_age is stored and returned, but nothing deletes old messages based on it. Don’t rely on it for retention.

A role has an id, a description, an optional color or gradient, a list of permissions, hoisted, self_assignable, an optional category, and a position.

Keep powerful roles narrow. The administrator permission passes every role permission check, so it amounts to full server control apart from owner-only actions. Give moderators specific permissions instead.

Role management rules:

  • owner, admin, and user are protected. Only the owner can change them.
  • A manager can only change roles below their own highest role.
  • A manager without administrator can only grant permissions they hold, and never owner or administrator.

self_assignable roles are ones members can add or remove themselves, for interests or pronouns. Don’t use them for staff access.

Role mentions follow two rules:

  • Anyone who can post can mention a role that has the is_mentionable permission. The user role can’t be made mentionable this way.
  • Members with mention_roles or administrator can mention any role.

The owner can always mention roles.

The access mode decides who can join as a new member. It’s stored in access.json and changed with access_mode_set, which needs manage_access.

Mode Who gets in
open Anyone. This is the default.
whitelist Existing members and whitelisted accounts.
password Anyone who gives the server password. Set it first with server_password_set.
application Existing members. Others submit an application for review.
invite Anyone with a valid invite code.

The owner and whitelisted accounts always get in. Accepting an application or redeeming an invite adds the account to the whitelist.

See Access control for the full flow.

Action Command Effect
Kick user_kick Disconnects the user’s sessions. They can reconnect.
Timeout user_timeout, /mute Blocks posting, reacting, and other actions for a set time. The user stays connected and can read.
Ban user_ban, /ban Adds the banned role, disconnects the user, and blocks future logins. /ban can also delete all their messages.
Sever /sever Hides two users from each other.
Delete message message_delete Removes the message and its stored attachments.

Nobody can kick, time out, ban, or sever the owner.

The built-in slash commands cover the common cases from any chat box.

The server also checks Rotur-wide bans. About 30 seconds after startup, and then every hour, it asks Rotur which of its Rotur-account members are banned. It disconnects those members and removes their membership. Local accounts and the owner are skipped.

Give report reviewers review_reports without manage_users, so they can triage without acting. report_create can target a message, attachment, or user.

Moderation and admin actions go to the audit log, grouped into user moderation, role management, channel management, message moderation, and server management. Anyone with view_audit_log or manage_users can read it with modlog_get. Set retention to match your policy.

Automod can block words and patterns before messages are saved.

Adding, updating, and deleting custom emoji and stickers needs manage_emojis. Any member can list them.

Names are letters, digits, and underscores: 1 to 64 characters for emoji and 2 to 64 for stickers. Allowed file types come from uploads. Images are stored in serverEmojis/ and serverStickers/, with their details in serverEmojis.json and serverStickers.json.

The default 100 MiB file limit is high for a small server. Pick values that fit your disk or bucket budget:

  • a per-file limit (max_size)
  • a MIME type allowlist (allowed_types)
  • a per-user count (max_attachments_per_user)
  • an upload rate (uploads_per_minute)
  • a longest lifetime (free_tier_max_expiration_days)
  • a total storage limit (max_total_upload_size)

All of these are under attachments. Every upload expires; permanent_tiers doesn’t change that.

With local storage, watch the disk. With S3, back up or version the bucket as well as the database. See Storage and backups.

With the default settings, the server sends a Rotur push notification when someone is mentioned, their role is mentioned, or they’re replied to. It uses the ROTUR_TOKEN that init saved, or ROTUR_NOTIFICATION_TOKEN if you set one. The token’s account is the sender users see. See Notifications for the settings.

Webhooks let outside services post into a text or voice channel over HTTP. Managing them needs manage_server.

The token returned when you create or regenerate a webhook is a secret. Regenerating it invalidates the old URL. Incoming webhook requests arrive at /webhooks and /webhooks/{path...}, so rate-limit and log those paths at your proxy.

The owner can check status, restart, or update the server from a client with server_maintenance. Restart and update only work when the server runs under scripts/run.sh.

The owner can also replace S3 and plugin credentials with config_update. Responses show them masked. Server icon and banner uploads use the server asset endpoint.