LANGUAGE: JAVASCRIPT (NODE.JS/DISCORD.JS)
ACTIVE: 2016 - PRESENT
In this project, I co-developed a Discord bot for a football-themed community Discord server. The bot enhances user engagement and provides various features tailored to the community’s interests.
KEY CONTRIBUTIONS:
Predictions Module: The primary feature I implemented allows users to predict scorelines for upcoming matches during major tournaments such as the World Cup or Euros.
> Scoring System: Users earn 3 points for a perfect prediction or 1 point for correctly predicting the winner with an incorrect scoreline.
> Reminders and Notifications: Implemented automated reminders for users to submit their predictions and notifications for match results.
> Automated leaderboard updates: A graphic of the current state of the leaderboard is posted at the end of each week.
MESSAGE PARSING
When the user predicts a match, the bot processes the command to ensure it's valid, then adds it to the database as shown in the flowchart in Figure 1.
The validity checks are as follows:
- Verify if there are any games being played today.
- Ensure the current time is before the kick-off time to avoid predictions mid-game.
- Check if the start of the message begins with "!predict" to ensure the correct command is being sent.
- Use a regex to parse the message into sub-sections (Home Team, Home Score, Away Team, Away Score).
- Determine if the home team and away team predicted are actually playing each other in today's game(s).
- Verify the names of the teams (allow full names, nicknames, and emoji).
- Check if the user's data is already present in the database.
CALCULATING SCORES
Data from the actual matches is pulled from the Sportmonks Football API and stored in an IMatch class. To calculate leaderboard points, the predicted score (after being split into a home score and an away score in the message parsing section) is compared against the actual score. Users gain 3 points for an exact match and 1 point for correctly predicting the winner if the scores do not match.
If the current round of the tournament involves extra time and penalty shootouts, then extra considerations are made: If the user predicts a draw, they must add a "p" after the team they believe will win the shootout. The main score is calculated as normal, however, if the match indeed goes to penalties and the user correctly predicts the winner, they gain an additional bonus point.
Another way to gain bonus points is to predict for an underdog. If one of the teams is considered an underdog and the user predicts a draw or a win for that underdog, they gain an additional point or two additional points respectively. An underdog is determined by fetching data from a sports odds comparison service. If the odds to win are greater than a 2:1 ratio compared to their opponent and the FIFA ranking difference between the two teams is more than 15 places, then the team is considered an underdog.
LEADERBOARD UPDATES
Sweepstakes
To keep the community engaged, instead of just a standard league leaderboard, I also created a sweepstakes knockout tournament that matches the active tournament rules.
A random wheel assigns users with teams in the actual tournament and places them in groups against each other, with each user representing their chosen national team. Those who progress from the groups go into the knockouts, again matching the rules of the actual tournament.
Once scores have been calculated and sorted, the data is exported into a CSV file. A template for the leaderboard tables is made prior to each tournament and uses Photoshop scripting to import data and edit the table.
Using the CSV file as the source of data, the Photoshop file is laid out in such a way that a simple for loop can iterate through the folders and the children layers to edit the data based on the current standings.
The script then exports this as a PNG file, making it available for me to send to the community. This entire process is semi-automated rather than fully automated by choice, as having manual intervention prevents mistakes in a CI/CD pipeline and allows me to make any spontaneous tweaks with ease.