When a Faceit match starts, the bot creates two private voice channels — one for each team — so players can communicate without interference. Only the players on each roster are granted access. When the match ends or is cancelled, players are returned to their original channels and the temporary channels are deleted. All of this logic lives inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/VasquezRivero92/Discord_Faceit/llms.txt
Use this file to discover all available pages before exploring further.
services/voice.js.
Voice channels are created in the same category as
DISCORD_WAITING_ROOM_CHANNEL_ID. Make sure this channel exists and is placed inside a category — temporary match channels will appear alongside it.Channel Creation — createMatchVoiceChannels()
match_status_starting / match_status_ready webhook event when autoVoiceChannels is enabled. The function:
- Fetches the waiting room channel to read its
parentId(category). - Builds a
permissionOverwritesarray for each team:- Everyone (
guild.id) →Connectdenied. - Bot →
ViewChannel,Connect,Speak,ManageChannels,MoveMembersallowed. - Each linked player in the roster →
Connect,Speakallowed (resolved viadb.getDiscordIdByFaceitId()with adb.getDiscordIdByNickname()fallback).
- Everyone (
- Creates the two voice channels with
guild.channels.create():🔊 <faction1.name>(or🔊 Equipo Aif no name)🔊 <faction2.name>(or🔊 Equipo Bif no name)
- Returns
{ vc1Id, vc2Id }for storage in Firestore viadb.addActiveMatch().
Player Movement — movePlayersToVoice()
movePlayersToVoice() is called once per team roster. For each player:
- Their Faceit player ID is resolved to a Discord ID (same two-step lookup as above).
- The guild member is fetched.
- If the member is currently in any voice channel, their current channel ID is recorded in
originalStates[discordId]and thenmember.voice.setChannel(voiceChannelId)moves them.
originalStates map is persisted to Firestore alongside the active match record so that cleanup can restore players to the correct channel.
Auto-Move on Reconnect
WhenautoMovePlayers is enabled, the voiceStateUpdate event handler checks whether a member who just connected (or entered the waiting room) is a participant in an active match. If they are, member.voice.setChannel() is called to move them directly to their team channel — no manual action required after a disconnect.
Match Cleanup — cleanupVoiceChannel()
Restore original positions
For each member still in the temporary channel, the function checks
originalVoiceStates[member.id]. If a previous channel ID is found it fetches that channel and calls member.voice.setChannel(originalChannel). If no original channel is recorded, members are moved to the waiting room instead.match_status_finishedwebhook event.match_status_cancelled/match_status_abortedwebhook event.- Force-cleanup from the admin panel (
POST /api/admin/matches/<id>/cleanup).
Orphan Cleanup on Startup
events/ready.js), it scans every channel in the guild for voice channels whose name starts with 🔊. Any found are cleaned up via cleanupVoiceChannel(). This handles the case where the bot was restarted mid-match and temporary channels were left behind from the previous session.
Expired Match Cleanup
Every 5 minutes, asetInterval in events/ready.js calls cleanupExpiredMatches(), which checks all active matches in Firestore for entries older than 2 hours (matchTimeoutMinutes, default 120). Expired matches are force-cleaned — voice channels deleted, match removed from Firestore, and the live panel updated.
Feature Flags
| Flag | Effect |
|---|---|
autoVoiceChannels | Creates 🔊 TeamName voice channels when a match starts |
autoMovePlayers | Moves players from their current voice channel to their team channel on match start, and auto-moves reconnecting players during an active match |
autoVoiceChannels
Channels are created with per-player permission overwrites so that only each team’s members can connect. The bot retains full control to move and delete them.
autoMovePlayers
Works both at match start (bulk move) and during the match (reconnect detection via
voiceStateUpdate). Original channel states are always preserved for restoration.