Skip to content

Commit 415136e

Browse files
committed
Fix slash command registration
- Move verify command from class method to standalone function - Register command using bot.tree.command() like Veil-Bot - Commands now properly registered to guild at startup - Use guild-specific command registration (not global) - This matches the working implementation from Veil-Bot Fixes: Slash command not appearing in Discord Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a7d74b1 commit 415136e

1 file changed

Lines changed: 99 additions & 91 deletions

File tree

bot.py

Lines changed: 99 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -400,16 +400,106 @@ async def post_to_log_channel(self, embed: discord.Embed = None, file: discord.F
400400
except Exception as e:
401401
log.warning(f"[LOG] Could not send to log channel: {e}")
402402

403-
@app_commands.command(
403+
@tasks.loop(hours=1)
404+
async def update_stfc_ranks(self):
405+
"""Periodically check for rank changes and request admin confirmation."""
406+
guild = self.get_guild(GUILD_ID)
407+
if not guild:
408+
log.warning("[UPDATE] Guild not found")
409+
return
410+
411+
# Only run every UPDATE_CHECK_HOURS hours
412+
await self._update_stfc_ranks_impl(guild)
413+
414+
async def _update_stfc_ranks_impl(self, guild: discord.Guild):
415+
"""Implementation of rank update checking."""
416+
log.info("[UPDATE] Starting periodic rank check")
417+
418+
players = store.get_all_players()
419+
log.info(f"[UPDATE] Found {len(players)} players to check")
420+
421+
for user_id, player_id in players:
422+
member = guild.get_member(user_id)
423+
if not member:
424+
log.debug(f"[UPDATE] Member {user_id} no longer in guild")
425+
continue
426+
427+
try:
428+
player_data = STFCProScraper.fetch_player_data(player_id)
429+
if not player_data:
430+
log.warning(f"[UPDATE] Could not fetch data for player {player_id}")
431+
continue
432+
433+
old_data = store.get_player_data(user_id)
434+
if not old_data:
435+
continue
436+
437+
old_rank = old_data[4] # rank is 5th column
438+
new_rank = player_data.rank
439+
440+
# Check if rank changed
441+
if old_rank != new_rank:
442+
log.info(f"[UPDATE] Rank change detected for {member.name}: {old_rank}{new_rank}")
443+
444+
# Update nickname in case it changed
445+
new_nick = self._build_nickname(player_data.alliance_tag, player_data.username)
446+
if member.nick != new_nick:
447+
try:
448+
await member.edit(nick=new_nick)
449+
except discord.Forbidden:
450+
log.warning(f"[UPDATE] Could not update nickname for {member.name}")
451+
452+
# Request confirmation for ANY rank change
453+
confirmation_view = await self._assign_ranks(member, player_data, request_confirmation=True)
454+
455+
# Update database
456+
store.store_stfc_player(user_id, player_data, old_data[5]) # screenshot_url is 6th column
457+
458+
# Post confirmation request if needed
459+
if confirmation_view:
460+
admin_ping = f"<@&{ADMIN_ROLE_ID}>" if ADMIN_ROLE_ID else "Admins"
461+
alliance_display = f"[{player_data.alliance_tag}]" if player_data.alliance_tag else "N/A"
462+
confirm_embed = discord.Embed(
463+
title="🔔 Rank Change Detected - Confirmation Required",
464+
description=f"{admin_ping}, please confirm this rank change.",
465+
color=discord.Color.orange(),
466+
)
467+
confirm_embed.add_field(name="Player", value=f"{member.mention} ({player_data.username})", inline=False)
468+
confirm_embed.add_field(name="Previous Rank", value=old_rank or "N/A", inline=True)
469+
confirm_embed.add_field(name="New Rank", value=new_rank or "N/A", inline=True)
470+
confirm_embed.add_field(name="Alliance", value=alliance_display, inline=True)
471+
await self.post_to_log_channel(embed=confirm_embed, view=confirmation_view)
472+
473+
except Exception as e:
474+
log.error(f"[UPDATE] Error checking player {player_id}: {e}")
475+
continue
476+
477+
@update_stfc_ranks.before_loop
478+
async def before_update_stfc_ranks(self):
479+
"""Wait for bot to be ready before starting update loop."""
480+
await self.wait_until_ready()
481+
# Adjust loop to run at specified intervals
482+
current_hours = UPDATE_CHECK_HOURS
483+
if current_hours > 0:
484+
self.update_stfc_ranks.change_interval(hours=current_hours)
485+
486+
487+
# ---------------------------------------------------------------------------
488+
# Commands (Registered after bot instantiation)
489+
# ---------------------------------------------------------------------------
490+
def setup_commands(bot: STFCRankBot):
491+
"""Register slash commands with the bot."""
492+
493+
@bot.tree.command(
404494
name="verify",
405-
description="Verify your STFC player account with alliance rank"
495+
description="Verify your STFC player account with alliance rank",
496+
guild=discord.Object(GUILD_ID),
406497
)
407498
@app_commands.describe(
408-
player_url="Your stfc.pro/stfc.wtf player URL or player ID",
499+
player_url="Your stfc.pro/stfc.wtf/stfc.live player URL or player ID",
409500
screenshot="Screenshot of your player profile (for verification logging)"
410501
)
411502
async def verify_command(
412-
self,
413503
interaction: discord.Interaction,
414504
player_url: str,
415505
screenshot: discord.Attachment,
@@ -446,7 +536,7 @@ async def verify_command(
446536
return
447537

448538
# Update nickname
449-
new_nick = self._build_nickname(player_data.alliance_tag, player_data.username)
539+
new_nick = bot._build_nickname(player_data.alliance_tag, player_data.username)
450540
try:
451541
await member.edit(nick=new_nick, reason="STFC Verification")
452542
log.info(f"[VERIFY] Updated nickname for {member.name}: {new_nick}")
@@ -465,7 +555,7 @@ async def verify_command(
465555
store.store_stfc_player(member.id, player_data, screenshot_url)
466556

467557
# Assign ranks (base role immediate, higher ranks need confirmation)
468-
confirmation_view = await self._assign_ranks(member, player_data, request_confirmation=False)
558+
confirmation_view = await bot._assign_ranks(member, player_data, request_confirmation=False)
469559

470560
# Success response
471561
embed = discord.Embed(
@@ -491,7 +581,7 @@ async def verify_command(
491581
log_embed.add_field(name="Rank", value=player_data.rank or "N/A", inline=True)
492582
log_embed.add_field(name="Server", value=str(player_data.server), inline=True)
493583
log_embed.set_image(url=screenshot_url)
494-
await self.post_to_log_channel(embed=log_embed)
584+
await bot.post_to_log_channel(embed=log_embed)
495585

496586
# If rank requires confirmation, post confirmation request
497587
if confirmation_view:
@@ -504,90 +594,7 @@ async def verify_command(
504594
confirm_embed.add_field(name="Player", value=f"{member.mention} ({player_data.username})", inline=False)
505595
confirm_embed.add_field(name="Rank", value=player_data.rank, inline=True)
506596
confirm_embed.add_field(name="Alliance", value=alliance_display, inline=True)
507-
await self.post_to_log_channel(embed=confirm_embed, view=confirmation_view)
508-
509-
@tasks.loop(hours=1)
510-
async def update_stfc_ranks(self):
511-
"""Periodically check for rank changes and request admin confirmation."""
512-
guild = self.get_guild(GUILD_ID)
513-
if not guild:
514-
log.warning("[UPDATE] Guild not found")
515-
return
516-
517-
# Only run every UPDATE_CHECK_HOURS hours
518-
await self._update_stfc_ranks_impl(guild)
519-
520-
async def _update_stfc_ranks_impl(self, guild: discord.Guild):
521-
"""Implementation of rank update checking."""
522-
log.info("[UPDATE] Starting periodic rank check")
523-
524-
players = store.get_all_players()
525-
log.info(f"[UPDATE] Found {len(players)} players to check")
526-
527-
for user_id, player_id in players:
528-
member = guild.get_member(user_id)
529-
if not member:
530-
log.debug(f"[UPDATE] Member {user_id} no longer in guild")
531-
continue
532-
533-
try:
534-
player_data = STFCProScraper.fetch_player_data(player_id)
535-
if not player_data:
536-
log.warning(f"[UPDATE] Could not fetch data for player {player_id}")
537-
continue
538-
539-
old_data = store.get_player_data(user_id)
540-
if not old_data:
541-
continue
542-
543-
old_rank = old_data[4] # rank is 5th column
544-
new_rank = player_data.rank
545-
546-
# Check if rank changed
547-
if old_rank != new_rank:
548-
log.info(f"[UPDATE] Rank change detected for {member.name}: {old_rank}{new_rank}")
549-
550-
# Update nickname in case it changed
551-
new_nick = self._build_nickname(player_data.alliance_tag, player_data.username)
552-
if member.nick != new_nick:
553-
try:
554-
await member.edit(nick=new_nick)
555-
except discord.Forbidden:
556-
log.warning(f"[UPDATE] Could not update nickname for {member.name}")
557-
558-
# Request confirmation for ANY rank change
559-
confirmation_view = await self._assign_ranks(member, player_data, request_confirmation=True)
560-
561-
# Update database
562-
store.store_stfc_player(user_id, player_data, old_data[5]) # screenshot_url is 6th column
563-
564-
# Post confirmation request if needed
565-
if confirmation_view:
566-
admin_ping = f"<@&{ADMIN_ROLE_ID}>" if ADMIN_ROLE_ID else "Admins"
567-
alliance_display = f"[{player_data.alliance_tag}]" if player_data.alliance_tag else "N/A"
568-
confirm_embed = discord.Embed(
569-
title="🔔 Rank Change Detected - Confirmation Required",
570-
description=f"{admin_ping}, please confirm this rank change.",
571-
color=discord.Color.orange(),
572-
)
573-
confirm_embed.add_field(name="Player", value=f"{member.mention} ({player_data.username})", inline=False)
574-
confirm_embed.add_field(name="Previous Rank", value=old_rank or "N/A", inline=True)
575-
confirm_embed.add_field(name="New Rank", value=new_rank or "N/A", inline=True)
576-
confirm_embed.add_field(name="Alliance", value=alliance_display, inline=True)
577-
await self.post_to_log_channel(embed=confirm_embed, view=confirmation_view)
578-
579-
except Exception as e:
580-
log.error(f"[UPDATE] Error checking player {player_id}: {e}")
581-
continue
582-
583-
@update_stfc_ranks.before_loop
584-
async def before_update_stfc_ranks(self):
585-
"""Wait for bot to be ready before starting update loop."""
586-
await self.wait_until_ready()
587-
# Adjust loop to run at specified intervals
588-
current_hours = UPDATE_CHECK_HOURS
589-
if current_hours > 0:
590-
self.update_stfc_ranks.change_interval(hours=current_hours)
597+
await bot.post_to_log_channel(embed=confirm_embed, view=confirmation_view)
591598

592599

593600
# ---------------------------------------------------------------------------
@@ -598,4 +605,5 @@ async def before_update_stfc_ranks(self):
598605
os.makedirs("screenshots", exist_ok=True)
599606

600607
bot = STFCRankBot()
608+
setup_commands(bot)
601609
bot.run(DISCORD_TOKEN)

0 commit comments

Comments
 (0)