Files
hoi4botdc/app.py
2025-10-26 00:23:34 +02:00

134 lines
4.2 KiB
Python

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())