A modern Discord bot for RT25K with Google Sheets integration for real-time standings and tournament management.
- Modern Discord.js v14 with slash commands support
- Google Sheets Integration for real-time standings
- Challonge Tournament Integration for tournament management
- Docker Support for easy deployment
- Structured Logging with Winston
- Environment-based Configuration with Docker Secrets support
- Node.js 16.9.0 or higher (LTS recommended)
- Docker (optional, for containerized deployment)
- A Discord bot token from the Discord Developer Portal
- Google Cloud Project with Google Sheets API enabled (for standings functionality)
- Challonge API key (optional, for tournament features)
-
Clone the repository
git clone https://github.com/yourusername/RT25K-bot.git cd RT25K-bot -
Install dependencies
npm install
-
Set up environment variables
- Copy
.env.exampleto.env - Fill in your configuration (see Configuration section)
- Copy
-
Start the development server
npm run dev
For production, it's recommended to use Docker:
docker-compose up -dOr deploy with npm:
npm run build
npm startnpm run dev- Start development server with nodemonnpm start- Start production servernpm run register- Register slash commands with Discord
src/
βββ commands/ # Slash command handlers
βββ events/ # Discord event handlers
βββ utils/ # Utility functions
β βββ googleSheets.js # Google Sheets integration
β βββ logger.js # Logging configuration
βββ deploy-commands.js # Command deployment script
βββ index.js # Main application entry point
-
src/- Source codecommands/- Bot slash commandsevents/- Event handlershandlers/- Command and event handlersutils/- Utility functions including Google Sheets integration
-
service-account.json- Google Cloud service account credentials (keep this private!) -
.env- Environment variables (keep this private!)
Display the current RT25K standings from Google Sheets.
Options:
team(Optional): Filter standings by team name (case-insensitive, partial match)
Examples:
/standings
/standings team:Bodega
Display information about a Challonge tournament.
Options:
id(Required): Tournament ID or URL (e.g.,my-tournamentormytourney123)
Examples:
/tournament id:my-tournament
/tournament id:mytourney123
/help- Shows help information about available commands/ping- Check if the bot is responsive/serverinfo- Display server information/userinfo [user]- Display information about a user
/register- Register slash commands (Admin only)/config- Configure bot settings (Admin only)
Create a .env file in the root directory with the following variables:
# Required
DISCORD_TOKEN=your_discord_bot_token
CLIENT_ID=your_discord_client_id
APPLICATION_ID=your_discord_application_id
# Google Sheets Integration
GOOGLE_SHEETS_SPREADSHEET_ID=your_spreadsheet_id
GOOGLE_SHEETS_WORKSHEET_NAME=your_worksheet_name
# Challonge Integration (Optional)
CHALLONGE_API_KEY=your_challonge_api_key
# Logging
LOG_LEVEL=info
# Docker Secrets (alternative to environment variables)
# Mount secrets at /run/secrets/For enhanced security in production, you can use Docker secrets instead of environment variables:
-
Create a Docker secret:
echo "your_discord_token" | docker secret create discord_token -
-
The bot will automatically look for secrets in
/run/secrets/with the following names:discord_tokenclient_idapplication_idgoogle_credentials
The bot can fetch and display tournament information from Challonge. Here's how to set it up:
-
Get your Challonge API key
- Log in to your Challonge account
- Go to Account Settings
- Under "API Credentials", generate a new API key
-
Configure Environment Variables Add this to your
.envfile:CHALLONGE_API_KEY=your_challonge_api_key_here -
Using the Tournament Command
- Use the
/tournamentcommand with a tournament ID or URL - The bot will display tournament details, participants, and match information
- Use the
The bot can fetch and display standings data from a Google Sheet. Here's how to set it up:
-
Set up a Google Cloud Project
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Enable the Google Sheets API
- Create a service account and download the JSON key file
-
Configure Environment Variables Add these to your
.envfile:# Google Sheets Integration GOOGLE_SHEETS_SPREADSHEET_ID=your_spreadsheet_id GOOGLE_SHEETS_WORKSHEET_NAME=Overall StandingsOr use Docker secrets:
echo '{"type": "service_account", ...}' | docker secret create google_credentials -
-
Share your Google Sheet
- Open your Google Sheet
- Click "Share" and add your service account email as an editor
- Docker Engine 20.10.0+
- Docker Compose 1.29.0+
-
Create a
.envfile with your configuration -
Start the services:
docker-compose up -d
See the Configuration section for all available environment variables.
/app/data- Persistent data storage/app/logs- Application logs
The container includes a healthcheck that verifies the bot is connected to Discord.
Create a new JavaScript file in the src/commands/ directory with the following structure:
const { SlashCommandBuilder } = require('@discordjs/builders');
const { logger } = require('../utils/logger');
module.exports = {
data: new SlashCommandBuilder()
.setName('commandname')
.setDescription('Command description')
// Add options if needed
.addStringOption(option =>
option
.setName('optionname')
.setDescription('Option description')
.setRequired(false)
),
async execute(interaction) {
try {
// Command code here
await interaction.reply('Command response');
} catch (error) {
logger.error('Error in commandname command:', error);
if (!interaction.replied) {
await interaction.reply({
content: 'There was an error executing this command!',
ephemeral: true
});
}
}
}
};- Each command is a module that exports a
dataproperty (the command definition) and anexecutefunction - The
dataproperty usesSlashCommandBuilderto define the command and its options - The
executefunction contains the command's logic and is called when the command is used
-
Symptom: "The caller does not have permission"
- β Ensure the service account email is added as an editor to the Google Sheet
- β
Verify the
GOOGLE_SHEETS_SPREADSHEET_IDis correct - β
Check that the private key is properly formatted with
\nfor newlines
-
Symptom: No standings appear
-
β Check the bot logs for error messages
-
β Verify the worksheet name matches exactly (case-sensitive)
-
β Ensure your Google Sheet has the required columns:
- Column 1: Position
- Column 2: Team Name
- Column 3: Total Points
-
-
Symptom: Tournament not found
- β Verify the tournament ID or URL is correct
- β Ensure the tournament is not private or password-protected
- β Check that your API key has the correct permissions
-
Symptom: Container exits immediately
- β
Check logs:
docker-compose logs -f - β Verify all required environment variables are set
- β Ensure the Discord token is valid
- β
Check logs:
-
Enable Debug Logging Set
LOG_LEVEL=debugin your.envfile for more detailed logs. -
Check Container Logs
docker-compose logs -f
-
Test Commands
# Test environment variables docker-compose exec bot env # Get a shell in the container docker-compose exec bot sh
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
This project is licensed under the MIT License - see the LICENSE file for details.
- Discord.js - The library that powers this bot
- Google Sheets API - For spreadsheet integration
- Challonge API - For tournament management
- TypeScript - For type safety and better developer experience