The bot reads its configuration from three sources in order of increasing priority: environment variables (Documentation 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.
.env file), Firestore faceit_config/settings (global overrides editable from the admin panel), and Firestore guild_settings/{guildId} (per-guild overrides). This layered approach lets a single process serve multiple Discord servers, each with its own channels, hub, and role configuration.
Required Variables
These two variables must be present at startup. The bot throws an error and exits immediately if either is missing.The Discord bot token. Generate or reset it in Discord Developer Portal → Bot → Token.
The Discord application ID. Found on the General Information page of your application in the Developer Portal.
The OAuth2 client secret for your Discord application. Required for the admin panel login flow (
/auth/discord/callback).A random secret string used to sign and verify JWT tokens for admin panel sessions. Choose a long, random value and keep it private.
Absolute or relative path to your Firebase service account JSON key file (e.g.
./firebase-credentials.json). If omitted, the bot attempts to initialise Firebase using Application Default Credentials, which works automatically on Google Cloud infrastructure.Faceit Settings
These variables connect the bot to your Faceit Hub and control how webhook events are filtered and authenticated.A server-side Faceit Data API v4 key obtained from developers.faceit.com. Used for all outbound Faceit API calls — fetching player stats, match details, and leaderboards.
The UUID of your Faceit Hub, visible in the hub URL (
/hubs/{uuid}). Incoming webhooks whose entity.id does not match this value are ignored unless a per-guild override is present.The UUID of the current season leaderboard for your hub. Used when displaying season rankings in embeds. Optional — if omitted, the bot falls back to the hub’s default leaderboard endpoint.
An optional shared secret for validating incoming webhook signatures. When the
webhookValidation feature flag is enabled in Firestore settings and this variable is set, the bot checks the x-faceit-signature or x-webhook-signature header and rejects requests that do not match.Discord Channel IDs
Channel ID variables are all optional, but each one unlocks a specific bot feature. Without the corresponding variable set, the feature is silently skipped rather than causing an error. The following table describes every channel variable:| Variable | Feature enabled |
|---|---|
DISCORD_GUILD_ID | Primary server ID; used as the default guild for all operations |
DISCORD_LINK_CHANNEL_ID | Restricts /verificar_fc and /desvincular_fc to this channel |
DISCORD_MATCHES_CHANNEL_ID | Where match announcement embeds and the live match panel are posted |
DISCORD_ROLES_CHANNEL_ID | Where role-change notifications (ELO level updates) are sent |
DISCORD_STATUS_CHANNEL_ID | Where the CS2 server status embed is maintained |
DISCORD_ADMIN_ALERTS_CHANNEL_ID | Staff alert channel — notified when a player opens a support call |
DISCORD_WAITING_ROOM_CHANNEL_ID | Voice channel used as the staging area; players connected here are automatically moved into their team’s match voice channel when a match starts |
DISCORD_SUPPORT_CHANNEL_ID | Channel where the persistent support panel button embed is deployed |
Server & Auth
These variables control the HTTP server and the public-facing URL required for OAuth2 and webhook delivery.The port the Express server listens on. The server binds to
0.0.0.0 so it is accessible from outside the container or VM. Default: 3000.The public HTTPS URL of your server (e.g.
https://bot.example.com). Used to build the Discord OAuth2 redirect URI ({BASE_URL}/auth/discord/callback) and any other absolute links the bot generates. Must be HTTPS in production for Discord OAuth2 to work.The exact name of the Discord role that grants access to admin-only slash commands and the web admin panel. Comparison is case-sensitive. Default:
ADMIN.Per-Guild Settings (Firestore)
Environment variables define a global baseline, but every setting can be overridden on a per-guild basis using Firestore documents. This makes the bot fully multi-tenant without any code changes. Per-guild settings are stored in theguild_settings Firestore collection, where each document ID is the Discord guild (server) ID. The getEffectiveConfigForGuild(guildId) function in config/index.js merges global settings with the guild document, with the guild document taking precedence.
The following fields are supported in a guild_settings/{guildId} document:
| Field | Type | Description |
|---|---|---|
discordLinkChannelId | string | Guild-scoped override for DISCORD_LINK_CHANNEL_ID |
discordMatchesChannelId | string | Guild-scoped override for DISCORD_MATCHES_CHANNEL_ID |
discordRolesChannelId | string | Guild-scoped override for DISCORD_ROLES_CHANNEL_ID |
discordStatusChannelId | string | Guild-scoped override for DISCORD_STATUS_CHANNEL_ID |
discordAdminAlertsChannelId | string | Guild-scoped override for DISCORD_ADMIN_ALERTS_CHANNEL_ID |
discordWaitingRoomChannelId | string | Guild-scoped override for DISCORD_WAITING_ROOM_CHANNEL_ID |
discordSupportChannelId | string | Guild-scoped override for DISCORD_SUPPORT_CHANNEL_ID |
faceitHubId | string | Hub UUID to filter webhook events for this guild |
faceitLeaderboardId | string | Leaderboard UUID for this guild’s season rankings |
adminRoleName | string | Admin role name for this guild |
matchTimeoutMinutes | number | Minutes before an unfinished match is auto-cleaned (default: 120) |
Club Role Mapping
The bot maps Faceit Club role UUIDs to Discord role names using theCLUB_ROLES_MAP constant defined in config/index.js. These mappings are hardcoded in the source and are triggered whenever a hub_user_role_added or hub_user_role_removed webhook event is received.
When Faceit fires one of these events, the bot looks up the role_id in the map and assigns or removes the corresponding Discord role from the linked player.
The four built-in club role mappings are:
| Faceit Club Role UUID | Discord Role Name |
|---|---|
d79607e7-77b8-4db0-9abf-c2592820066c | EXTREME |
f6b04720-3908-4933-9555-f61e63bf420b | EXTREME BAJOS |
dfb94a9b-b17f-4f8e-ace7-6d4863b2ea69 | PREMIUM |
38d0142f-04da-4130-8df6-c5d801ff5c3e | PLUS |
| Role | Colour |
|---|---|
EXTREME | #FF0000 (red) |
EXTREME BAJOS | #D35400 (burnt orange) |
PREMIUM | #FFD700 (gold) |
PLUS | #00BFFF (sky blue) |
LEVEL_ROLE_COLORS: levels 1–3 are grey (#8C8C8C), 4–7 are green (#15C253), 8–9 are orange (#FF9E00), and level 10 is red (#FF3E3E).
To support a different Club tier, add its Faceit role UUID and desired Discord role name to the
CLUB_ROLES_MAP object in config/index.js and redeploy. No other changes are needed.