Skip to main content

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.

Discord Faceit Hub Bot is a full-stack automation layer that bridges your CS2 Faceit Hub with a Discord server. It listens to live Faceit webhook events, maintains a Firestore database of linked player accounts, and reacts in real time — posting match announcements, assigning ELO-based roles, spinning up per-match voice channels, and running captain-draft (Mixton) lobbies — all without any manual intervention from staff.

Architecture Overview

The project is composed of four tightly integrated components that work together whenever a Faceit event fires.
ComponentTechnologyResponsibility
Discord Botdiscord.js v14Slash commands, role management, voice channels, live panels
HTTP ServerExpress 4Webhook receiver (POST /webhook/faceit), REST API, OAuth2 flow
DatabaseFirebase FirestoreLinked accounts, active matches, guild settings, match history
Admin PanelReact (served as static files)Web UI for per-guild config and lobby management

Event Flow

Faceit Hub
    │  webhook event (match_status_*, hub_user_role_*)

Express Server  ──►  signature validation (optional)


handleFaceitWebhook()

    ├──►  Discord Bot  ──►  post embed, manage roles, move members

    └──►  Firestore    ──►  persist active match, update player stats
On startup, the bot validates the environment configuration, registers slash commands globally with the Discord API, cleans up any orphan voice channels left over from a previous run, and initialises the live match panel in DISCORD_MATCHES_CHANNEL_ID.

Key Capabilities

Account Linking

Players self-verify with /verificar_fc <nickname>. The bot confirms ownership via a Faceit profile description challenge and writes the mapping to Firestore so all future events are personalised.

Match Announcements

Every match_status_configuring, match_status_starting, and match_status_finished event produces a rich Discord embed with map, teams, rosters, and a live result update.

Role Management

Faceit ELO levels (1–10) are reflected as Discord roles, colour-coded from grey → green → orange → red. Club tier roles (EXTREME, PREMIUM, PLUS, and more) are assigned via hub_user_role_added webhook events.

Voice Channels

When a match starts, two private voice channels are created — one per faction. Players are automatically moved from a waiting room channel into their team channel and returned when the match ends.

Mixton Lobbies

An interactive captain-draft system lets players queue as ready, then captains take turns picking from the pool. The lobby state is persisted in Firestore and broadcast in real time over WebSocket to the admin panel.

Admin Panel

A React web app served at /admin lets staff view active matches, edit per-guild settings, manage the Mixton lobby, and read bot logs — all through a browser, authenticated with Discord OAuth2.

Prerequisites

Before deploying the bot you will need the following:
  • Node.js 18 or later — the project uses ES Modules ("type": "module" in package.json) and top-level await.
  • Firebase project — Firestore in Native mode for persistent storage.
  • Faceit API key — a server-side Data API v4 key from developers.faceit.com.
  • Discord application with a Bot token and the bot + applications.commands OAuth2 scopes.
  • A server with a public HTTPS URL — Faceit sends webhooks to your endpoint, so the bot must be reachable from the internet.

Multi-Guild Support

The bot supports running across multiple Discord servers from a single process. Configuration is resolved in a layered fashion:
  1. Environment variables — global baseline loaded from .env at startup.
  2. Firestore faceit_config/settings — global overrides editable from the admin panel.
  3. Firestore guild_settings/{guildId} — per-guild overrides that take the highest priority.
This means you can host one instance and serve several communities, each with its own channel IDs, hub, leaderboard, and admin role name, without restarting the process.

Build docs developers (and LLMs) love