From 9438b63c40fd4458ed4a2614e0174af8d0230efc Mon Sep 17 00:00:00 2001 From: Charlie Date: Sun, 1 Feb 2026 21:10:56 +1300 Subject: [PATCH] Im adding a config file this is part of the new cogly or what ever I call it --- README.md | 17 ++++---- bot.py | 117 ++++++++++++---------------------------------------- config.toml | 23 +++++++++++ 3 files changed, 56 insertions(+), 101 deletions(-) create mode 100644 config.toml diff --git a/README.md b/README.md index cf5060b..1324688 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,29 @@
- Booly - discord.py python Made by Chersbobers :3 -
# Overview - Booly bot (or better tooly) is a fork of my original discord bot tooly bot this is a updated fork that is easier to develop and use. - Fork freely just credit booly # Installation - there is 2 methods of install: 1. prehosted 100 servers limit servers can be slow and updates are tested there. 2. self host it ## Prehosted +[__Click me for invite__](__https://discord.com/oauth2/authorize?client_id=1466398693383995558&permissions=8&integration_type=0&scope=bot+applications.commands__) -[Click me for invite](https://discord.com/oauth2/authorize?client_id=1466398693383995558&permissions=8&integration_type=0&scope=bot+applications.commands) notes: again servers will most likely be slow and only 100 servers at a time if it reaches over a 100 servers I might host another one links will be updated. ## Self hosting - I recommended using the main stable repo (https://github.com/chersbobers/booly) for yours but the nightly branch is usable too (https://github.com/chersbobers/booly/tree/nightly) ### what you need - A server I use render because im broke with uptimerobot (note: Oregen servers are ip banned for me they might not be for you) - Also a discord bot with Presence Intent, Server Members Intent and Message Content Intent Envs: @@ -79,6 +70,12 @@ For the invite link it just needs bot and applications.commands - `/youtubestatus` - Check YouTube notification status - `/testlastvideo` - Test the last video notification +## Utility +- `/shorten` - Shorten a long URL with optional custom code +- `/expand` - Get the original URL from a short code +- `/listshort` - List all shortened URLs in the server +- `/deleteshort` - Delete a shortened URL by code + ## Info Commands - `/ping` - Check bot latency - `/serverinfo` - Get information about the server diff --git a/bot.py b/bot.py index f29862a..06fee17 100644 --- a/bot.py +++ b/bot.py @@ -3,21 +3,24 @@ from discord.ext import commands import os import json import logging +import tomllib from aiohttp import web import asyncio logging.basicConfig(level=logging.INFO) logger = logging.getLogger('bot') -CONFIG = { - 'xp_min': 15, - 'xp_max': 25, - 'xp_cooldown': 60, - 'xp_per_level': 100, - 'level_up_multiplier': 10, - 'data_file': 'data.json', - 'video_check_interval': 300 -} +def load_config(): + base_path = os.path.dirname(__file__) + config_path = os.path.join(base_path, "config.toml") + try: + with open(config_path, "rb") as f: + return tomllib.load(f) + except FileNotFoundError: + logger.error("config.toml missing.") + exit(1) + +CONFIG = load_config() class SimpleDB: def __init__(self, filename): @@ -41,13 +44,8 @@ class SimpleDB: key = f"{guild_id}_{user_id}" if key not in self.data['users']: self.data['users'][key] = { - 'coins': 0, - 'bank': 0, - 'level': 1, - 'xp': 0, - 'last_message': 0, - 'last_daily': 0, - 'last_work': 0 + 'coins': 0, 'bank': 0, 'level': 1, 'xp': 0, + 'last_message': 0, 'last_daily': 0, 'last_work': 0 } return self.data['users'][key] @@ -55,15 +53,6 @@ class SimpleDB: key = f"{guild_id}_{user_id}" self.data['users'][key] = data self.save() - - def get_all_guild_users(self, guild_id): - users = [] - for key, data in self.data['users'].items(): - if key.startswith(f"{guild_id}_"): - user_id = key.split('_')[1] - users.append({'user_id': user_id, 'data': data}) - users.sort(key=lambda x: (x['data']['level'], x['data']['xp']), reverse=True) - return users class MyBot(commands.Bot): def __init__(self): @@ -72,18 +61,18 @@ class MyBot(commands.Bot): intents.members = True super().__init__(command_prefix='/', intents=intents) - self.db = SimpleDB(CONFIG['data_file']) + self.db = SimpleDB(CONFIG['bot']['data_file']) self.config = CONFIG async def setup_hook(self): - await self.load_extension('cogs.leveling') - await self.load_extension('cogs.system') - await self.load_extension('cogs.economy') - await self.load_extension('cogs.fun') - await self.load_extension('cogs.utility') + for extension in self.config['bot']['enabled_cogs']: + try: + await self.load_extension(extension) + logger.info(f'Loaded: {extension}') + except Exception as e: + logger.error(f'Error {extension}: {e}') await self.tree.sync() - logger.info('All cogs loaded and commands synced!') bot = MyBot() @@ -92,21 +81,15 @@ async def health_check(request): async def redirect_handler(request): code = request.match_info.get('code', '') - - if os.path.exists(CONFIG['data_file']): + if os.path.exists(CONFIG['bot']['data_file']): try: - with open(CONFIG['data_file'], 'r') as f: + with open(CONFIG['bot']['data_file'], 'r') as f: data = json.load(f) - for guild_id, guild_data in data.get('guilds', {}).items(): if 'urls' in guild_data and code in guild_data['urls']: - return web.Response( - status=301, - headers={'Location': guild_data['urls'][code]} - ) + return web.Response(status=301, headers={'Location': guild_data['urls'][code]}) except Exception as e: logger.error(f'Error: {e}') - return web.Response(text='Not Found', status=404) async def start_web_server(): @@ -114,69 +97,21 @@ async def start_web_server(): app.router.add_get('/', health_check) app.router.add_get('/health', health_check) app.router.add_get('/{code}', redirect_handler) - runner = web.AppRunner(app) await runner.setup() - port = int(os.getenv('PORT', 8080)) site = web.TCPSite(runner, '0.0.0.0', port) await site.start() - logger.info(f'Web server running on port {port}') @bot.event async def on_ready(): asyncio.create_task(start_web_server()) - logger.info(f'Logged in as {bot.user}') - logger.info(f'Connected to {len(bot.guilds)} guilds') - await bot.change_presence(activity=discord.Game(name="/help")) - logger.info('All systems operational!') - -@bot.tree.command(name='help', description='Show all available commands') -async def help_command(interaction: discord.Interaction): - embed = discord.Embed( - title='Bot Commands', - description='Here are all the slash commands you can use!', - color=0x5865F2 - ) - embed.add_field( - name='Leveling & Economy', - value='`/rank` - View your rank\n`/leaderboard` - Top 10 users\n`/balance` - Check balance\n`/daily` - Daily reward\n`/work` - Work for coins', - inline=False - ) - embed.add_field( - name='Fun', - value='`/8ball` - Magic 8ball\n`/roll` - Roll dice\n`/flip` - Flip coin\n`/cat` - Random cat\n`/dog` - Random dog', - inline=False - ) - embed.add_field( - name='System & Moderation', - value='`/kick` - Kick member\n`/ban` - Ban member\n`/unban` - Unban user\n`/timeout` - Timeout member\n`/warn` - Warn member\n`/warnings` - View warnings\n`/clearwarnings` - Clear warnings\n`/purge` - Delete messages\n`/lock` - Lock channel\n`/unlock` - Unlock channel', - inline=False - ) - embed.add_field( - name='Reaction Roles & YouTube', - value='`/reactionrole` - Create reaction role\n`/removereactionrole` - Remove reaction role\n`/listreactionroles` - List reaction roles\n`/createreactionpanel` - Create panel\n`/setupyoutube` - Setup YouTube\n`/toggleyoutube` - Toggle YouTube\n`/youtubestatus` - YouTube status\n`/testlastvideo` - Test video', - inline=False - ) - embed.add_field( - name='Utility', - value='`/shorten` - Shorten a URL', - inline=False - ) - embed.add_field( - name='Info', - value='`/ping` - Bot latency\n`/serverinfo` - Server info\n`/userinfo` - User info', - inline=False - ) - await interaction.response.send_message(embed=embed) + await bot.change_presence(activity=discord.Game(name="Commands")) if __name__ == '__main__': token = os.getenv('DISCORD_TOKEN') if not token: - logger.error('DISCORD_TOKEN not set!') + logger.error('DISCORD_TOKEN not set') exit(1) - - logger.info("everythings working") - logger.info('hello from chersbobers and booly co :3') bot.run(token) \ No newline at end of file diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..442c07f --- /dev/null +++ b/config.toml @@ -0,0 +1,23 @@ +# this is the deafult config file +[bot] +data_file = "data.json" +# this allows you to pick your cogs if installing multiple +enabled_cogs = [ + "cogs.leveling", + "cogs.system", + "cogs.economy", + "cogs.fun", + "cogs.utility" +] + +# this might not even need a comment but xp +[xp] +min = 15 +max = 25 +cooldown = 60 +per_level = 100 +level_up_multiplier = 10 +# port and how many times it checks for videos +[web] +video_check_interval = 300 +port = 3000 \ No newline at end of file