I am making a discord.py bot that utilizes slash commands aswell as text based commands. I am using cogs to order them properly but the slash commands do not want to sync so I cannot use them.
Folder discord_bot -> main.py, cogs(folder); cogs -> embed.py, etc
This is main.py where I am syncing up the bot and calling in tree.sync stuff.
import os
import discord
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.presences = True
intents.voice_states = True
bot = commands.Bot(command_prefix='$', intents=intents)
async def load_extensions():
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
cog_name = f"cogs.{filename[:-3]}"
try:
await bot.load_extension(cog_name)
print(f"Loaded extension: {cog_name}")
except Exception as e:
print(f"Failed to load extension {cog_name}: {e}")
@bot.event
async def on_ready():
print(f'We have logged in as {bot.user}')
try:
# Print all commands in the command tree before syncing
print("Commands before sync:")
for command in bot.tree.get_commands():
print(f"- {command.name}")
print("Attempting to sync slash commands...")
synced = await bot.tree.sync()
print(f"Synced {len(synced)} command(s)")
# Print all commands in the command tree after syncing
print("Registered slash commands after sync:")
for command in bot.tree.get_commands():
print(f"- {command.name}")
except Exception as e:
print(f"Error during sync: {e}")
await bot.change_presence(status=discord.Status.dnd, activity=discord.Game('Watching over you\n Prefix: $'))
await load_extensions()
try:
token = os.getenv('DISCORD_TOKEN')
if token == "":
raise Exception("Please add your token to the Secrets pane.")
bot.run(token)
except discord.HTTPException as e:
if e.status == 429:
print("The Discord servers denied the connection for making too many requests")
print("Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests")
else:
raise e
This is embed.py. Structure where I am using slash commands.
from discord.ext import commands
import discord
from discord import app_commands
import random
class Embeds(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
#sync slash commands when cogs is loaded
await self.bot.tree.sync()
print(f"Slash commands synced for {self.__class__.__name__}")
@commands.command(help="Send an embed to a channel. Format: $embed [title] [description] [color hex, type random / r to randomize it] [channel]\n Note: Use "" to seperate title and description ")
async def embed(self, ctx, title: str, description: str, color: str, channel: discord.TextChannel):
if channel.permissions_for(ctx.author).send_messages:
try:
if color.lower() == "r" or color.lower() == "random":
color_int = discord.Color.from_rgb(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
else:
color_int = discord.Color(int(color, 16))
embed = discord.Embed(title=title, description=description, color=color_int)
send_channel = channel or ctx.channel
await send_channel.send(embed=embed)
await ctx.send(f"Embed sent to {send_channel.mention}.")
except discord.Forbidden:
await ctx.send("Cannot send message in the specified channel. Please check if the bot has desired permissions.")
else:
await ctx.send("You don't have permissions to use this command.")
@app_commands.command(name="embed", description="Embed generator")
@app_commands.describe(
title = "Title",
description = "Description",
color = "Hex color code or 'random' to randomize it",
channel = "Where to send embed"
)
async def embed_slash(self, interaction: discord.interactions, title: str, description: str, color: str, channel: discord.TextChannel):
if color.lower() == "random":
color_int = discord.Color.from_rgb(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
else:
color_int = color
embed = discord.Embed(title=title, description=description, color=color_int)
await channel.send(embed=embed)
await interaction.response.send_message(f"Embed sent successfully in {channel.mention}", ephemeral = True)
async def setup(bot):
await bot.add_cog(Embeds(bot))
This is coin_flip.py. Structure where I am NOT using slash commands.
from discord.ext import commands
import random
class coin_flip(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name="flip", help="Flip a coin.")
async def flip(self, ctx):
sides = ['heads', 'tails']
output_side = random.choice(sides)
await ctx.send(f"{ctx.author.mention} {output_side}")
async def setup(bot):
await bot.add_cog(coin_flip(bot))
I am using the same structure for where I am using slash commands and same structure for where I am not using slash commands.
Interestingly if I just have text based commands in cogs and the slash commands in main.py then the commands work perfectly fine. But idk why tho.
This answer solved my issue. Bot wasn't syncing in on_ready. When I created a slash command to sync however, it worked. Now I have just created a try, except config to automatically sync in on_ready and that workes apparently. I still don't know why but yes it works now. Thank you for whoever saw this post and helped me!