import discord from discord.ext import commands import os import asyncio import logging from dotenv import load_dotenv # Load environment variables load_dotenv() # Configure logging logging.basicConfig(level=logging.INFO) # Bot configuration intents = discord.Intents.default() intents.message_content = True intents.guilds = True intents.members = True bot = commands.Bot(command_prefix='!', intents=intents) @bot.event async def on_ready(): """Event triggered when the bot is ready""" print(f'{bot.user} is online and ready!') print(f'Bot ID: {bot.user.id}') print(f'Discord.py Version: {discord.__version__}') print('------') # Set bot status await bot.change_presence( activity=discord.Game(name="Hearts of Iron IV"), status=discord.Status.online ) # Sync hybrid commands on startup try: synced = await bot.tree.sync() print(f'Synced {len(synced)} hybrid commands') except Exception as e: print(f'Failed to sync commands: {e}') @bot.event async def on_guild_join(guild): """Event triggered when the bot joins a server""" print(f'Bot joined server "{guild.name}" (ID: {guild.id})') @bot.event async def on_guild_remove(guild): """Event triggered when the bot leaves a server""" print(f'Bot left server "{guild.name}" (ID: {guild.id})') # Owner Configuration OWNER_ID = 253922739709018114 # Owner only decorator def is_owner(): def predicate(ctx): return ctx.author.id == OWNER_ID return commands.check(predicate) # Owner Commands @bot.hybrid_command(name='reload', description='Reloads the bot and syncs slash commands (Owner only)') @is_owner() async def reload_bot(ctx): """Reloads the bot and syncs slash commands (Owner only)""" try: # Send initial message embed = discord.Embed( title="🔄 Bot Reload", description="Reloading bot and syncing commands...", color=discord.Color.yellow() ) message = await ctx.send(embed=embed) # Sync slash commands synced = await bot.tree.sync() # Update embed with success embed = discord.Embed( title="✅ Bot Reloaded Successfully", description=f"Bot has been reloaded!\nSynced {len(synced)} slash commands.", color=discord.Color.green() ) embed.add_field(name="Servers", value=len(bot.guilds), inline=True) embed.add_field(name="Latency", value=f"{round(bot.latency * 1000)}ms", inline=True) embed.set_footer(text=f"Reloaded by {ctx.author}", icon_url=ctx.author.avatar.url if ctx.author.avatar else None) await message.edit(embed=embed) except Exception as e: embed = discord.Embed( title="❌ Reload Failed", description=f"Error during reload: {str(e)}", color=discord.Color.red() ) await ctx.send(embed=embed) @bot.event async def on_command_error(ctx, error): """Handles command errors""" if isinstance(error, commands.CheckFailure): await ctx.send("❌ You don't have permission to use this command!") elif isinstance(error, commands.CommandNotFound): # Silently ignore command not found errors pass elif isinstance(error, commands.MissingRequiredArgument): await ctx.send(f"❌ Missing arguments! Command: `{ctx.command}`") elif isinstance(error, commands.BadArgument): await ctx.send("❌ Invalid argument!") else: print(f"Unknown error: {error}") await ctx.send("❌ An unknown error occurred!") async def main(): """Main function to start the bot""" # Load Discord token from environment variables token = os.getenv('DISCORD_TOKEN') if not token: print("❌ DISCORD_TOKEN environment variable not found!") print("Please set the DISCORD_TOKEN variable in Coolify or create a .env file") return try: print("🚀 Starting bot...") await bot.start(token) except discord.LoginFailure: print("❌ Invalid Discord token!") except Exception as e: print(f"❌ Error starting bot: {e}") if __name__ == "__main__": asyncio.run(main())