-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbot_api.py
More file actions
122 lines (105 loc) · 4.23 KB
/
bot_api.py
File metadata and controls
122 lines (105 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import logging
import disnake
from aiohttp import web
logger = logging.getLogger(__name__)
_INTERNAL_KEY = os.getenv("ADMIN_API_KEY", "").strip()
def _auth(request):
if not _INTERNAL_KEY or request.headers.get("X-Admin-Key", "") != _INTERNAL_KEY:
raise web.HTTPUnauthorized(text="Unauthorized")
def create_bot_api(bot):
async def list_cogs(request):
_auth(request)
cog_dir = os.path.join(os.path.dirname(__file__), "cogs")
available = [
f"cogs.{f[:-3]}"
for f in os.listdir(cog_dir)
if f.endswith(".py") and not f.startswith("__")
]
loaded = set(bot.extensions.keys())
return web.json_response({
"cogs": [
{"name": name, "loaded": name in loaded}
for name in sorted(available)
]
})
async def reload_cog(request):
_auth(request)
data = await request.json()
name = data.get("name", "").strip()
if not name:
return web.json_response({"error": "name is required"}, status=400)
try:
bot.reload_extension(name)
logger.info(f"[BotAPI] Reloaded: {name}")
return web.json_response({"message": f"Reloaded {name}."})
except Exception as e:
logger.error(f"[BotAPI] Reload failed for {name}: {e}")
return web.json_response({"error": str(e)}, status=400)
async def load_cog(request):
_auth(request)
data = await request.json()
name = data.get("name", "").strip()
if not name:
return web.json_response({"error": "name is required"}, status=400)
try:
bot.load_extension(name)
logger.info(f"[BotAPI] Loaded: {name}")
return web.json_response({"message": f"Loaded {name}."})
except Exception as e:
logger.error(f"[BotAPI] Load failed for {name}: {e}")
return web.json_response({"error": str(e)}, status=400)
async def unload_cog(request):
_auth(request)
data = await request.json()
name = data.get("name", "").strip()
if not name:
return web.json_response({"error": "name is required"}, status=400)
try:
bot.unload_extension(name)
logger.info(f"[BotAPI] Unloaded: {name}")
return web.json_response({"message": f"Unloaded {name}."})
except Exception as e:
logger.error(f"[BotAPI] Unload failed for {name}: {e}")
return web.json_response({"error": str(e)}, status=400)
async def get_bot_config(request):
_auth(request)
from utils.database import get_setting
import config
version = await get_setting("version", config.version)
status = await get_setting("status", f"/help | {config.version}")
return web.json_response({"version": version, "status": status})
async def set_bot_config(request):
_auth(request)
from utils.database import set_setting
data = await request.json()
version = data.get("version", "").strip()
status = data.get("status", "").strip()
if version:
await set_setting("version", version)
logger.info(f"[BotAPI] Version updated to {version}")
if status:
await set_setting("status", status)
await bot.change_presence(activity=disnake.Game(name=status))
logger.info(f"[BotAPI] Status updated to: {status}")
return web.json_response({"message": "Bot config updated."})
app = web.Application()
app.router.add_get("/internal/cogs", list_cogs)
app.router.add_post("/internal/cogs/reload", reload_cog)
app.router.add_post("/internal/cogs/load", load_cog)
app.router.add_post("/internal/cogs/unload", unload_cog)
app.router.add_get("/internal/config", get_bot_config)
app.router.add_post("/internal/config", set_bot_config)
return app
_started = False
async def start_bot_api(bot):
global _started
if _started:
return
_started = True
app = create_bot_api(bot)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, "0.0.0.0", 8887)
await site.start()
logger.info("Bot internal API running on :8887")