The project is a Python Discord bot that aim to perform repetitive tasks for a gaming community around Ubisoft Rainbow Six Siege.
- The bot sends a daily message to a specific channel of the guild asking the user when they plan to play the game. It uses reaction by emoji for user to specify many range of hours that they plan to play.
- The bot allows a user to specify a recurrent schedule.
- The bot sends a voice message to the first user that joins the voice channel giving who is about to come play (optional).
- The bot has administrative features with many statistics and analytics giving hindsight on the user's activity to pro-actively reaching folks.
- The bot allows users to know everyone's timezone in a specific voice channel to help identifying the best host.
- The bot has a tournament system allowing moderator to create a single elimination tournament with lost reporting and bracket visualization.
- The bot allows user to place fake bets on each match of a tournament.
- The bot has a daily stats posted to a configured channel.
- The bot uses the Discord activity API to determine when a user in a stack is back in the menu, ready to play and send a LFG (looking for group) message if the user is not in a full stack automatically.
- The bot has AI generated summary of what happened in the last 24 hours in term of matches played, kills, deaths, etc. The summary is sent to a specific channel of the guild.
- Tournament support 1v1 but also team tournament. The bot can handle 1v1, 2v2, 3v3, 4v4 and 5v5 tournaments.
- User can communicate by at-mentioning the bot or replying to the bot's message. The bot will generate an answer based on the context of the conversation and the user's question. The bot can also answer questions about the game, statistics, and other information related to the game. This feature is powered by the Gemini and Open AI API and uses the database to fetch statistics and information about the game.
- Allows user to follow any user and get notified when one of their followed users joins a voice channel.
- Has a custom game mode (10-man) that proposes maps by using stats to find the worst maps of the 10-man participants and organizes teams using stats (KD, % win, etc).
- The bot tracks consecutive daily play streaks per user and allows anyone to check their current streak or another user's streak.
- Users with 350+ hours of activity can create a private voice channel under a configured category. Only the creator can join and drag others in; the channel is automatically deleted when empty. Multiple private channels can exist simultaneously.
The bot sends a daily message to the guild asking the user when they plan to play the game. The user can react to the message with the hours they plan to play. By default, the bot fills the timeline with folks who used the /addschedule which allows user to set week day and time in advance. The bot automatically adjust the schedule every 15 minutes by looking at the voice channel and add people in the schedule.
Everytime someone leave a voice channels that is configured as part of the gaming voice channel, the bot collects the active user account and fetches the statistic.
The bot allows the moderator to create a single elimination tournament. The tournament is created by the moderator and the user can report the lost. The bot will generate a bracket and the user can see the progress of the tournament.
For every tournament, user can bet on matches. The user can see the leaderboard of the bets and the active bets. The system determines the odds depending of some statistics and adjust dynamically the bet as people vote.
Every time a match is completed, the money is distributed to the winners.
The bot show stats about the last 7 days every day like the number of T/K, numbers of kills divided by matches, the most used operators by users, etc.
The auto-lfg feature is a feature that allows the bot to send a message to the guild when a user is back in the menu (from a arcade, AI, etc or when a stack complete a rank match).
The admin console allows recurrent task in development (local) or in production (Linux Machine). The admin can execute tests or run visualizations of the user activity.

One of the administrative feature is to see the relationship between users. The bot uses the voice channel to see who is playing with whom and generate a network graph.
The visualization is also in 3D.
The bot keeps track of who is joining the voice channels. The bot can generate a visualization of the inactive user.
The bot can analyze who is playing with whom at the same time (in the same voice channel) and create a graph of the most common duo.
The bot can gives you who is the most active in the voice channels.
The bot can generate a matrix of the most active day of the week for each user.
The bot can answer questions about the game, statistics, and other information related to the game. The bot uses the Gemini AI API to generate answers based on the context of the conversation and the user's question.
A new user must run /setupprofile to set up their profile. The command prompts for their Ubisoft account name, fetches their maximum rank from R6 Tracker, and assigns the corresponding role. Without this step the user will have limited access to the server.
A user in a voice channel can use the /lfg command to notify the other users. The command will calculate the amount of user required and post who is already in the voice channel with a @here mention.
User can react to a message every day or can use the /addschedule command to set a schedule. The command allows selecting day of the weeks and many hours. If the user executes the command multiple times, the previous schedule will be overridden.
Once a user set a schedule, they can remove it using the /removeschedule command or calling the /addschedule which will override the previous schedule.
/seeschedule command will show the current schedule of the user.
Allows a user to specify which timezone they are in.
Allows a user to retrieve a user timezone
Allows a user to get the list of timezones of all people in a specific voice channel.
Allows the user to set their Ubisoft account name used for fetching the maximum rank they achieved and assigning the corresponding role.
Allows the user to set the Ubisoft account name used for real-time stats collection after gaming sessions. This can be different from the max-rank account.
Every user interested to participate in the tournament must register using the /registertournament command.
Allows to report a lost. If there are many tournaments, the user needs to specify the tournament name from a list. Otherwise, only the score is required.
Allows to see the current bracket. The bracket is automatically updated to the tournament text channel on a report of a lost. The command allows to regenerate it.
/mystreak shows the current consecutive daily play streak for you or another user. A streak increments each day you appear in a tracked voice channel and resets if you miss a day.
/mystreak → your own streak
/mystreak user:@Alice → Alice's streak
/privatechannel creates a private voice channel under the category configured by an administrator. Requirements and behaviour:
- Requires 350 hours of tracked voice activity on the server.
- Only the creator can connect by default; everyone else can see the channel but cannot join on their own.
- The creator can click to join/rejoin their own private channel.
- The creator uses
/privatechannelinvite @userto grant a member access and send them a DM with a join link. - The channel is automatically deleted when it becomes empty.
- Multiple private channels can exist at the same time across different users.
- An optional
trackparameter (defaulttrue) controls whether time spent in the channel counts toward activity stats. Settrack:Falseto create an off-the-record session.
/privatechannel → tracked private channel
/privatechannel track:False → untracked private channel
Once you have a private channel, use /privatechannelinvite @user to grant a member access and DM them a direct join link. Only the creator of the active private channel can use this command.
/privatechannelinvite user:@Alice → grants Alice access and DMs a join link
Add a member of the guild to follow.
Remove a followed member
See the list of members you follow
Add to the list that will get ping if a custom game is looking for people
Remove yourself of the list. You won't be ping in the future if a custom game stats
See the list of people subscribed to custom game
Send a ping to all subscribed people who are in the /subscribecustomgame group
Once you have your full amount of people (10-man) you can start the process to select the map and creating the two teams
An administrator can add a schedule (hours) for a user for the current day.
If the bot is down, call the function to refresh the cache from the reaction of the message.
Force sending the daily question regardless if it was already sent or not (in the cache). Useful if the cache has the value that the message was sent but it crashed and the message was never sent.
Force the bot to check the cache for user's schedule and apply it on the current day.
Allows an administrator to set the timezone of a user.
The bot needs to send daily messages to a specific channel of the guild. The action specifies which channel the bot will send a daily message. Without this configuration, the bot will skip the guild daily message.
Allows to see what is the text channel configured for the guild to send the schedule every day.
The bot needs to know which voice channel to check for the guild. The action specify which channel the bot check activity. Without this configuration, the bot will skip the voice participation. Calling the function many times adds up the voice channels.
Allows to see what is the voice channels configured for the guild.
Remove all voice channels configuration. It is good to reset and add the voice channels again.
Set the Discord category under which private voice channels will be created when users run /privatechannel. Only one category can be configured per guild.
Display the category currently configured for private voice channels.
The moderator can create many tournaments. The tournament is a single elimination tournament. The tournament is created with a name and the number of players. The tournament is created with the current date and time.
Start a tournament that has been created and has enough registered participants. This locks registration and generates the initial bracket.
In case a user does not report a loss, a moderator can unblock the tournament by reporting the loss on the behalf of the user.
Display the final results and standings once a tournament has concluded.
Set the text channel to send the bracket and messages about the tournament
Allows to see what is the text channel configured for the guild to send the tournament information.
User can see who won the most for a specific tournament in term of bets.
User can see the active (not closed) bet for a specific tournament that every user placed.
User can place a bet on a specific user for a specific tournament.
User can see how much money they have in their wallet.
Turn on and off the feature that the bot goes into the voice channel to send a voice mesage to the first user.
Generate an image that is a network graph of the users and with whom they play the most.
Display match statistics for a user over a configurable time window.
Show which users have been most active (by voice time) over a recent period.
Display detailed profile information for the most active users.
Force-send the daily stats summary to the configured channel immediately, without waiting for the scheduled task.
Force-generate and post an AI-written summary of the last 24 hours of match activity to the configured AI channel.
Display the current Siege activity state (menu, ranked, custom game, etc.) for all users currently in voice channels.
Display the bot's effective permissions in the current channel. Useful for diagnosing permission issues.
Give the latest SHA of the commit. Helps to ensure that the bot is running the latest version.
Reset the cache for the administration guild.
Create a Discord Application:
- https://discord.com/developers/applications
- Click on "New Application" and give it a name.
- Currently, this application has two applications:
GameTimeSchedulerandGameTimeScheduler_Dev. The first one is for production and the second one is for development.
In your application, navigate to the "Bot" tab.
- Click "Add Bot" and confirm.
- Under "TOKEN", click "Copy" to get your bot's token. Keep this token secure!
Navigate to the OAuth2 tab and then URL Generator.
Under Scopes select:
botapplications.commands
Under "Bot Permissions", select the necessary permissions:
- View Audit Log
- Manage Roles
- Manage Channels
- View Channels
- Send Messages
- Manage Messages
- Read Message History
- Mention Everyone
- Add Reactions
- Connect
- Move Members
- Set Voice Channel Status
Copy the generated URL and open it in your browser to invite the bot to your desired server.
# Production Bot
https://discord.com/oauth2/authorize?client_id=1279592054996996219&permissions=281475263179984&redirect_uri=https%3A%2F%2Fdiscord.com%2Foauth2%2Fauthorize&integration_type=0&scope=bot+applications.commands
# Dev Bot
https://discord.com/oauth2/authorize?client_id=1282412272458924103&permissions=281475263179984&redirect_uri=https%3A%2F%2Fdiscord.com%2Foauth2%2Fauthorize&integration_type=0&scope=bot+applications.commandsYou also need the Presence Intent to be checked (located above the bot permission, same page). This will allows the bot to see who is playing the game and what is the status of the user (menu, playing, etc).
To get the statistics of the user, you need to create a developer account on the TRN website. The TRN API is used to get the statistics of the user. The API key is required to get the statistics of the user.
- Create an account on the TRN website: https://tracker.gg/developers
- E.g. https://tracker.gg/developers/apps/330f2e3d-c58f-4170-a4c1-65710ba2e55d
The .env file should contain the following in development. These values should be kept secret and be environment variable for your private deployment.
ENV=dev # or prod
BOT_TOKEN=<bot token>
BOT_TOKEN_DEV=<bot token>
GEMINI_API_KEY=<gemini api token>
OPENAI_API_KEY=<open ai api token>
To run the bot in development, you can use the following commands.
source .venv/bin/activate
python3 bot.py # or ./bot.py- Upgrade apt packages
sudo apt-get updateand upgradesudo apt-get upgrade - SSH into the machine
ssh pi@10.0.0.181- Clone the repository
git clone https://github.com/MrDesjardins/python-discord-scheduler-bot.git- Install
uv:curl -LsSf https://astral.sh/uv/install.sh | sh - Edit the environment variables file
/etc/environment(require sudo)
ENV=prod
BOT_TOKEN=<bot token>
TRN_API_KEY<TRN token>
GEMINI_API_KEY=<api key>
OPENAI_API_KEY=<api key>- Install ffmpeg for the audio
sudo apt-get install ffmpeg- Install SqlLite3 for analytic
sudo apt install sqlite3- Install OpenBLAS for numpy used in the generation of relation analytic between user. This might require other dependencies and must have the latest APT packages.
sudo apt-get install libopenblas-base
sudo apt-get install libjpeg-dev zlib1g-dev libtiff-dev libopenjp2-7-dev- Install the systemd that will run the bot at startup
sudo cp systemd/gametimescheduler.service /etc/systemd/system/gametimescheduler.service
sudo systemctl daemon-reload
sudo systemctl enable gametimescheduler.service
sudo systemctl stop gametimescheduler.service
sudo systemctl start gametimescheduler.service
sudo journalctl -u gametimescheduler.service -n 1000 -f- Install Chrome for the web scraping
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/google.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google.gpg] http://dl.google.com/linux/chrome/deb/ stable main" \
| sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt update
sudo apt install -y google-chrome-stable xvfbHere are few commands to set up the environment and dependencies.
sudo nano ~/.config/pip/pip.confSet the current index which focus on Raspberry PI supported packages with fallback to generic:
[global]
index-url = https://www.piwheels.org/simple
extra-index-url = https://pypi.org/simple
Then install Python by building:
sudo apt update
sudo apt install -y \
build-essential \
libffi-dev \
libbz2-dev \
liblzma-dev \
libsqlite3-dev \
libssl-dev \
zlib1g-dev \
libncurses5-dev \
libgdbm-dev \
libreadline-dev \
tk-dev \
uuid-dev
cd /usr/src
sudo wget https://www.python.org/ftp/python/3.10.14/Python-3.10.14.tgz
sudo tar xzf Python-3.10.14.tgz
cd /usr/src/Python-3.10.14
sudo make clean
CPPFLAGS="-I/usr/include/arm-linux-gnueabihf" \
LDFLAGS="-L/usr/lib/arm-linux-gnueabihf" \
./configure --enable-optimizations
make -j4
sudo make altinstall# Install system dependencies
sudo apt update
sudo apt install -y \
build-essential \
libffi-dev \
libbz2-dev \
liblzma-dev \
libsqlite3-dev \
libssl-dev \
zlib1g-dev \
libncurses5-dev \
libgdbm-dev \
libreadline-dev \
tk-dev \
uuid-dev
PIP_INDEX_URL=https://pypi.org/simple pip install cffi
Add in your ~/.zshrc or ~/.bashrc the following line to have the SQLite3 headers and columns configuration from the root .sqliterc file.
alias sqlite3="sqlite3 --init .sqliterc"If the service does not start, you can check the status of the service with the following command:
sudo systemctl status gametimescheduler.serviceYou can check the log in the service journal:
sudo journalctl -u gametimescheduler.service --reverseReal-time check:
sudo journalctl -u gametimescheduler.service -n 1000 -fChecking the log file (last 200 or real-time):
tail -n 200 app.log
tail -n 200 app.log -fTo lint the code, you can use the following command:
pylint **/*.py
black **/*.py
mypy deps
mypy cogs
mypy testsThe best way to code and publish a new version is to code, push in GitHub, and then pull the code in the Raspberry Pi. The script deployment/update.sh does the fetching, install the dependencies and restart the service.
deployment/update.shThe bot listen to the voice channels selected by the administrator and store the data in a database. The analytic concerns the user, the channel, the time in/out. The goal is establishing pattern which may help in the future scheduling and also see if how we may predict the user's activity and suggest partners.
Information are in the user_activity.db database. You can access the database using the following command which download the database in the current directory and open it.
analytics/transfer.sh
sqlite3 user_activity.dbYou can also while developing using the test script with python3 test_analytics_fake_date.py which will use the local database and generate fake data. You can see the data but also the generated images.
pytest -v -s ./tests/*_unit_test.pypytest -v -s ./tests/*_integration_test.pycoverage run --omit="./tests/*" -m pytest -v -s ./tests/*unit_test.py && coverage htmlLogs can accumulate and make the server run out of space. You can remove the logs by running the following command:
Check the size of large files:
sudo find / -type f -size +50M -exec ls -lh {} \; | awk '{ print $9 ": " $5 }'See what is the issue with logs:
sudo du -h --max-depth=1 /var/log | sort -rhTo see the journal size:
sudo journalctl --disk-usageReduce the journal logs, kill the logs for syslog and deamon log:
sudo truncate -s 0 /var/log/daemon.log
sudo truncate -s 0 /var/log/syslog
sudo journalctl --vacuum-size=100M
sudo journalctl --vacuum-time=7dConfigure journal and syslog retention:
sudo journalctl --vacuum-size=100M
sudo nano /etc/logrotate.d/rsyslog
sudo systemctl restart rsyslog
sudo nano /etc/systemd/journald.conf
SystemMaxUse=100M















