A versatile Discord bot designed for the Pulchowk Campus community, featuring email verification, administrative tools, community engagement features, and academic information.
This bot offers a wide range of functionalities to manage and enhance Discord server:
Verification & Onboarding:
- Email Verification (
/verify,/confirmotp): Verifies users using their official Pulchowk Campus email by sending a one-time password (OTP). - Welcome Messages: Configurable welcome messages for new members, sent to a channel or via DM.
Moderation & Administration:
- Anti-Spam System: Automatically detects and takes action (mute, kick, ban) against spamming users based on configurable thresholds.
- Warnings (
/warn): Records warnings for users in the database, with a confirmation box before execution and an option to reset warnings. - Kick (
/kick): Kicks a user from the server. - Ban (
/ban): Bans a user from the server. - Timeout (
/timeout): Temporarily mutes a user. - Setup FSU (
/setupfsu): Creates a basic set of FSU-related roles, categories, and channels for quick server setup. - Admin Tasks (
/addtask,/listtasks,/completetask): Manage administrative to-do items. - Verified Users List (
/gotverified): Displays a list of verified users with their real names and college email addresses (Admin/Moderator only).
Community Engagement & Information:
- Leveling/XP System: Awards experience points (XP) for messages sent and voice chat activity, allowing users to level up and gain recognition.
- Suggestions (
/suggest,/approvesuggestion,/denysuggestion,/listsuggestions): Allows members to submit suggestions and administrators to review them. - Reaction Roles (
/setreactionrole,/removereactionrole): Enables users to assign themselves roles by reacting to specific messages. - FAQs (
/addfaq,/getfaq,/removefaq): Create and retrieve frequently asked questions. - User Stats (
/mystats,/topchatters,/topvoice): Tracks user activity (messages sent, voice chat time) and displays leaderboards. - Birthday Announcements: Announces birthdays of members who have set their birthday.
- Important Links (
/links): Provides quick access to relevant Pulchowk Campus and FSU links. - News/Notices (
/news): Provides links to official campus news and notice boards, and scrapes latest notices. - Holidays (
/holidays): Displays upcoming holidays fetched from Google Calendar.
Role Management:
- Assign Role (
/assignrole): Assigns a specified role to a user. - Remove Role (
/removerole): Removes a specified role from a user. - List All Roles (
/allroles): Lists all roles in the server with their IDs. - List User Roles (
/roles): Lists roles of a specified user or self.
βββ .dockerignore
βββ .env.example
βββ .github
β βββ workflows
β βββ build-docker-image.yml
β βββ codeql.yml
β βββ summary.yml
βββ Dockerfile
βββ LICENSE
βββ README.md
βββ deploy-commands.js
βββ docker-compose.yml
βββ generateToken.js
βββ package-lock.json
βββ package.json
βββ src
βββ bot.js
βββ commands
β βββ slash
β βββ addFaq.js
β βββ allRoles.js
β βββ approveSuggestion.js
β βββ assignRole.js
β βββ ban.js
β βββ clean.js
β βββ confirmotp.js
β βββ denySuggestion.js
β βββ getFaq.js
β βββ gotVerified.js
β βββ help.js
β βββ holidays.js
β βββ kick.js
β βββ links.js
β βββ listSuggestions.js
β βββ myStats.js
β βββ news.js
β βββ remindVerify.js
β βββ removeBirthday.js
β βββ removeFaq.js
β βββ removeReactionRole.js
β βββ removeRole.js
β βββ repu.js
β βββ roles.js
β βββ rss.js
β βββ setAntiSpam.js
β βββ setBirthday.js
β βββ setReactionRole.js
β βββ setWelcome.js
β βββ setupFSU.js
β βββ suggest.js
β βββ tasks.js
β βββ timeout.js
β βββ topChatters.js
β βββ topVoice.js
β βββ verify.js
β βββ viewAntiSpam.js
β βββ warn.js
βββ database.js
βββ services
β βββ emailService.js
β βββ rssDbManager.js
β βββ rssService.js
β βββ scraper.js
βββ utils
βββ debug.js
βββ imageExtactorRSS.js
βββ otpGenerator.js
Follow these steps to get Pulchowk Discord Bot up and running.
# Discord Bot Token (from Discord Developer Portal -> Bot -> Token)
BOT_TOKEN="_DISCORD_BOT_TOKEN_HERE"
# Discord Application (Client) ID (from Discord Developer Portal -> General Information)
CLIENT_ID="_DISCORD_APPLICATION_CLIENT_ID_HERE"
# ID of the Guild (Server) where you want to test/deploy commands (right-click server -> Copy ID - Developer Mode must be enabled)
GUILD_ID="_DISCORD_GUILD_ID_HERE"
# ID of the role to assign on successful verification (right-click role -> Copy ID)
VERIFIED_ROLE_ID="_VERIFIED_ROLE_ID_HERE"
# --- Google Cloud Project Credentials for Gmail API ---
# GOOGLE_CLIENT_ID (from Google Cloud Console -> APIs & Services -> Credentials -> OAuth 2.0 Client IDs)
GOOGLE_CLIENT_ID="_GOOGLE_CLIENT_ID_HERE"
# GOOGLE_CLIENT_SECRET (from Google Cloud Console -> APIs & Services -> Credentials -> OAuth 2.0 Client IDs)
GOOGLE_CLIENT_SECRET="_GOOGLE_CLIENT_SECRET_HERE"
# Redirect URI used during OAuth2 consent screen setup (e.g., https://developers.google.com/oauthplayground)
REDIRECT_URI="https://developers.google.com/oauthplayground" # Or custom redirect URI
# Refresh Token generated from OAuth2 Playground with https://www.googleapis.com/auth/gmail.send scope
REFRESH_TOKEN="_GOOGLE_REFRESH_TOKEN_HERE"
# The email address from college Workspace that will send the OTP emails
SENDER_EMAIL="college-email@pcampus.edu.np"
# --- Google Calendar API (for Holidays command) ---
# Path to Google Service Account Key JSON file (e.g., ./service_account_key.json)
# If not using service account, leave blank or remove. Holidays command will be disabled.
GOOGLE_SERVICE_ACCOUNT_KEY_PATH="./service_account_key.json"
# Google Calendar ID for holidays (e.g., 'en.nepali#holiday@group.v.calendar.google.com' for Nepal holidays)
GOOGLE_HOLIDAY_CALENDAR_ID="en.nepali#holiday@group.v.calendar.google.com"
# Optional: provide service account JSON as base64 (bot will decode to `src/service_account_key.json` on startup)
GOOGLE_SERVICE_ACCOUNT_KEY_B64=""
# --- Notice Scraper Configuration ---
# Channel ID where new notices will be posted
TARGET_NOTICE_CHANNEL_ID="_NOTICE_CHANNEL_ID_HERE"
# Channel ID for scraper error notifications (e.g., an admin channel)
NOTICE_ADMIN_CHANNEL_ID="_NOTICE_ADMIN_CHANNEL_ID_HERE"
# Interval for checking new notices in milliseconds (e.g., 30 minutes = 1800000)
NOTICE_CHECK_INTERVAL_MS=1800000
# --- Suggestions Feature Configuration ---
# Channel ID where suggestions will be posted and reacted to
SUGGESTIONS_CHANNEL_ID="_SUGGESTIONS_CHANNEL_ID_HERE"
# --- Birthday Announcements Configuration ---
# Channel ID where birthday announcements will be posted
BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID="_BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID_HERE"
# --- Club / Event Automation (optional) ---
CLUB_AUTO_SYNC_ENABLED="false"
CLUB_SYNC_INTERVAL_MINUTES=30
CLUB_AUTO_APPROVE="false"
EVENT_APPROVAL_CHANNEL_ID=""
CLUB_EVENT_REMINDER_HOURS=24
CLUB_JOIN_REQUESTS_PATH="./data/join_requests.xlsx"
CLUB_REGISTRATIONS_PATH="./data/club_registrations.xlsx"
CLUB_ATTENDANCE_PATH="./data/attendance.xlsx"
# --- Bot Prefix for traditional commands (e.g., !help) ---
BOT_PREFIX="!" - Copy the generated URL and paste it into browser to invite the bot.
- Create a "Verified" Role:
- In Discord server, go to Server Settings -> Roles.
- Create a new role named "Verified" (or anything you prefer).
- Copy its ID: Right-click the role and select "Copy ID". This is
VERIFIED_ROLE_ID. Ensure this role is positioned below bot's role in the server's role hierarchy so the bot can assign it.
This bot uses Google APIs for email verification and holiday announcements.
- Create a Google Cloud Project:
- Go to the Google Cloud Console.
- Create a new project or select an existing one.
- Enable APIs:
- In project, navigate to "APIs & Services" -> "Enabled APIs & Services".
- Click "+ ENABLE APIS AND SERVICES".
- Search for and enable:
- Gmail API (for sending OTP emails)
- Google Calendar API (for
/holidayscommand)
- Create OAuth Consent Screen:
- Go to "APIs & Services" -> "OAuth consent screen".
- Configure it (choose "External" for personal use, fill in required info).
- Add
https://www.googleapis.com/auth/gmail.sendas a scope. - Add
https://www.googleapis.com/auth/calendar.readonlyas a scope. - Add email as a test user.
- Create OAuth 2.0 Client ID (for Gmail API):
- Go to "APIs & Services" -> "Credentials".
- Click "+ CREATE CREDENTIALS" and choose "OAuth client ID".
- Select "Desktop app" as the application type.
- Copy
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET. - Generate Refresh Token:
- Go to Google OAuth 2.0 Playground.
- In the left pane, authorize the
https://www.googleapis.com/auth/gmail.sendscope andhttps://www.googleapis.com/auth/calendar.readonlyscope. - Click "Authorize APIs".
- Select Google account and grant permissions.
- Click "Exchange authorization code for tokens".
- Copy the
Refresh Token. This isREFRESH_TOKEN. - Set
REDIRECT_URIin.envtohttps://developers.google.com/oauthplayground(or custom URI if you set one up).
- Set
SENDER_EMAILin.envto the email address you want the OTPs to be sent from (must be associated with Google Workspace account).
- Create Service Account Key (for Google Calendar API - Optional but Recommended):
- Go to "APIs & Services" -> "Credentials".
- Click "+ CREATE CREDENTIALS" and choose "Service Account".
- Follow the steps to create a new service account.
- Grant it the "Calendar Viewer" role (or a custom role with
calendar.events.listpermission). - After creation, click on the service account email.
- Go to the "Keys" tab and click "ADD KEY" -> "Create new key".
- Select "JSON" and click "CREATE". A JSON file will download.
- Rename this file to
service_account_key.jsonand place it in the root directory of bot project. - Set
GOOGLE_SERVICE_ACCOUNT_KEY_PATH="./service_account_key.json"in.env. - Set
GOOGLE_HOLIDAY_CALENDAR_IDin.env(e.g.,'en.nepali#holiday@group.v.calendar.google.com'for Nepal holidays).
Create a file named .env in the root directory of project and populate it with the values obtained from the previous steps.
# Discord Bot Token (from Discord Developer Portal -> Bot -> Token)
BOT_TOKEN="_DISCORD_BOT_TOKEN_HERE"
# Discord Application (Client) ID (from Discord Developer Portal -> General Information)
CLIENT_ID="_DISCORD_APPLICATION_CLIENT_ID_HERE"
# ID of the Guild (Server) where you want to test/deploy commands (right-click server -> Copy ID - Developer Mode must be enabled)
GUILD_ID="_DISCORD_GUILD_ID_HERE"
# ID of the role to assign on successful verification (right-click role -> Copy ID)
VERIFIED_ROLE_ID="_VERIFIED_ROLE_ID_HERE"
# --- Google Cloud Project Credentials for Gmail API ---
# GOOGLE_CLIENT_ID (from Google Cloud Console -> APIs & Services -> Credentials -> OAuth 2.0 Client IDs)
GOOGLE_CLIENT_ID="_GOOGLE_CLIENT_ID_HERE"
# GOOGLE_CLIENT_SECRET (from Google Cloud Console -> APIs & Services -> Credentials -> OAuth 2.0 Client IDs)
GOOGLE_CLIENT_SECRET="_GOOGLE_CLIENT_SECRET_HERE"
# Redirect URI used during OAuth2 consent screen setup (e.g., [https://developers.google.com/oauthplayground](https://developers.google.com/oauthplayground))
REDIRECT_URI="[https://developers.google.com/oauthplayground](https://developers.google.com/oauthplayground)" # Or custom redirect URI
# Refresh Token generated from OAuth2 Playground with [https://www.googleapis.com/auth/gmail.send](https://www.googleapis.com/auth/gmail.send) scope
REFRESH_TOKEN="_GOOGLE_REFRESH_TOKEN_HERE"
# The email address from college Workspace that will send the OTP emails
SENDER_EMAIL="-college-email@pcampus.edu.np"
# --- Google Calendar API (for Holidays command) ---
# Path to Google Service Account Key JSON file (e.g., ./service_account_key.json)
# If not using service account, leave blank or remove. Holidays command will be disabled.
GOOGLE_SERVICE_ACCOUNT_KEY_PATH="./service_account_key.json"
# Google Calendar ID for holidays (e.g., 'en.nepali#holiday@group.v.calendar.google.com' for Nepal holidays)
GOOGLE_HOLIDAY_CALENDAR_ID="en.nepali#holiday@group.v.calendar.google.com"
# --- Notice Scraper Configuration ---
# Channel ID where new notices will be posted
TARGET_NOTICE_CHANNEL_ID="_NOTICE_CHANNEL_ID_HERE"
# Channel ID for scraper error notifications (e.g., an admin channel)
NOTICE_ADMIN_CHANNEL_ID="_NOTICE_ADMIN_CHANNEL_ID_HERE"
# Interval for checking new notices in milliseconds (e.g., 30 minutes = 1800000)
NOTICE_CHECK_INTERVAL_MS=1800000
# --- Suggestions Feature Configuration ---
# Channel ID where suggestions will be posted and reacted to
SUGGESTIONS_CHANNEL_ID="_SUGGESTIONS_CHANNEL_ID_HERE"
# --- Birthday Announcements Configuration ---
# Channel ID where birthday announcements will be posted
BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID="_BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID_HERE"
# --- Bot Prefix for traditional commands (e.g., !help) ---
BOT_PREFIX="!"Open terminal in the project's root directory and run:
npm installSlash commands need to be registered with Discord. You can deploy them to a specific guild for testing or globally for production.
- For testing (recommended): Deploy to specific test guild.
node deploy-commands.js --guild
- For global deployment (production): This can take up to an hour to propagate.
node deploy-commands.js --global
Once commands are deployed, you can start bot:
npm start/verify: Initiates the email verification process./confirmotp <code>: Confirms the verification with a One-Time Password.
| Command | Description | Example Usage |
|---|---|---|
/help [command_name] |
Displays a list of all commands or detailed information. | /help |
/news |
Shows the latest notices scraped from the Pulchowk Campus website. | /news |
/holidays |
Displays upcoming holidays fetched from Google Calendar. | /holidays |
/addfaq "Question" "Answer" [keywords] |
Adds a new FAQ entry. | /addfaq "What is FSU?" "Future Skills University" |
/getfaq <ID> |
Retrieves an FAQ by ID or searches by keywords. | /getfaq "What is FSU?" |
/removefaq <ID> |
Removes an existing FAQ entry. | /removefaq 123 |
/addtask <description> |
Adds a new administrative task. | /addtask "Study for exam" |
/listtasks [status] |
Lists pending, completed, or all administrative tasks. | /listtasks |
/completetask <ID> |
Marks an administrative task as complete. | /completetask 1 |
/suggest <suggestion> |
Submits a suggestion to the server staff. | /suggest "Add more channels" |
/listsuggestions [status] |
Lists all pending suggestions (Moderator). | /listsuggestions |
/approvesuggestion <ID> [reason] |
Approves a suggestion (Moderator). | /approvesuggestion 1 |
/denysuggestion <ID> [reason] |
Denies a suggestion (Moderator). | /denysuggestion 1 |
/links |
Displays important Pulchowk Campus/FSU-related links. | /links |
/mystats |
Shows personal chat and voice activity. | /myStats |
/topchatters [limit] |
Displays the top chatters in the server. | /topchatters 10 |
/topvoice [limit] |
Displays the top voice activity users in the server. | /topvoice 5 |
/setbirthday <MM/DD/YYYY> |
Sets birthday for announcements. | /setbirthday 01/15 |
/removebirthday |
Removes saved birthday. | /removebirthday |
/assignrole @user <RoleNameOrID> |
Assigns a role to a user (Moderator). | /assignrole @User Member |
/removeRole @user <RoleNameOrID> |
Removes a role from a user (Moderator). | /removerole @User Member |
/allroles |
Lists all available roles on the server. | /allroles |
/setreactionrole <messageId> <emoji> <RoleNameOrID> |
Sets up a reaction role message. | /setreactionrole 1234567890 π 9876543210 |
/removereactionrole <messageId> <emoji> |
Removes a reaction role from a message. | /removereactionrole 1234567890 π |
/setwelcome "message" |
Sets the welcome message for new members. | /setwelcome "Welcome {user}!" |
/setwelcome disable |
Disables the welcome message. | /setwelcome disable |
/ban @user [reason] |
Bans a user from the server (Moderator). | /ban @User Spamming |
/kick @user [reason] |
Kicks a user from the server (Moderator). | /kick @User Rule break |
/timeout @user <duration> [reason] |
Times out a user (Moderator). | /timeout @User 5m Misbehaving |
/warn @user [reason] |
Issues a warning to a user (Moderator). | /warn @User Off-topic |
/setantispam [setting <value>] ... |
Configures anti-spam settings (Admin). | /setantispam message_limit 7 time_window_seconds 10 |
/viewantispam |
Views current anti-spam settings (Admin). | /viewantispam |
/gotverified |
Displays a list of verified users with their real names and college email addresses (Admin/Moderator). |
Detailed guides for the Club & Event Management system:
- Club Management: Registration, settings, member management, and leadership transfer.
- Event Management: Creating events, visibility settings, and approval workflows.
- Payment Verification: Handling paid events, valid proof uploads, and verifying payments.
- Email Notifications: Triggers and configuration for email alerts.
- Troubleshooting: Common errors and solutions.
- Club registration: Clubs are created (via commands) and may require admin approval.
- Event creation:
/createeventtriggers a workflow for event details, payment settings, and poster uploads. - Payment System: Built-in verification loop for paid events using DM proofs.
- Automation: Scheduled reminders, Excel export syncs, and inactive club checks.
The bot can access Google Calendar using a service account JSON file or by accepting a base64-encoded JSON in an environment variable. This is useful in CI/CD or when secret files are not convenient.
- File approach (existing): set
GOOGLE_SERVICE_ACCOUNT_KEY_PATHto the JSON file path (commonly./service_account_key.json). - Base64 env approach (supported by
src/bot.js): setGOOGLE_SERVICE_ACCOUNT_KEY_B64to the base64-encoded contents of the service account JSON. The bot will decode and writesrc/service_account_key.jsonat startup.
Example to create base64 string locally (Unix/macOS):
base64 -w0 service_account_key.json > sa_key.b64
# copy the content of sa_key.b64 into env var GOOGLE_SERVICE_ACCOUNT_KEY_B64Security note: Do NOT commit service account JSON or the base64 string to version control. Use secret management in your deployment platform.
src/bot.jsβ Main bot class. Initializes client, commands, events, schedules, and integrations.src/database.jsβ SQLite initialization and migration logic (creates all tables used by the bot).src/commands/slash/β Slash commands (one file per command). Examples:createEvent.js,setupFSU.js,verify.js.src/services/β Background services (email, RSS, scraper, club automation).src/utils/β Utility modules (logging, permission checks, OTP generator, notice processor).
- Back up
bot.dbregularly. The file is created at the repository root asbot.dbby default. - If using Docker or Render, ensure persistent storage for
bot.db(bind mount or persistent disk). - Store
service_account_key.jsonand other credentials as secrets in your deployment platform, or provideGOOGLE_SERVICE_ACCOUNT_KEY_B64as a protected env var. - To redeploy commands after changing a command file, run:
node deploy-commands.js --guild # for testing in a guild
node deploy-commands.js --global # for global deploymentFor details on Render and Docker deployment, see the sections below.
This section provides detailed instructions for deploying bot on Render.com.
Important Note on Database Persistence:
Bot uses SQLite (bot.db) for data storage. Render's standard web services use ephemeral storage, meaning any data written to the disk (like bot.db file) will be lost on redeploys or restarts. To ensure bot's data (user stats, anti-spam configs, suggestions, etc.) persists, you must configure a persistent disk.
-
Push Code to a Git Repository:
- Ensure all bot files (including the
srcfolder,deploy-commands.js,package.json,.env.exampleif you create one, andservice_account_key.jsonif using it) are committed and pushed to a GitHub, GitLab, or Bitbucket repository. - Crucially, add
bot.dbandservice_account_key.jsonto.gitignorefile if repository is public! You will uploadservice_account_key.jsonas a secret file on Render, andbot.dbwill be created by the persistent disk.
- Ensure all bot files (including the
-
Create a Render Account:
- If you don't have one, sign up at Render.com. You can sign in with GitHub account.
-
Create a New Web Service:
- From Render Dashboard, click "New" -> "Web Service".
- Connect Git repository: Select the repository where bot's code is hosted. You might need to grant Render access to repository.
- Click "Connect".
-
Configure Web Service:
- Name: Give service a meaningful name (e.g.,
pulchowk-discord-bot). - Region: Choose a region closest to users or where you prefer.
- Branch: Select the Git branch you want to deploy from (e.g.,
mainormaster). - Root Directory: If
package.jsonis not in the root of repository (e.g., it's in abot/folder), specify that folder here. Otherwise, leave it blank. - Runtime:
Node - Build Command:
npm install - Start Command:
npm start(This uses thestartscript defined inpackage.json) - Instance Type: Choose a suitable instance type. The "Free" tier might be sufficient for a small bot, but keep in mind free instances spin down after inactivity. A paid tier (e.g., "Starter") is recommended for 24/7 uptime.
- Name: Give service a meaningful name (e.g.,
-
Add Environment Variables:
- Scroll down to the "Environment Variables" section.
- Add each key-value pair from local
.envfile here. - Important: For
GOOGLE_SERVICE_ACCOUNT_KEY_PATH, you will use a secret file instead of an environment variable.
-
Add Secret File for
service_account_key.json:- Still in the "Environment Variables" section, click "Add Secret File".
- Filename:
service_account_key.json(This must exactly match the filename you set inGOOGLE_SERVICE_ACCOUNT_KEY_PATHin.envand the path inholidays.jscommand). - Content: Copy and paste the entire content of local
service_account_key.jsonfile into this text area. - Click "Add Secret File".
-
Configure Persistent Disk (Crucial for SQLite):
- Scroll down to the "Disks" section.
- Click "Add Disk".
- Name:
bot-data(or any descriptive name). - Mount Path:
/opt/render/project/bot.db(This is the path where Render expectsbot.dbfile to be stored persistently. It aligns with wheredatabase.jscreates thebot.dbfile relative to the project root on Render's file system). - Size: Choose a small size (e.g., 1 GB) as SQLite databases are typically small.
- Click "Add Disk".
-
Create Web Service:
- Click "Create Web Service" at the bottom.
-
Monitor Deployment:
- Render will now start building and deploying bot. You can monitor the progress in the logs.
- If the build fails, check the build logs for errors (e.g., missing dependencies, syntax errors).
- If the deploy succeeds but the bot doesn't come online, check the runtime logs for errors (e.g., incorrect environment variables, bot token issues, API key problems).
- Verify Bot Status: Check Discord server to see if the bot is online.
- Test Commands: Try using slash commands (
/verify) and prefix commands (!help,!setbirthday, etc.) to ensure everything is working as expected. - Data Persistence: After testing, try manually restarting Render service. Then, check if
/mystatsor/listsuggestionsdata is still present. If it is, persistent disk is working correctly.
Troubleshooting Tips for Render:
- "Web service failed to start": Check
Start Commandand ensurepackage.jsonstartscript is correct (node src/bot.js). - "Cannot find module": Ensure all dependencies are listed in
package.jsonandnpm installran successfully during the build. - Bot goes offline: If on a free tier, it will spin down after inactivity. Upgrade to a paid instance type for 24/7 uptime.
- Errors related to Google APIs: Double-check all Google API environment variables and the
service_account_key.jsoncontent. Ensure the API is enabled in Google Cloud Console. - Permissions errors (Discord): Verify bot's permissions in the Discord Developer Portal and its role hierarchy in server.
To host your Pulchowk Discord Bot on a local server using Docker, follow these steps:
1. Prerequisites:
- Docker: Make sure Docker Desktop (or Docker Engine for Linux) is installed and running on your system.
2. Project Setup:
- Place Dockerfile and
docker-compose.yml: Ensure theDockerfileanddocker-compose.ymlfiles are in the root directory of your bot project, alongside yourpackage.jsonandsrcdirectory. .envfile: Create a.envfile in the root directory of your project and populate it with all the necessary environment variables as described in theREADME.mdfile, including your Discord bot token, Google API credentials, and other configurations.BOT_TOKEN="_DISCORD_BOT_TOKEN_HERE" CLIENT_ID="_DISCORD_APPLICATION_CLIENT_ID_HERE" GUILD_ID="_DISCORD_GUILD_ID_HERE" VERIFIED_ROLE_ID="_VERIFIED_ROLE_ID_HERE" GOOGLE_CLIENT_ID="_GOOGLE_CLIENT_ID_HERE" GOOGLE_CLIENT_SECRET="_GOOGLE_CLIENT_SECRET_HERE" REDIRECT_URI="[https://developers.google.com/oauthplayground](https://developers.google.com/oauthplayground)" REFRESH_TOKEN="_GOOGLE_REFRESH_TOKEN_HERE" SENDER_EMAIL="-college-email@pcampus.edu.np" GOOGLE_SERVICE_ACCOUNT_KEY_PATH="./service_account_key.json" GOOGLE_HOLIDAY_CALENDAR_ID="en.nepali#holiday@group.v.calendar.google.com" TARGET_NOTICE_CHANNEL_ID="_NOTICE_CHANNEL_ID_HERE" NOTICE_ADMIN_CHANNEL_ID="_NOTICE_ADMIN_CHANNEL_ID_HERE" NOTICE_CHECK_INTERVAL_MS=1800000 SUGGESTIONS_CHANNEL_ID="_SUGGESTIONS_CHANNEL_ID_HERE" BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID="_BIRTHDAY_ANNOUNCEMENT_CHANNEL_ID_HERE" BOT_PREFIX="!"
service_account_key.json: If you are using the Google Calendar API, ensure yourservice_account_key.jsonfile is in the root directory of your project.
3. Deploy Slash Commands (One-Time Setup):
Before running the bot with Docker, you need to deploy the slash commands to Discord. This is typically done directly using Node.js, not within the Docker container build process for the first time.
- Install dependencies locally (if you haven't already):
npm install
- Deploy slash commands:
- For testing on a specific guild (recommended for local development):
node deploy-commands.js --guild
- For global deployment (takes up to an hour to propagate):
node deploy-commands.js --global
- For testing on a specific guild (recommended for local development):
4. Build and Run with Docker Compose:
Navigate to the root directory of your bot project in your terminal where docker-compose.yml and Dockerfile are located.
- Build the Docker image: This command will build the image defined in your
Dockerfile.docker-compose build
- Start the bot: This command will create and start the Docker container for your bot.
docker-compose up -d
fsu-discord-botis the service name defined indocker-compose.yml.- The
-dflag runs the container in detached mode (in the background).
Explanation of docker-compose.yml and Dockerfile:
-
Dockerfile:FROM node:20-slim: Uses a slim Node.js 20 image as the base, which is good for smaller image sizes.RUN groupadd -r botuser && useradd -r -g botuser -d /app -s /bin/bash botuser: Creates a non-root userbotuserfor security best practices.WORKDIR /app: Sets the working directory inside the container to/app.RUN chown -R botuser:botuser /app: Ensures thebotuserowns the working directory.RUN apt-get update ... chromium ...: Installs necessary system dependencies, includingchromiumfor web scraping (Puppeteer).ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium: Configures Puppeteer to use the installed Chromium.COPY --chown=botuser:botuser package*.json ./: Copiespackage.jsonandpackage-lock.json(oryarn.lock) to leverage Docker's build cache.USER botuser: Switches to thebotuser.RUN npm ci --omit=dev && npm cache clean --force: Installs production dependencies and cleans the npm cache.npm ciis used for clean installs in CI/CD environments.COPY --chown=botuser:botuser . .: Copies the rest of your application code into the container.CMD ["node", "./src/bot.js"]: Specifies the command to run when the container starts. This executes your main bot file.
-
docker-compose.yml:version: "3.8": Specifies the Docker Compose file format version.services:: Defines the services (containers) for your application.fsu-discord-bot: The name of your bot service.container_name: fsu-discord-bot: Assigns a specific name to the container.image: agntperfect/fsu-discord-bot: Specifies the image to build/use. If you change theimagename, remember to update it here.user: botuser: Runs the container process as thebotusercreated in the Dockerfile.security_opt: - no-new-privileges:true: Enhances security by preventing privilege escalation.env_file: - .env: Tells Docker Compose to load environment variables from your local.envfile into the container.restart: unless-stopped: Configures the container to restart automatically unless it's explicitly stopped.volumes:: Defines data persistence.- fsu_data:/app/data:rw: This mounts a Docker volume namedfsu_datato/app/datainside the container. If your bot needs to write any other persistent data (e.g., logs, temporary files) besidesbot.dbin a specific/app/datadirectory, this volume will ensure it persists across container restarts.- ./bot.db:/app/bot.db:rw: This is crucial for SQLite persistence. It mounts your localbot.dbfile (or creates it if it doesn't exist) directly into the container at/app/bot.db. Any changes tobot.dbinside the container will be reflected on your host machine, ensuring data persistence.
tmpfs: - /tmp: Mounts atmpfs(temporary file system) at/tmpfor temporary files, which improves performance and security by not writing ephemeral data to disk.logging:: Configures logging for the container.networks: - fsu_net: Connects the bot to a custom Docker network.
volumes: fsu_data: driver: local: Defines the named volumefsu_data.networks: fsu_net: ...: Defines the custom bridge network for the services.
5. Verify and Manage:
- Check container status:
docker-compose ps
- View logs:
docker-compose logs fsu-discord-bot
- Stop the bot:
This will stop and remove the container and the
docker-compose down
fsu_netnetwork, but thefsu_datavolume and your localbot.dbfile will persist. - Stop and remove everything (including volumes):
Use with caution, as
docker-compose down --volumes
--volumeswill delete thefsu_datavolume, but your explicitbot.dbbind mount will keepbot.dbon your host.
Important Considerations:
- Firewall: Ensure your local firewall isn't blocking outgoing connections from the Docker container to Discord or Google APIs.
service_account_key.json: Since you're mounting the current directory, theservice_account_key.jsonfile should be accessible to the bot within the container at the path specified in your.envfile (./service_account_key.jsonrelative to/app).- Initial
bot.db: Thedatabase.jsscript in your bot'ssrcdirectory is responsible for creating thebot.dbfile and its tables if it doesn't exist. When you first run the container, it will create this file on your host machine at the path specified in the volume mount (./bot.db). - Updates: If you make changes to your bot's code, you'll need to rebuild the Docker image:
docker-compose build docker-compose up -d
Contributions are welcome! If you have suggestions for improvements or new features, feel free to open an issue or submit a pull request.
- Fork the repository.
- Create feature branch (git checkout -b feature/AmazingFeature).
- Commit changes (git commit -m 'Add some AmazingFeature').
- Push to the branch (git push origin feature/AmazingFeature).
- Open a Pull Request.
This project is licensed under the [No Redistribution License](https://www.google.com/search?q=LICENSE).