๐ Temp VC¶
Temp VC lets members create their own temporary voice channels by joining a configured lobby.
The short version: admins create lobby channels, members join a lobby, and the bot creates a personal voice channel for them.
Quick answer
Temp VC is controlled from two places:
- admins use
!tempvc ...commands to set it up - members use the [MGKL]VoiceControl Panel to manage their own temp channel
๐งญ Quick version¶
Temp VC works like this:
- An admin creates a Create a VC lobby inside a voice category.
- A member joins that lobby.
- The bot creates a new temporary voice channel in the same category.
- The bot moves the member into the new channel.
- The member becomes the channel owner.
- When the temp channel becomes empty, the bot deletes it.
Managed channels only
The panel only works on voice channels that the bot created and stored as managed Temp VC channels.
It will not manage normal Discord voice channels.
๐งฑ Main parts¶
| Part | What it does |
|---|---|
| ๐๏ธ Universal panel | One control panel per guild |
| ๐ช Lobby channels | Voice channels members join to create temp channels |
| ๐ Temp channels | Temporary channels created by the bot |
| ๐ Owner state | Stores who owns the temp channel |
| ๐ค AFK janitor | Moves idle users to the server AFK channel |
| ๐งพ Voice logs | Logs Temp VC events to modlog buckets |
๐ Live source files¶
The main live files are:
bot/cogs/tempvc_v2.py
bot/storage/pg_state.py
bot/storage/pg_config.py
bot/database.py
Important database/storage areas:
| Area | Purpose |
|---|---|
cfg.tempvc_panel |
Stores the universal panel channel/message |
cfg.tempvc_creator |
Stores configured lobby/creator rows |
cfg.tempvc_live |
Stores live temp channel state |
| guild config AFK fields | Stores AFK enabled/timeout settings |
State backend
Temp VC uses bot.state_storage.
In the current VPS design, live Temp VC state should be backed by Postgres via cfg.tempvc_live.
If unsure, check the bot boot logs for the selected state backend before changing Temp VC storage code.
๐ ๏ธ Admin setup commands¶
The main command group is:
!tempvc
These commands require the Magikal admin cap.
| Command | Purpose |
|---|---|
!tempvc |
Shows setup help |
!tempvc setup #text_channel |
Posts or updates the universal control panel |
!tempvc addlobby <category_id> "Lobby Name" |
Creates a persistent lobby VC |
!tempvc listlobbies |
Lists configured lobby channels |
!tempvc dellobby <id or "Lobby Name"> |
Deletes a configured lobby |
!tempvc afk status |
Shows AFK auto-move status |
!tempvc afk on |
Enables AFK auto-move |
!tempvc afk off |
Disables AFK auto-move |
!tempvc afk set <minutes> |
Sets AFK idle timeout |
Admin-only
Temp VC setup commands are admin-only through:
@prefix_require_caps("admin")
๐๏ธ Universal control panel¶
The universal panel is posted with:
!tempvc setup #text_channel
The panel tells users:
- join a Create a VC lobby
- the bot creates a temporary voice channel
- the bot moves them into it
- the channel is deleted when empty
- the panel buttons manage the active temp channel
The panel record is stored so the bot can update the same panel later.
Panel permissions
The bot needs these permissions in the panel text channel:
- View Channel
- Send Messages
- Embed Links
๐ช Creating lobby channels¶
Admins create lobbies with:
!tempvc addlobby <category_id> "Lobby Name"
Example:
!tempvc addlobby 123456789012345678 "Create a VC"
What happens:
- The bot creates a voice channel under the chosen category.
- The bot stores a creator row in the database.
- The lobby ID is loaded into the in-memory lobby set.
- Members who join that lobby will get their own temp VC.
Lobby category matters
A lobby must be inside a Discord category.
New temp channels are created in the same category as the lobby.
๐ Creating a temp channel¶
When a member joins a configured lobby:
- The bot creates a new voice channel.
- The channel name is based on the member display name.
- The bot makes sure it can still view/connect/manage the channel.
- The bot moves the member into the new channel.
- The bot stores the owner as a privacy-safe PID.
- The bot logs the creation event.
The owner is stored as:
owner_pid
not as a raw Discord user ID.
Privacy rule
Temp VC state should store privacy-safe PIDs, not raw Discord user IDs.
๐ Channel ownership¶
The first member who creates the temp channel becomes the owner.
The owner can use the panel controls while they are in the temp channel.
Mods with Manage Channels can also manage a temp channel when they are inside it.
| User | Can manage temp channel? |
|---|---|
| Current owner | โ |
| User with Manage Channels inside the channel | โ |
| Normal member who is not owner | โ |
| User not in a temp channel | โ |
Panel scope
The panel manages the temp voice channel the clicker is currently in.
Users must be in the temp channel to use most controls.
๐๏ธ Panel controls¶
The current control panel supports:
| Control | What it does |
|---|---|
| Rename | Opens a modal to rename the temp channel |
| Lock/Unlock | Toggles whether normal members can connect |
| Hide/Show | Toggles whether normal members can view the channel |
| Set Limit | Sets the user limit, 0โ99 |
| Transfer | Transfers ownership to another member in the channel |
| Claim | Claims ownership if the current owner has left |
โ๏ธ Rename¶
Rename opens a modal and edits the voice channel name.
If Discord rejects the change or the bot lacks permission, the bot returns a failure message and logs:
tempvc.rename_failed
๐ Lock / unlock¶
Lock/unlock changes the channel connect permission.
| State | Effect |
|---|---|
| Locked | Normal users cannot connect |
| Unlocked | Connect overwrite is cleared |
If it fails, the bot logs:
tempvc.toggle_lock_failed
tempvc.lock_unlock_failed
๐๏ธ Hide / show¶
Hide/show changes whether normal users can view the channel.
The bot attempts to keep its own access so it can still clean up hidden channels later.
If it fails, the bot logs:
tempvc.toggle_visibility_failed
tempvc.hide_show_failed
๐ฅ User limit¶
The panel can set the channel user limit.
Allowed values:
| Value | Meaning |
|---|---|
0 |
Unlimited |
1โ99 |
Fixed user limit |
If the value is invalid, the bot sends an error and does not edit the channel.
๐ Transfer ownership¶
Transfer lets the current owner choose another member in the temp channel.
What happens:
- The owner clicks transfer.
- The bot shows a member select menu.
- The chosen member becomes the new owner.
- The bot updates
owner_pidin state. - The bot logs the transfer.
Log event:
tempvc.owner_transferred
Voice modlog action:
TempVC Ownership Transferred
Discord select limit
Discord select menus can show up to 25 options.
If a temp channel has more than 25 members, not every member may be shown.
๐ Claim ownership¶
Claim is for when the current owner has left the channel.
Claim is allowed only when:
- the clicker is in a managed temp VC
- the current owner is not present in the channel
If the current owner is still present, claim is denied.
Log event:
tempvc.owner_claimed
Voice modlog action:
TempVC Ownership Claimed
โฑ๏ธ Owner grace transfer¶
When the owner leaves but the temp channel is not empty, the bot starts a grace timer.
If the owner comes back before the timer ends, the grace task is cancelled.
If the owner does not return, ownership transfers to the longest-present member in the channel.
Log events:
tempvc.grace_start
tempvc.owner_transferred
Why grace exists
Grace prevents ownership instantly jumping around if someone disconnects briefly.
๐งน Empty channel cleanup¶
When a managed temp channel becomes empty:
- the bot cancels any grace task
- the bot makes sure it can still access the channel
- the bot deletes the channel
- the bot deletes the live state row
- the bot clears join tracking
- the bot logs the deletion
Log event:
tempvc.deleted
Voice modlog action:
TempVC Deleted
Hidden channel cleanup
Hidden temp channels still need to be visible/manageable by the bot.
The code tries to preserve bot access when creating and cleaning channels.
๐ค AFK auto-move¶
Temp VC has an AFK janitor task.
It runs roughly every 30 seconds.
If enabled, it checks managed temp channels and moves idle users to the guild AFK channel.
A user is treated as AFK when they are:
self-muted
OR self-deafened
The timeout is per guild and stored in config.
Commands:
| Command | Purpose |
|---|---|
!tempvc afk status |
Shows current AFK state and timeout |
!tempvc afk on |
Enables AFK auto-move |
!tempvc afk off |
Disables AFK auto-move |
!tempvc afk set <minutes> |
Sets timeout from 1โ240 minutes |
AFK requirement
The server must have a Discord AFK channel configured.
If no guild AFK channel exists, the janitor skips moving users.
๐งพ Voice logging¶
Temp VC sends voice-related logs through the modlog system.
Routing order:
voice bucket
then events bucket
then main bucket
If no channel is configured, the log is dropped safely.
Useful log events:
| Event | Meaning |
|---|---|
modlog.voice.sent |
Voice log sent successfully |
modlog.voice.drop |
No suitable modlog channel was configured |
modlog.voice.failed |
Sending the voice log failed |
tempvc.voice_log_failed |
Temp VC tried to send a voice log but failed |
Current logging note
Some Temp VC log lines still include raw guild_id or channel_id.
Future cleanup should align these with the wider privacy rule using hashed IDs where practical.
๐๏ธ Stored state¶
Temp VC uses two types of state.
| State | Storage | Purpose |
|---|---|---|
| Panel record | Postgres config | Remembers panel channel/message |
| Lobby creators | Postgres config | Remembers configured creator lobbies |
| Live temp VC state | bot.state_storage |
Tracks active temp channels and owners |
| Join timestamps | In memory | Chooses longest-present member for owner transfer |
| Grace tasks | In memory | Handles delayed owner transfer |
| AFK timers | In memory | Tracks how long users have been self-muted/deafened |
Restart behaviour
In-memory join timestamps, grace tasks, and AFK timers do not survive restart.
Live temp channel ownership/state should survive only if bot.state_storage is backed by Postgres.
๐งช Testing checklist¶
After changing Temp VC, test these flows:
- admin can run
!tempvc - normal user cannot run setup commands
- panel posts successfully
- lobby creates successfully
- joining lobby creates a temp channel
- member is moved into new temp channel
- owner can rename channel
- owner can lock/unlock channel
- owner can hide/show channel
- owner can set user limit
- owner can transfer ownership
- member can claim ownership only after owner leaves
- channel deletes when empty
- AFK auto-move works when self-muted/self-deafened
- voice modlog receives create/delete/transfer/claim logs
- bot can clean up hidden temp channels
๐ฉบ Troubleshooting¶
| Symptom | Likely area to check |
|---|---|
| Panel does not post | Bot text-channel permissions |
| Lobby does not create | Bot Manage Channels permission |
| Temp channel does not spawn | Lobby not loaded or not stored |
| User is not moved | Bot Move Members/connect permissions |
| Panel says not a temp channel | Channel is not in live Temp VC state |
| Owner controls denied | User is not owner and lacks Manage Channels |
| Channel does not delete | Bot cannot manage/view the channel |
| AFK does nothing | AFK disabled, no guild AFK channel, or user not self-muted/deafened |
| Voice logs missing | Voice/events/main modlog channels not configured |
๐จ Known live code notes¶
These are notes from the current live file and should be reviewed before the next Temp VC refactor.
Duplicate leave handler call
on_voice_state_update currently calls _maybe_handle_leave(...) twice for the same leave event.
This should be reviewed carefully before changing Temp VC behaviour.
State backend comment may be stale
tempvc_v2.py comments describe state_storage as Redis or Ephemeral.
Current project direction is Postgres-backed live state through cfg.tempvc_live.
Confirm the selected backend from boot logs before migration or state work.
๐ง Rule¶
Temp VC should stay simple:
- admins configure lobbies and panel
- members create channels by joining lobbies
- owners manage their own channels
- the bot cleans up empty temp channels
- state should avoid raw user IDs
- risky state/storage changes need a restore point first