Download main.py from wpms/bot: direct link, hf CLI and curl.
- Browser
- Download file 17 kB
-
https://huggingface.co/spaces/wpms/bot/resolve/main/main.py
- Command line
-
hf download hf://spaces/wpms/bot/main.py
-
curl -L -o main.py https://huggingface.co/spaces/wpms/bot/resolve/main/main.py
17 kB
| import discord | |
| from discord.ext import commands, tasks | |
| import os | |
| import asyncio | |
| from datetime import datetime | |
| import logging | |
| from flask import Flask | |
| from threading import Thread | |
| # Setup logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| logger = logging.getLogger('discord_bot') | |
| # Flask web server | |
| app = Flask(__name__) | |
| def home(): | |
| return "hey, bot started✅" | |
| def run_web(): | |
| app.run(host='0.0.0.0', port=7860) | |
| # Start web server in a thread | |
| web_thread = Thread(target=run_web) | |
| web_thread.start() | |
| # Bot configuration | |
| TOKEN = os.getenv('DISCORD_TOKEN') | |
| if not TOKEN: | |
| raise ValueError("DISCORD_TOKEN environment variable is required!") | |
| # Bot intents | |
| intents = discord.Intents.default() | |
| intents.message_content = True | |
| intents.members = True | |
| intents.presences = True | |
| # Create bot instance | |
| bot = commands.Bot( | |
| command_prefix='!', | |
| intents=intents, | |
| help_command=None, | |
| case_insensitive=True | |
| ) | |
| # Event: Bot ready | |
| async def on_ready(): | |
| logger.info(f'✅ Bot logged in as {bot.user.name} ({bot.user.id})') | |
| logger.info(f'🌐 Connected to {len(bot.guilds)} guilds') | |
| await bot.change_presence( | |
| activity=discord.Activity( | |
| type=discord.ActivityType.watching, | |
| name=f"{len(bot.guilds)} servers | !help" | |
| ), | |
| status=discord.Status.online | |
| ) | |
| status_update.start() | |
| # Background task: Update status every 5 minutes | |
| async def status_update(): | |
| await bot.change_presence( | |
| activity=discord.Activity( | |
| type=discord.ActivityType.watching, | |
| name=f"{len(bot.guilds)} servers | !help" | |
| ), | |
| status=discord.Status.online | |
| ) | |
| async def on_guild_join(guild): | |
| logger.info(f'➕ Joined guild: {guild.name} ({guild.id})') | |
| async def on_guild_remove(guild): | |
| logger.info(f'➖ Left guild: {guild.name} ({guild.id})') | |
| async def on_message(message): | |
| if message.author.bot: | |
| return | |
| await bot.process_commands(message) | |
| # ==================== COMMANDS ==================== | |
| async def help_command(ctx, command_name: str = None): | |
| """Show help information""" | |
| if command_name: | |
| command = bot.get_command(command_name) | |
| if command: | |
| embed = discord.Embed( | |
| title=f"📖 Help: !{command.name}", | |
| description=command.help or "No description available", | |
| color=discord.Color.blue() | |
| ) | |
| embed.add_field( | |
| name="Usage", | |
| value=f"`!{command.name} {command.signature}`" if command.signature else f"`!{command.name}`", | |
| inline=False | |
| ) | |
| if command.aliases: | |
| embed.add_field( | |
| name="Aliases", | |
| value=", ".join([f"`!{alias}`" for alias in command.aliases]), | |
| inline=False | |
| ) | |
| await ctx.send(embed=embed) | |
| else: | |
| await ctx.send(f"❌ Command `!{command_name}` not found!") | |
| else: | |
| embed = discord.Embed( | |
| title="🤖 Bot Commands", | |
| description="Here are all available commands:", | |
| color=discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| categories = { | |
| "General": ['help', 'ping', 'info', 'serverinfo', 'userinfo'], | |
| "Fun": ['say', 'embed', 'poll', '8ball', 'coinflip'], | |
| "Utility": ['avatar', 'invite', 'uptime', 'clear'] | |
| } | |
| for category, cmds in categories.items(): | |
| valid_cmds = [] | |
| for cmd_name in cmds: | |
| cmd = bot.get_command(cmd_name) | |
| if cmd: | |
| valid_cmds.append(f"`!{cmd.name}`") | |
| if valid_cmds: | |
| embed.add_field( | |
| name=f"📁 {category}", | |
| value=" | ".join(valid_cmds), | |
| inline=False | |
| ) | |
| embed.set_footer(text=f"Use !help <command> for more details | Prefix: !") | |
| await ctx.send(embed=embed) | |
| async def ping_command(ctx): | |
| """Check bot latency""" | |
| latency = round(bot.latency * 1000) | |
| embed = discord.Embed( | |
| title="🏓 Pong!", | |
| description=f"**Latency:** `{latency}ms`\n**API Latency:** `{round(bot.latency * 1000)}ms`", | |
| color=discord.Color.green() if latency < 200 else discord.Color.orange() if latency < 500 else discord.Color.red() | |
| ) | |
| embed.set_footer(text=f"Requested by {ctx.author.name}") | |
| await ctx.send(embed=embed) | |
| async def info_command(ctx): | |
| """Show bot information""" | |
| embed = discord.Embed( | |
| title="🤖 Bot Information", | |
| description="A Discord bot powered by discord.py", | |
| color=discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| embed.add_field(name="Bot Name", value=bot.user.name, inline=True) | |
| embed.add_field(name="Bot ID", value=bot.user.id, inline=True) | |
| embed.add_field(name="Servers", value=len(bot.guilds), inline=True) | |
| embed.add_field(name="Users", value=sum(g.member_count for g in bot.guilds), inline=True) | |
| embed.add_field(name="Library", value="discord.py", inline=True) | |
| embed.add_field(name="Python Version", value="3.10+", inline=True) | |
| embed.add_field(name="Created", value=bot.user.created_at.strftime("%Y-%m-%d"), inline=True) | |
| embed.add_field(name="Uptime", value=get_uptime(), inline=True) | |
| embed.set_thumbnail(url=bot.user.avatar.url if bot.user.avatar else bot.user.default_avatar.url) | |
| embed.set_footer(text="Made with ❤️ using discord.py") | |
| await ctx.send(embed=embed) | |
| async def serverinfo_command(ctx): | |
| """Show server information""" | |
| guild = ctx.guild | |
| embed = discord.Embed( | |
| title=f"📊 {guild.name} Server Info", | |
| color=discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| embed.add_field(name="Server ID", value=guild.id, inline=True) | |
| embed.add_field(name="Owner", value=guild.owner.mention if guild.owner else "Unknown", inline=True) | |
| embed.add_field(name="Members", value=guild.member_count, inline=True) | |
| embed.add_field(name="Channels", value=f"{len(guild.text_channels)} Text | {len(guild.voice_channels)} Voice", inline=True) | |
| embed.add_field(name="Roles", value=len(guild.roles), inline=True) | |
| embed.add_field(name="Created", value=guild.created_at.strftime("%Y-%m-%d"), inline=True) | |
| embed.add_field(name="Boost Level", value=f"Level {guild.premium_tier} ({guild.premium_subscription_count} boosts)", inline=True) | |
| if guild.icon: | |
| embed.set_thumbnail(url=guild.icon.url) | |
| await ctx.send(embed=embed) | |
| async def userinfo_command(ctx, member: discord.Member = None): | |
| """Show user information""" | |
| member = member or ctx.author | |
| embed = discord.Embed( | |
| title=f"👤 {member.name}'s Profile", | |
| color=member.color if member.color != discord.Color.default() else discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| embed.add_field(name="Username", value=member.name, inline=True) | |
| embed.add_field(name="Display Name", value=member.display_name, inline=True) | |
| embed.add_field(name="ID", value=member.id, inline=True) | |
| embed.add_field(name="Joined Server", value=member.joined_at.strftime("%Y-%m-%d %H:%M") if member.joined_at else "Unknown", inline=True) | |
| embed.add_field(name="Account Created", value=member.created_at.strftime("%Y-%m-%d %H:%M"), inline=True) | |
| embed.add_field(name="Status", value=str(member.status).title(), inline=True) | |
| embed.add_field(name="Top Role", value=member.top_role.mention, inline=True) | |
| embed.add_field(name="Bot?", value="Yes" if member.bot else "No", inline=True) | |
| roles = [role.mention for role in member.roles if role != ctx.guild.default_role] | |
| if roles: | |
| embed.add_field(name=f"Roles ({len(roles)})", value=" ".join(roles[:10]) + ("..." if len(roles) > 10 else ""), inline=False) | |
| embed.set_thumbnail(url=member.avatar.url if member.avatar else member.default_avatar.url) | |
| embed.set_footer(text=f"Requested by {ctx.author.name}") | |
| await ctx.send(embed=embed) | |
| async def avatar_command(ctx, member: discord.Member = None): | |
| """Show user's avatar""" | |
| member = member or ctx.author | |
| embed = discord.Embed( | |
| title=f"🖼️ {member.name}'s Avatar", | |
| color=discord.Color.blue() | |
| ) | |
| avatar_url = member.avatar.url if member.avatar else member.default_avatar.url | |
| embed.set_image(url=avatar_url) | |
| embed.add_field(name="Links", value=f"[PNG]({member.avatar.url if member.avatar else member.default_avatar.url}) | [WEBP]({member.avatar.url if member.avatar else member.default_avatar.url})", inline=False) | |
| await ctx.send(embed=embed) | |
| async def say_command(ctx, *, message: str): | |
| """Make the bot say something""" | |
| await ctx.message.delete() | |
| await ctx.send(message) | |
| async def embed_command(ctx, *, message: str): | |
| """Create a custom embed""" | |
| embed = discord.Embed( | |
| description=message, | |
| color=discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url) | |
| await ctx.send(embed=embed) | |
| async def poll_command(ctx, *, question: str): | |
| """Create a poll""" | |
| embed = discord.Embed( | |
| title="📊 Poll", | |
| description=question, | |
| color=discord.Color.blue(), | |
| timestamp=datetime.now() | |
| ) | |
| embed.set_footer(text=f"Poll by {ctx.author.name}") | |
| poll_message = await ctx.send(embed=embed) | |
| await poll_message.add_reaction("👍") | |
| await poll_message.add_reaction("👎") | |
| await poll_message.add_reaction("🤷") | |
| async def eightball_command(ctx, *, question: str): | |
| """Ask the magic 8-ball""" | |
| import random | |
| responses = [ | |
| "🎱 It is certain.", | |
| "🎱 It is decidedly so.", | |
| "🎱 Without a doubt.", | |
| "🎱 Yes definitely.", | |
| "🎱 You may rely on it.", | |
| "🎱 As I see it, yes.", | |
| "🎱 Most likely.", | |
| "🎱 Outlook good.", | |
| "🎱 Yes.", | |
| "🎱 Signs point to yes.", | |
| "🎱 Reply hazy, try again.", | |
| "🎱 Ask again later.", | |
| "🎱 Better not tell you now.", | |
| "🎱 Cannot predict now.", | |
| "🎱 Concentrate and ask again.", | |
| "🎱 Don't count on it.", | |
| "🎱 My reply is no.", | |
| "🎱 My sources say no.", | |
| "🎱 Outlook not so good.", | |
| "🎱 Very doubtful." | |
| ] | |
| embed = discord.Embed( | |
| title="🎱 Magic 8-Ball", | |
| color=discord.Color.purple() | |
| ) | |
| embed.add_field(name="Question", value=question, inline=False) | |
| embed.add_field(name="Answer", value=random.choice(responses), inline=False) | |
| await ctx.send(embed=embed) | |
| async def coinflip_command(ctx): | |
| """Flip a coin""" | |
| import random | |
| result = random.choice(["Heads", "Tails"]) | |
| emoji = "🪙" if result == "Heads" else "🪙" | |
| embed = discord.Embed( | |
| title=f"{emoji} Coin Flip", | |
| description=f"**Result:** {result}", | |
| color=discord.Color.gold() | |
| ) | |
| await ctx.send(embed=embed) | |
| async def invite_command(ctx): | |
| """Get bot invite link""" | |
| permissions = discord.Permissions( | |
| send_messages=True, | |
| embed_links=True, | |
| read_messages=True, | |
| read_message_history=True, | |
| add_reactions=True, | |
| use_external_emojis=True, | |
| attach_files=True, | |
| manage_messages=True, | |
| connect=True, | |
| speak=True | |
| ) | |
| invite_url = discord.utils.oauth_url(bot.user.id, permissions=permissions) | |
| embed = discord.Embed( | |
| title="🔗 Invite Bot", | |
| description=f"[Click here to invite me!]({invite_url})", | |
| color=discord.Color.green() | |
| ) | |
| embed.add_field(name="Bot ID", value=bot.user.id, inline=False) | |
| await ctx.send(embed=embed) | |
| async def clear_command(ctx, amount: int = 5): | |
| """Clear messages (requires Manage Messages permission)""" | |
| if amount < 1 or amount > 100: | |
| await ctx.send("❌ Please specify a number between 1 and 100!") | |
| return | |
| deleted = await ctx.channel.purge(limit=amount + 1) | |
| embed = discord.Embed( | |
| description=f"🗑️ Deleted {len(deleted) - 1} messages!", | |
| color=discord.Color.green() | |
| ) | |
| msg = await ctx.send(embed=embed) | |
| await asyncio.sleep(3) | |
| await msg.delete() | |
| async def uptime_command(ctx): | |
| """Show bot uptime""" | |
| embed = discord.Embed( | |
| title="⏱️ Bot Uptime", | |
| description=get_uptime(), | |
| color=discord.Color.blue() | |
| ) | |
| await ctx.send(embed=embed) | |
| # ==================== ERROR HANDLER (FIXED) ==================== | |
| async def on_command_error(ctx, error): | |
| # Ignore if we can't send messages due to connection issues | |
| try: | |
| if isinstance(error, commands.CommandNotFound): | |
| return | |
| elif isinstance(error, commands.MissingRequiredArgument): | |
| embed = discord.Embed( | |
| title="❌ Missing Argument", | |
| description=f"Missing required argument: `{error.param.name}`\nUse `!help {ctx.command.name}` for usage info.", | |
| color=discord.Color.red() | |
| ) | |
| await ctx.send(embed=embed) | |
| elif isinstance(error, commands.MissingPermissions): | |
| embed = discord.Embed( | |
| title="❌ Missing Permissions", | |
| description=f"You need `{', '.join(error.missing_permissions)}` permission to use this command.", | |
| color=discord.Color.red() | |
| ) | |
| await ctx.send(embed=embed) | |
| elif isinstance(error, commands.MemberNotFound): | |
| embed = discord.Embed( | |
| title="❌ User Not Found", | |
| description="The specified user was not found.", | |
| color=discord.Color.red() | |
| ) | |
| await ctx.send(embed=embed) | |
| elif isinstance(error, commands.CommandInvokeError): | |
| # Handle connection errors gracefully | |
| original = error.original | |
| if isinstance(original, aiohttp.ClientConnectorError): | |
| logger.warning(f"Connection error in command {ctx.command.name}: {original}") | |
| # Don't try to send message - connection is down | |
| return | |
| else: | |
| logger.error(f"Command error: {error}") | |
| embed = discord.Embed( | |
| title="❌ Error", | |
| description="An unexpected error occurred. Please try again later.", | |
| color=discord.Color.red() | |
| ) | |
| await ctx.send(embed=embed) | |
| else: | |
| logger.error(f"Command error: {error}") | |
| embed = discord.Embed( | |
| title="❌ Error", | |
| description="An unexpected error occurred. Please try again later.", | |
| color=discord.Color.red() | |
| ) | |
| await ctx.send(embed=embed) | |
| except Exception as e: | |
| # If we can't even send the error message, just log it | |
| logger.error(f"Failed to send error message: {e}") | |
| # Helper function: Get uptime | |
| start_time = datetime.now() | |
| def get_uptime(): | |
| delta = datetime.now() - start_time | |
| days = delta.days | |
| hours, remainder = divmod(delta.seconds, 3600) | |
| minutes, seconds = divmod(remainder, 60) | |
| parts = [] | |
| if days > 0: | |
| parts.append(f"{days}d") | |
| if hours > 0: | |
| parts.append(f"{hours}h") | |
| if minutes > 0: | |
| parts.append(f"{minutes}m") | |
| parts.append(f"{seconds}s") | |
| return " ".join(parts) | |
| # Run the bot with auto-reconnect | |
| if __name__ == "__main__": | |
| while True: | |
| try: | |
| bot.run(TOKEN, reconnect=True) | |
| except Exception as e: | |
| logger.error(f"Bot crashed: {e}") | |
| logger.info("Restarting bot in 10 seconds...") | |
| import time | |
| time.sleep(10) | |