#Any way to import commands from a folder without breaking script?
1 messages · Page 1 of 1 (latest)
Hi all!
Just so you know, I'm new to Discord bot development and this is my first Discord bot. I organised the commands inside a "commands" folder but when it comes to using them they throw a KeyError which I have not been able to find a fix for.
main.py
import os
from interactions import Client, Intents, listen
bot = Client(
token="REDACTED",
intents=Intents.DEFAULT,
)
guild_ids = [REDACTED]
colors = [
0x2ECC71, # Green
0x3498DB, # Blue
0xE74C3C, # Red
0xF1C40F, # Yellow
0x9B59B6, # Purple
]
# List all command files in the "commands" folder
command_files = [file for file in os.listdir("commands") if file.endswith(".py")]
# Import each command module and pass the bot instance
for file in command_files:
module_name = file[:-3] # Remove the ".py" extension
command_module = __import__(f"commands.{module_name}", fromlist=[module_name])
command_module.setup(bot, colors) # Pass the bot instance to the command module
@listen()
async def on_ready():
print(f"{bot.user} is Ready | Owner: {bot.owner}")
bot.start()
An example command, commands/ping.py
import random
import datetime
from interactions import Embed, slash_command, SlashContext
def setup(bot, colors):
@slash_command(name="ping", description="Pong!")
async def ping(ctx: SlashContext):
embed = Embed(
title="Ping Test",
description=f":ping_pong: Pong! ({bot.latency * 1000}ms)",
color=random.choice(colors),
timestamp=datetime.datetime.now(),
)
await ctx.send(embeds=embed)
Error thrown upon usage:
Task exception was never retrieved
future: <Task finished name='Task-52' coro=<Client._dispatch_interaction() done, defined at C:\Users\zeesh\AppData\Local\Programs\Python\Python310\lib\site-packages\interactions\client\client.py:1773> exception=KeyError('ping')>
Traceback (most recent call last):
File "C:\Users\zeesh\AppData\Local\Programs\Python\Python310\lib\site-packages\interactions\client\client.py", line 1798, in _dispatch_interaction
if ctx.command:
File "C:\Users\zeesh\AppData\Local\Programs\Python\Python310\lib\site-packages\interactions\models\internal\context.py", line 329, in command
return self.client._interaction_lookup[self._command_name]
KeyError: 'ping'
That is not how you use different files, use extensions!
Extensions are an easy way of organzing and scaling your bot into different files. Check out this guide for more information.
Ah okay sure, testing that right now.
So I tried to use this with the ping command but I ended up getting the same error.
For context my main.py is now:
import os, random, datetime, requests, glob
from importlib import import_module
from commands.data.plugins import failedEmbed
from interactions import (
Client,
Intents,
listen,
Embed,
slash_command,
modal_callback,
SlashContext,
Modal,
ModalContext,
ShortText,
slash_option,
OptionType,
ParagraphText,
) # I'll remove the unused ones later
bot = Client(
token="REDACTED",
intents=Intents.DEFAULT | Intents.GUILDS,
)
guild_ids = [REDACTED]
command_filenames = glob.glob("commands/*.py")
command_names = [
filename.removesuffix(".py").replace("/", ".") for filename in command_filenames
]
for command in command_names:
bot.load_extension(command)
@listen()
async def on_ready():
print(f"{bot.user} is Ready | Owner: {bot.owner}\n")
for guild_id in guild_ids:
server = bot.get_guild(guild_id)
server_name = server.name if server else "Unknown Server"
# Print server name and member count
print(f"Server: {server_name}")
bot.start()
And my commands/ping.py is now:
import random
import datetime
from interactions import Embed, slash_command, SlashContext
def setup(bot):
@slash_command(name="ping", description="Pong!")
async def ping(ctx: SlashContext):
embed = Embed(
title="Ping Test",
description=f":ping_pong: Pong! ({bot.latency * 1000}ms)",
color=random.choice(colors),
timestamp=datetime.datetime.now(),
)
await ctx.send(embeds=embed)
I'm still confused on how to properly use this as upon running the command from the bot the same error happens.
Just wondering, do I need to add classes for each extension as shown in the docs?