Im adding a config file this is part of the new cogly or what ever I call it

This commit is contained in:
Charlie 2026-02-01 21:10:56 +13:00
parent e70d126a95
commit 9438b63c40
3 changed files with 56 additions and 101 deletions

View file

@ -1,38 +1,29 @@
<div align="center"> <div align="center">
<img src="https://files.catbox.moe/zuj0ob.png" alt="Booly" width="100%"> <img src="https://files.catbox.moe/zuj0ob.png" alt="Booly" width="100%">
<img src="https://img.shields.io/badge/discord.py-2.0+-5865F2?style=flat&logo=discord&logoColor=white" alt="discord.py"> <img src="https://img.shields.io/badge/discord.py-2.0+-5865F2?style=flat&logo=discord&logoColor=white" alt="discord.py">
<img src="https://img.shields.io/badge/Python-3.8+-3776AB?style=flat&logo=python&logoColor=white" alt="python"> <img src="https://img.shields.io/badge/Python-3.8+-3776AB?style=flat&logo=python&logoColor=white" alt="python">
<img src="https://img.shields.io/badge/made%20by-chersbobers%20%3A3-FF69B4?style=flat&labelColor=555555" alt="Made by Chersbobers :3"> <img src="https://img.shields.io/badge/made%20by-chersbobers%20%3A3-FF69B4?style=flat&labelColor=555555" alt="Made by Chersbobers :3">
</div> </div>
# Overview # 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. 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 Fork freely just credit booly
# Installation # Installation
there is 2 methods of install: there is 2 methods of install:
1. prehosted 100 servers limit servers can be slow and updates are tested there. 1. prehosted 100 servers limit servers can be slow and updates are tested there.
2. self host it 2. self host it
## Prehosted ## 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. 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 ## 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) 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 ### 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) 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 Also a discord bot with Presence Intent, Server Members Intent and Message Content Intent
Envs: Envs:
@ -79,6 +70,12 @@ For the invite link it just needs bot and applications.commands
- `/youtubestatus` - Check YouTube notification status - `/youtubestatus` - Check YouTube notification status
- `/testlastvideo` - Test the last video notification - `/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 ## Info Commands
- `/ping` - Check bot latency - `/ping` - Check bot latency
- `/serverinfo` - Get information about the server - `/serverinfo` - Get information about the server

117
bot.py
View file

@ -3,21 +3,24 @@ from discord.ext import commands
import os import os
import json import json
import logging import logging
import tomllib
from aiohttp import web from aiohttp import web
import asyncio import asyncio
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('bot') logger = logging.getLogger('bot')
CONFIG = { def load_config():
'xp_min': 15, base_path = os.path.dirname(__file__)
'xp_max': 25, config_path = os.path.join(base_path, "config.toml")
'xp_cooldown': 60, try:
'xp_per_level': 100, with open(config_path, "rb") as f:
'level_up_multiplier': 10, return tomllib.load(f)
'data_file': 'data.json', except FileNotFoundError:
'video_check_interval': 300 logger.error("config.toml missing.")
} exit(1)
CONFIG = load_config()
class SimpleDB: class SimpleDB:
def __init__(self, filename): def __init__(self, filename):
@ -41,13 +44,8 @@ class SimpleDB:
key = f"{guild_id}_{user_id}" key = f"{guild_id}_{user_id}"
if key not in self.data['users']: if key not in self.data['users']:
self.data['users'][key] = { self.data['users'][key] = {
'coins': 0, 'coins': 0, 'bank': 0, 'level': 1, 'xp': 0,
'bank': 0, 'last_message': 0, 'last_daily': 0, 'last_work': 0
'level': 1,
'xp': 0,
'last_message': 0,
'last_daily': 0,
'last_work': 0
} }
return self.data['users'][key] return self.data['users'][key]
@ -55,15 +53,6 @@ class SimpleDB:
key = f"{guild_id}_{user_id}" key = f"{guild_id}_{user_id}"
self.data['users'][key] = data self.data['users'][key] = data
self.save() 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): class MyBot(commands.Bot):
def __init__(self): def __init__(self):
@ -72,18 +61,18 @@ class MyBot(commands.Bot):
intents.members = True intents.members = True
super().__init__(command_prefix='/', intents=intents) super().__init__(command_prefix='/', intents=intents)
self.db = SimpleDB(CONFIG['data_file']) self.db = SimpleDB(CONFIG['bot']['data_file'])
self.config = CONFIG self.config = CONFIG
async def setup_hook(self): async def setup_hook(self):
await self.load_extension('cogs.leveling') for extension in self.config['bot']['enabled_cogs']:
await self.load_extension('cogs.system') try:
await self.load_extension('cogs.economy') await self.load_extension(extension)
await self.load_extension('cogs.fun') logger.info(f'Loaded: {extension}')
await self.load_extension('cogs.utility') except Exception as e:
logger.error(f'Error {extension}: {e}')
await self.tree.sync() await self.tree.sync()
logger.info('All cogs loaded and commands synced!')
bot = MyBot() bot = MyBot()
@ -92,21 +81,15 @@ async def health_check(request):
async def redirect_handler(request): async def redirect_handler(request):
code = request.match_info.get('code', '') code = request.match_info.get('code', '')
if os.path.exists(CONFIG['bot']['data_file']):
if os.path.exists(CONFIG['data_file']):
try: try:
with open(CONFIG['data_file'], 'r') as f: with open(CONFIG['bot']['data_file'], 'r') as f:
data = json.load(f) data = json.load(f)
for guild_id, guild_data in data.get('guilds', {}).items(): for guild_id, guild_data in data.get('guilds', {}).items():
if 'urls' in guild_data and code in guild_data['urls']: if 'urls' in guild_data and code in guild_data['urls']:
return web.Response( return web.Response(status=301, headers={'Location': guild_data['urls'][code]})
status=301,
headers={'Location': guild_data['urls'][code]}
)
except Exception as e: except Exception as e:
logger.error(f'Error: {e}') logger.error(f'Error: {e}')
return web.Response(text='Not Found', status=404) return web.Response(text='Not Found', status=404)
async def start_web_server(): 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_check)
app.router.add_get('/health', health_check) app.router.add_get('/health', health_check)
app.router.add_get('/{code}', redirect_handler) app.router.add_get('/{code}', redirect_handler)
runner = web.AppRunner(app) runner = web.AppRunner(app)
await runner.setup() await runner.setup()
port = int(os.getenv('PORT', 8080)) port = int(os.getenv('PORT', 8080))
site = web.TCPSite(runner, '0.0.0.0', port) site = web.TCPSite(runner, '0.0.0.0', port)
await site.start() await site.start()
logger.info(f'Web server running on port {port}')
@bot.event @bot.event
async def on_ready(): async def on_ready():
asyncio.create_task(start_web_server()) asyncio.create_task(start_web_server())
logger.info(f'Logged in as {bot.user}') 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="Commands"))
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)
if __name__ == '__main__': if __name__ == '__main__':
token = os.getenv('DISCORD_TOKEN') token = os.getenv('DISCORD_TOKEN')
if not token: if not token:
logger.error('DISCORD_TOKEN not set!') logger.error('DISCORD_TOKEN not set')
exit(1) exit(1)
logger.info("everythings working")
logger.info('hello from chersbobers and booly co :3')
bot.run(token) bot.run(token)

23
config.toml Normal file
View file

@ -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