forked from sass/tipibot
Edit discord role rights
This commit is contained in:
5
bot.py
5
bot.py
@@ -22,6 +22,7 @@ import psutil
|
|||||||
import config
|
import config
|
||||||
import strings as S
|
import strings as S
|
||||||
from core import economy, pb_client, sheets
|
from core import economy, pb_client, sheets
|
||||||
|
from core.admin import is_bot_admin
|
||||||
from core.member_sync import SyncResult
|
from core.member_sync import SyncResult
|
||||||
from commands.dev_member_commands import register_dev_member_commands
|
from commands.dev_member_commands import register_dev_member_commands
|
||||||
from commands.dev_member_runtime import handle_member_join, run_birthday_daily
|
from commands.dev_member_runtime import handle_member_join, run_birthday_daily
|
||||||
@@ -593,8 +594,8 @@ class HelpSelect(discord.ui.Select):
|
|||||||
|
|
||||||
@tree.command(name="help", description=S.CMD["help"])
|
@tree.command(name="help", description=S.CMD["help"])
|
||||||
async def cmd_help(interaction: discord.Interaction):
|
async def cmd_help(interaction: discord.Interaction):
|
||||||
perms = interaction.user.guild_permissions if interaction.guild else None
|
member = interaction.user
|
||||||
is_admin = bool(perms and (perms.manage_roles or perms.manage_guild))
|
is_admin = isinstance(member, discord.Member) and is_bot_admin(member)
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True
|
embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import discord
|
|||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
|
|
||||||
from core import sheets
|
from core import sheets
|
||||||
|
from core.admin import bot_admin_check
|
||||||
import strings as S
|
import strings as S
|
||||||
from core.member_sync import announce_birthday, sync_member, today_local
|
from core.member_sync import announce_birthday, sync_member, today_local
|
||||||
|
|
||||||
@@ -167,7 +168,7 @@ def register_dev_member_commands(
|
|||||||
|
|
||||||
@tree.command(name="check", description=S.CMD["check"])
|
@tree.command(name="check", description=S.CMD["check"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_roles=True)
|
@bot_admin_check()
|
||||||
async def cmd_check(interaction: discord.Interaction):
|
async def cmd_check(interaction: discord.Interaction):
|
||||||
await interaction.response.defer(ephemeral=True)
|
await interaction.response.defer(ephemeral=True)
|
||||||
|
|
||||||
@@ -281,7 +282,7 @@ def register_dev_member_commands(
|
|||||||
|
|
||||||
@tree.command(name="member", description=S.CMD["member"])
|
@tree.command(name="member", description=S.CMD["member"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_roles=True)
|
@bot_admin_check()
|
||||||
async def cmd_member(interaction: discord.Interaction, user: discord.Member):
|
async def cmd_member(interaction: discord.Interaction, user: discord.Member):
|
||||||
row = sheets.find_member(user.id, user.name)
|
row = sheets.find_member(user.id, user.name)
|
||||||
if row is None:
|
if row is None:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import discord
|
|||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
|
|
||||||
from core import economy
|
from core import economy
|
||||||
|
from core.admin import bot_admin_check
|
||||||
import strings as S
|
import strings as S
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ def register_economy_admin_commands(
|
|||||||
) -> None:
|
) -> None:
|
||||||
@tree.command(name="adminseason", description=S.CMD["adminseason"])
|
@tree.command(name="adminseason", description=S.CMD["adminseason"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
@app_commands.describe(top_n=S.OPT["adminseason_top_n"])
|
@app_commands.describe(top_n=S.OPT["adminseason_top_n"])
|
||||||
async def cmd_adminseason(interaction: discord.Interaction, top_n: int = 10):
|
async def cmd_adminseason(interaction: discord.Interaction, top_n: int = 10):
|
||||||
await interaction.response.defer(ephemeral=True)
|
await interaction.response.defer(ephemeral=True)
|
||||||
@@ -73,7 +74,7 @@ def register_economy_admin_commands(
|
|||||||
kogus=S.OPT["admincoins_kogus"],
|
kogus=S.OPT["admincoins_kogus"],
|
||||||
põhjus=S.OPT["admin_põhjus"],
|
põhjus=S.OPT["admin_põhjus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_admincoins(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
async def cmd_admincoins(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
||||||
if kogus == 0:
|
if kogus == 0:
|
||||||
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
||||||
@@ -112,7 +113,7 @@ def register_economy_admin_commands(
|
|||||||
minutid=S.OPT["adminjail_minutid"],
|
minutid=S.OPT["adminjail_minutid"],
|
||||||
põhjus=S.OPT["admin_põhjus"],
|
põhjus=S.OPT["admin_põhjus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminjail(interaction: discord.Interaction, kasutaja: discord.Member, minutid: int, põhjus: str):
|
async def cmd_adminjail(interaction: discord.Interaction, kasutaja: discord.Member, minutid: int, põhjus: str):
|
||||||
if minutid <= 0:
|
if minutid <= 0:
|
||||||
await interaction.response.send_message(S.ERR["positive_duration"], ephemeral=True)
|
await interaction.response.send_message(S.ERR["positive_duration"], ephemeral=True)
|
||||||
@@ -133,7 +134,7 @@ def register_economy_admin_commands(
|
|||||||
@tree.command(name="adminunjail", description=S.CMD["adminunjail"])
|
@tree.command(name="adminunjail", description=S.CMD["adminunjail"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminunjail(interaction: discord.Interaction, kasutaja: discord.Member):
|
async def cmd_adminunjail(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||||
await economy.do_admin_unjail(kasutaja.id, interaction.user.id)
|
await economy.do_admin_unjail(kasutaja.id, interaction.user.id)
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
@@ -148,7 +149,7 @@ def register_economy_admin_commands(
|
|||||||
kasutaja=S.OPT["admin_kasutaja"],
|
kasutaja=S.OPT["admin_kasutaja"],
|
||||||
põhjus=S.OPT["admin_põhjus"],
|
põhjus=S.OPT["admin_põhjus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminban(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
async def cmd_adminban(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
||||||
if bot.user and kasutaja.id == bot.user.id:
|
if bot.user and kasutaja.id == bot.user.id:
|
||||||
await interaction.response.send_message(S.ERR["admin_ban_bot"], ephemeral=True)
|
await interaction.response.send_message(S.ERR["admin_ban_bot"], ephemeral=True)
|
||||||
@@ -164,7 +165,7 @@ def register_economy_admin_commands(
|
|||||||
@tree.command(name="adminunban", description=S.CMD["adminunban"])
|
@tree.command(name="adminunban", description=S.CMD["adminunban"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminunban(interaction: discord.Interaction, kasutaja: discord.Member):
|
async def cmd_adminunban(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||||
await economy.do_admin_unban(kasutaja.id, interaction.user.id)
|
await economy.do_admin_unban(kasutaja.id, interaction.user.id)
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
@@ -179,7 +180,7 @@ def register_economy_admin_commands(
|
|||||||
kasutaja=S.OPT["admin_kasutaja"],
|
kasutaja=S.OPT["admin_kasutaja"],
|
||||||
põhjus=S.OPT["admin_põhjus"],
|
põhjus=S.OPT["admin_põhjus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminreset(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
async def cmd_adminreset(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
||||||
if bot.user and kasutaja.id == bot.user.id:
|
if bot.user and kasutaja.id == bot.user.id:
|
||||||
await interaction.response.send_message(S.ERR["admin_reset_bot"], ephemeral=True)
|
await interaction.response.send_message(S.ERR["admin_reset_bot"], ephemeral=True)
|
||||||
@@ -195,7 +196,7 @@ def register_economy_admin_commands(
|
|||||||
@tree.command(name="adminview", description=S.CMD["adminview"])
|
@tree.command(name="adminview", description=S.CMD["adminview"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminview(interaction: discord.Interaction, kasutaja: discord.Member):
|
async def cmd_adminview(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||||
res = await economy.do_admin_inspect(kasutaja.id)
|
res = await economy.do_admin_inspect(kasutaja.id)
|
||||||
data = res["data"]
|
data = res["data"]
|
||||||
@@ -238,7 +239,7 @@ def register_economy_admin_commands(
|
|||||||
kogus=S.OPT["adminexp_kogus"],
|
kogus=S.OPT["adminexp_kogus"],
|
||||||
põhjus=S.OPT["admin_põhjus"],
|
põhjus=S.OPT["admin_põhjus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminexp(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
async def cmd_adminexp(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
||||||
if kogus == 0:
|
if kogus == 0:
|
||||||
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
||||||
@@ -281,7 +282,7 @@ def register_economy_admin_commands(
|
|||||||
ese=S.OPT["adminitem_ese"],
|
ese=S.OPT["adminitem_ese"],
|
||||||
tegevus=S.OPT["adminitem_tegevus"],
|
tegevus=S.OPT["adminitem_tegevus"],
|
||||||
)
|
)
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_adminitem(interaction: discord.Interaction, kasutaja: discord.Member, ese: str, tegevus: str):
|
async def cmd_adminitem(interaction: discord.Interaction, kasutaja: discord.Member, ese: str, tegevus: str):
|
||||||
action = tegevus.strip().lower()
|
action = tegevus.strip().lower()
|
||||||
if action not in ("anna", "eemalda"):
|
if action not in ("anna", "eemalda"):
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import discord
|
|||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
|
|
||||||
import strings as S
|
import strings as S
|
||||||
|
from core.admin import bot_admin_check
|
||||||
|
|
||||||
|
|
||||||
def register_ops_admin_commands(
|
def register_ops_admin_commands(
|
||||||
@@ -32,7 +33,7 @@ def register_ops_admin_commands(
|
|||||||
) -> None:
|
) -> None:
|
||||||
@tree.command(name="status", description=S.CMD["status"])
|
@tree.command(name="status", description=S.CMD["status"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_status(interaction: discord.Interaction):
|
async def cmd_status(interaction: discord.Interaction):
|
||||||
mem = process.memory_info()
|
mem = process.memory_info()
|
||||||
cpu = process.cpu_percent(interval=0.1)
|
cpu = process.cpu_percent(interval=0.1)
|
||||||
@@ -95,7 +96,7 @@ def register_ops_admin_commands(
|
|||||||
|
|
||||||
@tree.command(name="sync", description=S.CMD["sync"])
|
@tree.command(name="sync", description=S.CMD["sync"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_sync(interaction: discord.Interaction):
|
async def cmd_sync(interaction: discord.Interaction):
|
||||||
await interaction.response.defer(ephemeral=True)
|
await interaction.response.defer(ephemeral=True)
|
||||||
tree.copy_global_to(guild=guild_obj)
|
tree.copy_global_to(guild=guild_obj)
|
||||||
@@ -107,7 +108,7 @@ def register_ops_admin_commands(
|
|||||||
|
|
||||||
@tree.command(name="restart", description=S.CMD["restart"])
|
@tree.command(name="restart", description=S.CMD["restart"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_restart(interaction: discord.Interaction):
|
async def cmd_restart(interaction: discord.Interaction):
|
||||||
restart_file.write_text(json.dumps({"channel_id": interaction.channel_id}), encoding="utf-8")
|
restart_file.write_text(json.dumps({"channel_id": interaction.channel_id}), encoding="utf-8")
|
||||||
await interaction.response.send_message(S.MSG_RESTARTING, ephemeral=True)
|
await interaction.response.send_message(S.MSG_RESTARTING, ephemeral=True)
|
||||||
@@ -117,7 +118,7 @@ def register_ops_admin_commands(
|
|||||||
|
|
||||||
@tree.command(name="shutdown", description=S.CMD["shutdown"])
|
@tree.command(name="shutdown", description=S.CMD["shutdown"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_shutdown(interaction: discord.Interaction):
|
async def cmd_shutdown(interaction: discord.Interaction):
|
||||||
await interaction.response.send_message(S.MSG_SHUTTING_DOWN, ephemeral=True)
|
await interaction.response.send_message(S.MSG_SHUTTING_DOWN, ephemeral=True)
|
||||||
log.info("/shutdown triggered by %s", interaction.user)
|
log.info("/shutdown triggered by %s", interaction.user)
|
||||||
@@ -125,7 +126,7 @@ def register_ops_admin_commands(
|
|||||||
|
|
||||||
@tree.command(name="pause", description=S.CMD["pause"])
|
@tree.command(name="pause", description=S.CMD["pause"])
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@app_commands.default_permissions(manage_guild=True)
|
@bot_admin_check()
|
||||||
async def cmd_pause(interaction: discord.Interaction):
|
async def cmd_pause(interaction: discord.Interaction):
|
||||||
paused = not get_paused()
|
paused = not get_paused()
|
||||||
set_paused(paused)
|
set_paused(paused)
|
||||||
|
|||||||
23
config.py
23
config.py
@@ -58,3 +58,26 @@ PB_ECONOMY_COLLECTION_ECONOMY = (
|
|||||||
PB_ECONOMY_COLLECTION = (
|
PB_ECONOMY_COLLECTION = (
|
||||||
PB_ECONOMY_COLLECTION_ECONOMY if BOT_PROFILE == "economy" else PB_ECONOMY_COLLECTION_DEV
|
PB_ECONOMY_COLLECTION_ECONOMY if BOT_PROFILE == "economy" else PB_ECONOMY_COLLECTION_DEV
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_admin_roles() -> dict[int, int]:
|
||||||
|
"""Parse BOT_ADMIN_ROLES env var (format: guild_id:role_id,guild_id:role_id)."""
|
||||||
|
raw = os.getenv("BOT_ADMIN_ROLES", "").strip()
|
||||||
|
if not raw:
|
||||||
|
return {}
|
||||||
|
result: dict[int, int] = {}
|
||||||
|
for pair in raw.split(","):
|
||||||
|
pair = pair.strip()
|
||||||
|
if not pair:
|
||||||
|
continue
|
||||||
|
parts = pair.split(":")
|
||||||
|
if len(parts) != 2:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
result[int(parts[0].strip())] = int(parts[1].strip())
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
BOT_ADMIN_ROLES: dict[int, int] = _parse_admin_roles()
|
||||||
|
|||||||
27
core/admin.py
Normal file
27
core/admin.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord import app_commands
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
|
def is_bot_admin(member: discord.Member) -> bool:
|
||||||
|
"""Return True if the member has the configured bot-admin role for their guild."""
|
||||||
|
role_id = config.BOT_ADMIN_ROLES.get(member.guild.id)
|
||||||
|
if role_id is None:
|
||||||
|
return False
|
||||||
|
return any(r.id == role_id for r in member.roles)
|
||||||
|
|
||||||
|
|
||||||
|
def bot_admin_check():
|
||||||
|
"""Slash-command check decorator: raises MissingPermissions if not a bot admin."""
|
||||||
|
def predicate(interaction: discord.Interaction) -> bool:
|
||||||
|
member = interaction.user
|
||||||
|
if not isinstance(member, discord.Member):
|
||||||
|
raise app_commands.MissingPermissions(["bot_admin"])
|
||||||
|
if not is_bot_admin(member):
|
||||||
|
raise app_commands.MissingPermissions(["bot_admin"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
return app_commands.check(predicate)
|
||||||
Reference in New Issue
Block a user