feat: Discord slash commands /stop /auto /send with guild sync

This commit is contained in:
2026-03-07 15:20:10 +09:00
parent 02e9e4d424
commit 0bd525a54c

59
bot.py
View File

@@ -115,8 +115,59 @@ class GravityBot(commands.Bot):
self.loop.create_task(self._process_events()) self.loop.create_task(self._process_events())
self.pending_approval_scanner.start() self.pending_approval_scanner.start()
self.chat_snapshot_scanner.start() self.chat_snapshot_scanner.start()
self._register_slash_commands()
logger.info("Bot setup complete") logger.info("Bot setup complete")
def _register_slash_commands(self):
"""Register Discord slash commands."""
@self.tree.command(name="stop", description="AI 작업 중지")
async def slash_stop(interaction: discord.Interaction):
project = self.channel_to_project.get(interaction.channel_id)
if not project:
await interaction.response.send_message("⚠️ 프로젝트 채널이 아닙니다.", ephemeral=True)
return
self.bridge.write_command(project, "!stop", project_name=project)
await interaction.response.send_message(
embed=discord.Embed(
title="⏹️ AI 작업 중지",
description=f"**{project}** IDE에 중지 요청 전달됨",
color=discord.Color.orange(),
)
)
@self.tree.command(name="auto", description="자동 승인 토글")
async def slash_auto(interaction: discord.Interaction, mode: str):
project = self.channel_to_project.get(interaction.channel_id)
if not project:
await interaction.response.send_message("⚠️ 프로젝트 채널이 아닙니다.", ephemeral=True)
return
enabled = mode.lower() in ("on", "true", "1")
self.bridge.write_command(project, f"!auto {'on' if enabled else 'off'}", project_name=project)
emoji = "🟢" if enabled else "🔴"
await interaction.response.send_message(
embed=discord.Embed(
title=f"{emoji} {'자동 승인' if enabled else '수동 승인'} 모드",
description=f"프로젝트: **{project}**",
color=discord.Color.green() if enabled else discord.Color.red(),
)
)
@self.tree.command(name="send", description="IDE 채팅에 메시지 전송")
async def slash_send(interaction: discord.Interaction, message: str):
project = self.channel_to_project.get(interaction.channel_id)
if not project:
await interaction.response.send_message("⚠️ 프로젝트 채널이 아닙니다.", ephemeral=True)
return
self.bridge.write_command(project, message, project_name=project)
await interaction.response.send_message(
embed=discord.Embed(
description=f"📨 → **{project}** IDE에 전달됨\n`{message[:100]}`",
color=discord.Color.blurple(),
),
delete_after=10,
)
async def on_ready(self): async def on_ready(self):
logger.info(f"Bot connected as {self.user} (ID: {self.user.id})") logger.info(f"Bot connected as {self.user} (ID: {self.user.id})")
@@ -144,6 +195,14 @@ class GravityBot(commands.Bot):
# Load conversation → project registrations from Extension # Load conversation → project registrations from Extension
self._load_registrations() self._load_registrations()
# Sync slash commands to guild
try:
self.tree.copy_global_to(guild=self.guild)
synced = await self.tree.sync(guild=self.guild)
logger.info(f"Synced {len(synced)} slash commands to guild")
except Exception as e:
logger.warning(f"Slash command sync failed: {e}")
# Open the gate # Open the gate
self._ready_event.set() self._ready_event.set()
logger.info("Ready gate opened — event processing enabled") logger.info("Ready gate opened — event processing enabled")