From 5f196f1c0b693a2ba4dcbe45fee7520b7e23b839 Mon Sep 17 00:00:00 2001 From: Thatcher Evans Date: Fri, 14 Aug 2026 17:25:01 -0600 Subject: [PATCH 1/8] Added a function to make bot send a message when mentioned Used the `bot.event` decorator to allow bot to respond to replies and mentions, only when it isn't the bot itself. Also removed unneeded function `get_or_create...` because the game I made to test isn't implemented anymore. Closes: #14 --- main.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/main.py b/main.py index 5ca4bb5..57aa5f9 100644 --- a/main.py +++ b/main.py @@ -18,20 +18,6 @@ bot = commands.Bot(command_prefix="!", intents=intents) -USER_PROFILES = {} -GAME_STATE = {"active": False, "word": "", "category": ""} - -def get_or_create_profile(user_id, username): - if user_id not in USER_PROFILES: - USER_PROFILES[user_id] = { - "name": username, - "level": 1, - "xp": 0, - "gold": 100, - "inventory": ["rusty_sword", "health_potion"] - } - return USER_PROFILES[user_id] - @bot.event async def on_ready(): print(f"Logged in and active as: {bot.user.name}") @@ -39,6 +25,27 @@ async def on_ready(): synced = await bot.tree.sync() except Exception as e: print(f"Error syncing commands: {e}") + +@bot.event +async def on_message(message): + if message.author == bot.user: + return + + was_mentioned = bot.user in message.mentions + is_reply_to_bot = False + + if message.reference and message.reference.cached_message: + is_reply_to_bot = message.reference.cached_message.author == bot.user + elif message.reference and not message.reference.cached_message: + try: + original_msg = await message.channel.fetch_message(message.reference.message_id) + is_reply_to_bot = original_msg.author == bot.user + except discord.HTTPException: + pass + + if was_mentioned or is_reply_to_bot: + await message.reply("beep boop this is my impression of a non-commital robot") + await bot.process_commands(message) @bot.tree.command(name="xkcd", description="Displays an xkcd comic by its number.") @app_commands.describe(n="The comic number to fetch") From 6056bd995fd16a7073704ee980f19a57e2ce01c4 Mon Sep 17 00:00:00 2001 From: Jax Date: Sat, 15 Aug 2026 15:31:41 -0600 Subject: [PATCH 2/8] Apply suggestions to clean up code Co-authored-by: Roman --- main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index 57aa5f9..c7da5e2 100644 --- a/main.py +++ b/main.py @@ -34,14 +34,15 @@ async def on_message(message): was_mentioned = bot.user in message.mentions is_reply_to_bot = False - if message.reference and message.reference.cached_message: - is_reply_to_bot = message.reference.cached_message.author == bot.user - elif message.reference and not message.reference.cached_message: - try: - original_msg = await message.channel.fetch_message(message.reference.message_id) - is_reply_to_bot = original_msg.author == bot.user - except discord.HTTPException: - pass + if message.reference: + if message.reference.cached_message: + is_reply_to_bot = message.reference.cached_message.author == bot.user + else: + try: + original_msg = await message.channel.fetch_message(message.reference.message_id) + is_reply_to_bot = original_msg.author == bot.user + except discord.HTTPException: + pass if was_mentioned or is_reply_to_bot: await message.reply("beep boop this is my impression of a non-commital robot") From 4526b1562dbce4d2acfcf45fc4db61da4bffb794 Mon Sep 17 00:00:00 2001 From: Thatcher Evans Date: Sat, 15 Aug 2026 15:39:48 -0600 Subject: [PATCH 3/8] Added comments to clarify parts of the bot reply roli2py suggested that I comment how the parts of the bot reply function work, so I added comments in the `on_message` function to clarify what each part of the function does. --- main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index c7da5e2..b771166 100644 --- a/main.py +++ b/main.py @@ -31,21 +31,21 @@ async def on_message(message): if message.author == bot.user: return - was_mentioned = bot.user in message.mentions + was_mentioned = bot.user in message.mentions # message.mentions stores all @ mentions is_reply_to_bot = False - if message.reference: - if message.reference.cached_message: - is_reply_to_bot = message.reference.cached_message.author == bot.user + if message.reference: # Is the message a refrence to anyone (reply or mention)? + if message.reference.cached_message: # Does the bot already has the original message saved in its memory? + is_reply_to_bot = message.reference.cached_message.author == bot.user # Check if the message it replied to was from the bot else: try: - original_msg = await message.channel.fetch_message(message.reference.message_id) - is_reply_to_bot = original_msg.author == bot.user + original_msg = await message.channel.fetch_message(message.reference.message_id) # Get the original message replied to + is_reply_to_bot = original_msg.author == bot.user # Check if the message it replied to was from the bot except discord.HTTPException: pass if was_mentioned or is_reply_to_bot: - await message.reply("beep boop this is my impression of a non-commital robot") + await message.reply("beep boop this is my impression of a non-commital robot") # Reply to the message with a funny comment ig await bot.process_commands(message) @bot.tree.command(name="xkcd", description="Displays an xkcd comic by its number.") From baffd24c2eacc0c62e2364fd97427f9faa9c72e9 Mon Sep 17 00:00:00 2001 From: roli2py Date: Sat, 15 Aug 2026 15:43:42 +0300 Subject: [PATCH 4/8] Add the necessary reqs to fix "no module" errors --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 7325c00..284376d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ discord.py~=2.3.2 python-dotenv~=1.0.0 +audioop-lts; python_version>='3.13' +requests~=2.34.2 From 091c37da7907e59971ba571097e699117ee2bd31 Mon Sep 17 00:00:00 2001 From: HellKeyes Date: Sat, 15 Aug 2026 18:27:23 +0530 Subject: [PATCH 5/8] fixed typo --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index b771166..22af813 100644 --- a/main.py +++ b/main.py @@ -140,5 +140,5 @@ async def pypi_package(interaction: discord.Interaction, name: str): BOT_TOKEN = os.getenv("DISCORD_API") if not BOT_TOKEN: - raise ValueError("The environemtnal variable DISCORD_API is empty. Please replace it with the bot token.") + raise ValueError("The environmental variable DISCORD_API is empty. Please replace it with the bot token.") bot.run(BOT_TOKEN) \ No newline at end of file From c7ec27fed6afa03b9236857b4f390424325bae9a Mon Sep 17 00:00:00 2001 From: roli2py Date: Sat, 15 Aug 2026 17:03:54 +0300 Subject: [PATCH 6/8] Place run of bot in the "name == main" condition Place the run to mitigate the problems when the tools are invoking the main module to inspect dependencies or get a `version` variable. --- main.py | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/main.py b/main.py index 22af813..02c1507 100644 --- a/main.py +++ b/main.py @@ -56,24 +56,24 @@ async def xkcd_comic(interaction: discord.Interaction, n: int): return await interaction.response.defer() - + url = f"https://xkcd.com/{n}/info.0.json" try: req = urllib.request.Request(url, headers={"User-Agent": "DiscordBot/1.0"}) with urllib.request.urlopen(req) as response: data = json.loads(response.read().decode()) - + title = data.get("title", "Unknown Title") img_url = data.get("img", "") alt_text = data.get("alt", "No alt text available.") - + output = ( f"*** XKCD Comic #{n}: {title} ***\n" f"Alt Text: {alt_text}\n" f"{img_url}" ) await interaction.followup.send(output) - + except urllib.error.HTTPError as e: if e.code == 404: await interaction.followup.send(f"Comic #{n} could not be found.") @@ -81,21 +81,21 @@ async def xkcd_comic(interaction: discord.Interaction, n: int): await interaction.followup.send(f"Failed to fetch comic data (HTTP Status {e.code}).") except Exception as e: await interaction.followup.send(f"An unexpected internal error occurred: {e}") - + def get_pypi_package_details(package_name): url = f"https://pypi.org/pypi/{package_name}/json" - + try: response = requests.get(url) - + if response.status_code == 404: return f"Error: Package '{package_name}' not found on PyPI." - + response.raise_for_status() data = response.json() - + info = data.get("info", {}) - + return ( info.get("name"), info.get("version"), @@ -107,10 +107,10 @@ def get_pypi_package_details(package_name): info.get("requires_dist") or [], list(data.get("releases", {}).keys()) ) - + except requests.exceptions.RequestException as e: return f"An error occurred while connecting to PyPI: {e}" - + @bot.tree.command(name="pypi", description="Displays a PyPI package by it's name.") @app_commands.describe(name="The pypi package name") async def pypi_package(interaction: discord.Interaction, name: str): @@ -119,26 +119,28 @@ async def pypi_package(interaction: discord.Interaction, name: str): return await interaction.response.defer() - + package_details = get_pypi_package_details(name) - + if isinstance(package_details, str): await interaction.followup.send(package_details) - + name, version, summary, author, _license, home_page, project_url, requires_dist, releases = package_details - + output = ( f"*** {name} v{version} by {author}***\n" f"{summary}\n" f"{len(releases)} total releases\n" f"{project_url}" ) - + await interaction.followup.send(output) -load_dotenv() -BOT_TOKEN = os.getenv("DISCORD_API") -if not BOT_TOKEN: - raise ValueError("The environmental variable DISCORD_API is empty. Please replace it with the bot token.") -bot.run(BOT_TOKEN) \ No newline at end of file +if __name__ == "__main__": + load_dotenv() + + BOT_TOKEN = os.getenv("DISCORD_API") + if not BOT_TOKEN: + raise ValueError("The environmental variable DISCORD_API is empty. Please replace it with the bot token.") + bot.run(BOT_TOKEN) From a111452747ae3fe9c40bd77bc7dbf5e81a779d46 Mon Sep 17 00:00:00 2001 From: roli2py Date: Sat, 15 Aug 2026 16:36:44 +0300 Subject: [PATCH 7/8] Add style guidelines Add the guidelines to mitigate typical mistakes when making changes to the code and resolve the problems on this basis more easily. --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a03f9ec..86316c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,7 @@ First, thank you for wanting to spend your time helping make this project better 1. By making PR, you agree that your code will be published under the [MIT License](https://opensource.org/license/MIT). 2. You agree to our [No LLM](#no-llm) rule. +3. You agree to follow the [style guidelines](#style-guidelines) when making changes to the code. ### No LLM @@ -28,6 +29,10 @@ Create an issue and PR, if you... If none of these cases are yours, then create an issue about your case and we'll discuss it. +### Style Guidelines + +The project follows [PEP 8](https://peps.python.org/pep-0008/). The only change is a maximum line length: limit all lines to a maximum of 120 symbols. + ## Security Send security issues to one of the authors' emails: [piston.pro0001@gmail.com](mailto:piston.pro0001@gmail.com) or [romanmashevskyi@proton.me](mailto:romanmashevskyi@proton.me). From d5a6227720a4c6a5e074e8b7192f9707a87a672f Mon Sep 17 00:00:00 2001 From: Thatcher Evans Date: Mon, 17 Aug 2026 07:22:24 -0600 Subject: [PATCH 8/8] Removed implicit `None` and uneeded comment --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 02c1507..4cbb7ba 100644 --- a/main.py +++ b/main.py @@ -29,7 +29,7 @@ async def on_ready(): @bot.event async def on_message(message): if message.author == bot.user: - return + return None was_mentioned = bot.user in message.mentions # message.mentions stores all @ mentions is_reply_to_bot = False @@ -45,7 +45,7 @@ async def on_message(message): pass if was_mentioned or is_reply_to_bot: - await message.reply("beep boop this is my impression of a non-commital robot") # Reply to the message with a funny comment ig + await message.reply("beep boop this is my impression of a non-commital robot") await bot.process_commands(message) @bot.tree.command(name="xkcd", description="Displays an xkcd comic by its number.")