import discord from discord.ext import commands, tasks import asyncio import os import stripe from aiohttp import web from dotenv import load_dotenv from database.models import init_db, seed_stickers from payments.stripe_handler import poll_and_fulfill load_dotenv() TOKEN = os.getenv("DISCORD_TOKEN") _guild_id_raw = os.getenv("DISCORD_GUILD_ID", "").strip() GUILD_ID = int(_guild_id_raw) if _guild_id_raw else None intents = discord.Intents.default() intents.message_content = True intents.members = True bot = commands.Bot(command_prefix="!", intents=intents) COGS = ["cogs.shop", "cogs.buy", "cogs.inventory", "cogs.blender_help"] @tasks.loop(seconds=30) async def poll_stripe(): poll_and_fulfill(bot) @bot.event async def on_ready(): print(f"Logged in as {bot.user} (ID: {bot.user.id})") try: if GUILD_ID: guild = discord.Object(id=GUILD_ID) bot.tree.copy_global_to(guild=guild) synced = await bot.tree.sync(guild=guild) print(f"Synced {len(synced)} command(s) to guild.") else: synced = await bot.tree.sync() print(f"Globally synced {len(synced)} command(s).") except discord.Forbidden: print("Guild sync failed — bot not in server. Trying global sync...") try: synced = await bot.tree.sync() print(f"Globally synced {len(synced)} command(s). May take up to 1hr to appear.") except Exception as e: print(f"Global sync error: {e}") except Exception as e: print(f"Sync error: {e}") poll_stripe.start() print("Stripe polling started (every 30s).") async def health(request): return web.Response(text="ok") async def start_health_server(): app = web.Application() app.router.add_get("/health", health) app.router.add_get("/", health) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, "0.0.0.0", 7860) await site.start() print("Health server running on port 7860") async def main(): init_db() seed_stickers() await start_health_server() async with bot: for cog in COGS: await bot.load_extension(cog) print(f"Loaded {cog}") await bot.start(TOKEN) if __name__ == "__main__": asyncio.run(main())