Initially, I developed the League Statistic Bot with the intention to improve communication with my boyfriend. One of the challenges we face was the timing of my calls, particularly when my boyfriend was in a game of League of Legend. Understandably, interrupting him during those moments would lead to frustration, and he humorously jokes that I shouldn't call him when he is "at war". Thus, I sought a solution that would allow me to determine if he was currently playing League. By implementing the League Statistic Bot, I can now know if my boyfriend is playing League at the moment. Which enables me to wait until after his game to reach out, ensuring our conversations are more enjoyable and uninterrupted.
League Statistic Bot has also become a helpful tool for my family, especially when it comes to my younger brother's gaming habits. He struggles with self-control and to manage his gaming time properly. So, my parents started using the bot to keep track of his playtime and help him with time management. It's made a significant difference in his academic performance. With the bot's support, my parents can better guide him and find a balance between gaming and his studies. It's been a positive intervention that's created a more supportive environment for his growth and success.
The League Statistic Bot is a Discord bot designed to fetch League of Legend game data using the Riot Games API. It utilizes Discord's slash commands feature to provide users with convenient ways to track summoner's games.
Users can check if a summoner is currently playing League of Legends by using the /active slash command.
Moreover, users can request the data for the summoner's past 10 games by using /past slash command.
Additionally, the bot generates two bar graphs by matplotlib. The first graph displays the total time played by the summoner last week, allowing users to visualize their gaming activity over time. The second graph shows the total number of games played by the summoner last week, providing insights into their gaming frequency.
Lastly, the bot generates a comprehensive weekly report that includes a list of games played by the summoner previous week and total time played graph and number of games played graph.
The code can be divided into 3 components. The first component, discord, is responsible for receiving commands and sending responses on Discord. It consists of two files,
discord_bot.pyand
responses.py. The second component, riot request, is responsible for fetching data from Riot API. It comprises of the file
riot_requests.py". The third component entity includes four files:
summoner.py,
team.py,
match.py,
weekly_report.py.
discord_bot.py&
requests.py
The discord session of the code handles user requests and sending corresponding responses to user. In the file
discord_bot.py, discord.py library is used to aid in creating the application that utilize the Discord API. By utilizing
client.tree.commanddecorator from discord.py, we can create slash commands that users can use on Discord. Each command invokes a corresponding function from
responses.pythen uses
discord.Interactionto send the responses to users (as shown below).
@client.tree.command(name="active") @app_commands.describe(summoner_name="Summoner Name") async def active(interaction: discord.Interaction, summoner_name: str) -> None: """ Sends a message to the user with the active game of the summoner Args: interaction (discord.Interaction): The Discord interaction object representing the original message summoner_name (str): The summoner name Returns: None """ active_game = responses.active(summoner_name) await interaction.response.send_message(active_game)
'responses.py' calls the corresponding function in 'riot_requests.py', that fetch the required data from riot api. which, in turn, calls the corresponding function in ‘riot_requests.py’, that fetch the required data from riot api.
def active(summoner_name: str) -> str: """ Return a string of active game information given summoner_name. Args: summoner_name (str): summoner name Returns: active_game (str): a string of active game information """ summoner = riot_requests.get_summoners_by_name(summoner_name) active_game = riot_requests.get_active_games_by_summoner_id(summoner.id) return str(active_game)
riot_requests.py
The Match class represents an individual game match in League of Legends. It contains attributes such as the match ID, start time, duration, and participating teams. It serves as a data transfer object (DTO) for storing match-related information. The Summoner class represents a League of Legends summoner. It contains attributes such as the summoner ID, name, level, and game statistics. It acts as a DTO for storing summoner-related data. The WeeklyReport class generates a report summarizing the summoner's activity in the previous week. It interacts with the Match and Summoner classes to gather the necessary data and produces visualizations, such as graphs depicting the total time played and total games played. the Team class, which represents a team in a League of Legends match. The Team class is a data transfer object (DTO) used to store information about a team, including its ID, list of participants (players), and the outcome of the team (win or loss).
The "riot_requests_test" suite validates the functionality of Riot API calls in an ever-changing API environment. Using pytest.fixture, the tests are set up with mock API responses from JSON files. By utilizing with patch("requests.get"), the actual requests.get function is replaced with a mock response. This approach ensures that the code correctly interacts with the Riot API, accommodating potential API changes. The mock responses create a stable testing environment where the application's behavior can be verified against expected outcomes. Through these tests, the reliability of Riot API integration is maintained, promptly identifying and resolving any issues. The ultimate goal is to deliver a robust application that seamlessly interacts with the evolving Riot API, ensuring a consistent and dependable user experience.
@pytest.fixture def mock_get_summoners_by_name_sucess(): with open("test/mock_get_summoners_by_name_success.json") as f: return json.load(f) def test_get_summoners_by_name_success(mock_get_summoners_by_name_sucess): """ Test get_summoners_by_name() with a valid summoner name. """ summoner_name = "Kid Orpheus" with patch("requests.get") as mock_get: mock_get.return_value.json.return_value = mock_get_summoners_by_name_sucess summoner = get_summoners_by_name(summoner_name) assert expected_summoner == summoner
Originally, the bot was hosted on Heroku, but recently they started charging $7 per month for command line access. Fortunately, I received a generous gift from my dad in the form of a Raspberry Pi. Now, the bot is hosted on my Raspberry Pi, allowing me to run it for free.