Every time a match changes state in your Faceit Hub, a webhook fires and the bot translates it into a rich Discord embed. Rather than posting separate messages for each stage, the bot edits the same message in place — so your announcements channel stays clean and each match is represented by a single, always-up-to-date post. The full pipeline 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.
webhooks/faceit.js and services/matchMessages.js.
The Four Match States
The bot handles six incoming webhook event types, mapped to four distinct embed styles:| Webhook event | State label | Embed color |
|---|---|---|
match_status_configuring | Configuring | #FFAA00 orange |
match_status_starting / match_status_ready | Started | #FF6B00 orange-red |
match_status_finished | Finished | #10B981 green |
match_status_cancelled / match_status_aborted | Cancelled | #EF4444 red |
Set
DISCORD_MATCHES_CHANNEL_ID (or discordMatchesChannelId in the admin settings panel) to the channel where all match embeds should be posted. The value may be a comma-separated list of channel IDs; the bot will use the first one it can successfully fetch.Embed Details from createMatchEmbed()
Each embed is produced by the createMatchEmbed(matchData, type) function in services/matchMessages.js.
Configuring — Lobby Created
Configuring — Lobby Created
Title: 🎮 ¡Lobby de Partida Creado!Signals that captains are in the Faceit voting phase (map and server selection). Fields shown:
- 🌐 Club —
matchData.entity_custom_name - 🎮 Game — e.g.,
CS2
https://www.faceit.com/en/cs2/room/<matchId>. The Discord message ID returned by channel.send() is persisted to Firestore via db.addActiveMatch() so it can be edited in subsequent states.Started — Match in Progress
Started — Match in Progress
Title: 🎮 ¡Partida Iniciada en el Club!Posted (or the configuring embed is edited in-place) once the match begins. Fields shown:
- 🌐 Club
- 🗺️ Map — from
matchData.voting.map.pick[0] - 📍 Server — from
matchData.voting.location.pick[0] - 👥 Team A roster — built by
buildTeamList() - 👥 Team B roster — built by
buildTeamList()
<@discordId>) for verified players, or code-formatted Faceit nicknames for unverified ones.Finished — Final Result
Finished — Final Result
Title: 🏁 Partida FinalizadaThe started embed is edited in-place. Additional fields shown:
- 📊 Score — formatted with a 🏆 trophy next to the winner’s score, e.g.,
🏆 **16** vs 10 - 🏆 Winner — the winning team name highlighted with 🎉
syncPlayerLevels() if autoRoleSync is enabled.Cancelled / Aborted
Cancelled / Aborted
Title: ❌ Partida CanceladaThe existing embed is edited to show the cancellation notice. Fields include club, map, and server. The description reads:
⚠️ Esta partida fue cancelada o abortada en Faceit.The active match record is removed from Firestore via
db.removeActiveMatch().In-Place Message Editing
Whenever the bot receives amatch_status_starting or terminal event, it calls db.getActiveMatch(matchData.id) to retrieve the message_id stored during the configuring phase. It then fetches that message with channel.messages.fetch(activeMatch.message_id) and calls msg.edit({ embeds: [newEmbed] }). If the original message has been deleted, a new message is sent instead and the record is updated.
Team List Building — buildTeamList()
faction.roster, the function:
- Tries
db.getDiscordIdByFaceitId(playerId, guildId)first. - Falls back to
db.getDiscordIdByNickname(p.nickname, guildId)if the ID lookup fails. - Returns a
<@discordId>mention for linked players, or`nickname`in backticks for unlinked ones.
Live Match Panel — updateLivePanel()
When the liveMatchPanel feature flag is enabled, updateLivePanel(client, matchesChannelId, db) maintains a single pinned embed in DISCORD_MATCHES_CHANNEL_ID listing every active match at a glance. It is called after every state change.
Active matches
Each entry shows team names (linked to the Faceit room), map, server location, and a relative timestamp using Discord’s
<t:...:R> format.No matches
When
db.getActiveMatches() returns an empty array, the panel shows a grey embed inviting players to queue in Faceit.db.setPanelMessageConfig() so it survives bot restarts.
Server Status Embed — createServerStatusEmbed()
When serverStatusAnnouncements is enabled and DISCORD_STATUS_CHANNEL_ID is configured, the bot posts or edits a status embed in the status channel every time a match starts. The embed shows:
- FACEIT API, LiveChat Service, Steam API, Steam Sessions, and Steam Community — all reported as Operational.
- LATAM server regions with their current status:
- 🇵🇪 Lima
- 🇨🇱 Santiago
- 🇦🇷 Buenos Aires
- 🇧🇷 São Paulo
- The currently active server is highlighted with 👈 (Jugando aquí 🎮).
- The latest CS2 patch note date (fetched from the Steam API) if available.
db.setStatusMessageConfig() / db.getStatusMessageConfig().
Feature Flags
| Flag | Effect |
|---|---|
matchAnnouncements | Master switch — disables all match embed posting when off |
liveMatchPanel | Controls the pinned live-panel embed in the matches channel |
serverStatusAnnouncements | Controls the LATAM server status embed in the status channel |