feat: Add manual trigger bypass for web UI autonomous engagement

- Added manual_trigger parameter to /autonomous/engage endpoint to bypass 12h cooldown
- Updated miku_engage_random_user_for_server() and miku_engage_random_user() to accept manual_trigger flag
- Modified Web UI to always send manual_trigger=true when engaging users from the UI
- Users can now manually engage the same user multiple times from web UI without cooldown restriction
- Regular autonomous schedules still respect the 12h cooldown between engagements to the same user

Changes:
- bot/api.py: Added manual_trigger parameter with string-to-boolean conversion
- bot/static/index.html: Added manual_trigger=true to engage user request
- bot/utils/autonomous_v1_legacy.py: Added manual_trigger parameter and cooldown bypass logic
This commit is contained in:
2026-02-20 00:53:42 +02:00
parent 9972edb06d
commit 2f0d430c35
3 changed files with 277 additions and 30 deletions

View File

@@ -869,16 +869,25 @@ async def trigger_autonomous_general(guild_id: int = None):
return {"status": "error", "message": "Bot not ready"}
@app.post("/autonomous/engage")
async def trigger_autonomous_engage_user(guild_id: int = None, user_id: str = None, engagement_type: str = None):
async def trigger_autonomous_engage_user(
guild_id: int = None,
user_id: str = None,
engagement_type: str = None,
manual_trigger: str = "false"
):
# If guild_id is provided, send autonomous engagement only to that server
# If no guild_id, send to all servers (legacy behavior)
# user_id: Optional specific user to engage (Discord user ID as string)
# engagement_type: Optional type - 'activity', 'general', 'status', or None for random
# manual_trigger: If True (as string), bypass the "recently engaged" check (for web UI manual triggers)
# Convert manual_trigger string to boolean
manual_trigger_bool = manual_trigger.lower() in ('true', '1', 'yes')
if globals.client and globals.client.loop and globals.client.loop.is_running():
if guild_id is not None:
# Send to specific server only
from utils.autonomous import miku_engage_random_user_for_server
globals.client.loop.create_task(miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type))
globals.client.loop.create_task(miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool))
# Build detailed message
msg_parts = [f"Autonomous user engagement queued for server {guild_id}"]
@@ -886,38 +895,49 @@ async def trigger_autonomous_engage_user(guild_id: int = None, user_id: str = No
msg_parts.append(f"targeting user {user_id}")
if engagement_type:
msg_parts.append(f"with {engagement_type} engagement")
if manual_trigger_bool:
msg_parts.append("(manual trigger - bypassing cooldown)")
return {"status": "ok", "message": " ".join(msg_parts)}
else:
# Send to all servers (legacy behavior)
from utils.autonomous import miku_engage_random_user
globals.client.loop.create_task(miku_engage_random_user(user_id=user_id, engagement_type=engagement_type))
globals.client.loop.create_task(miku_engage_random_user(user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool))
msg_parts = ["Autonomous user engagement queued for all servers"]
if user_id:
msg_parts.append(f"targeting user {user_id}")
if engagement_type:
msg_parts.append(f"with {engagement_type} engagement")
if manual_trigger_bool:
msg_parts.append("(manual trigger - bypassing cooldown)")
return {"status": "ok", "message": " ".join(msg_parts)}
else:
return {"status": "error", "message": "Bot not ready"}
@app.post("/autonomous/tweet")
async def trigger_autonomous_tweet(guild_id: int = None):
async def trigger_autonomous_tweet(guild_id: int = None, tweet_url: str = None):
# If guild_id is provided, send tweet only to that server
# If no guild_id, send to all servers (legacy behavior)
# If tweet_url is provided, share that specific tweet; otherwise fetch one
if globals.client and globals.client.loop and globals.client.loop.is_running():
if guild_id is not None:
# Send to specific server only
from utils.autonomous import share_miku_tweet_for_server
globals.client.loop.create_task(share_miku_tweet_for_server(guild_id))
return {"status": "ok", "message": f"Autonomous tweet sharing queued for server {guild_id}"}
globals.client.loop.create_task(share_miku_tweet_for_server(guild_id, tweet_url=tweet_url))
msg = f"Autonomous tweet sharing queued for server {guild_id}"
if tweet_url:
msg += f" with URL {tweet_url}"
return {"status": "ok", "message": msg}
else:
# Send to all servers (legacy behavior)
from utils.autonomous import share_miku_tweet
globals.client.loop.create_task(share_miku_tweet())
return {"status": "ok", "message": "Autonomous tweet sharing queued for all servers"}
globals.client.loop.create_task(share_miku_tweet(tweet_url=tweet_url))
msg = "Autonomous tweet sharing queued for all servers"
if tweet_url:
msg += f" with URL {tweet_url}"
return {"status": "ok", "message": msg}
else:
return {"status": "error", "message": "Bot not ready"}
@@ -1538,11 +1558,26 @@ async def trigger_autonomous_general_for_server(guild_id: int):
return {"status": "error", "message": f"Failed to trigger autonomous message: {e}"}
@app.post("/servers/{guild_id}/autonomous/engage")
async def trigger_autonomous_engage_for_server(guild_id: int, user_id: str = None, engagement_type: str = None):
"""Trigger autonomous user engagement for a specific server"""
async def trigger_autonomous_engage_for_server(
guild_id: int,
user_id: str = None,
engagement_type: str = None,
manual_trigger: str = "false"
):
"""Trigger autonomous user engagement for a specific server
Args:
guild_id: The server ID to engage in
user_id: Optional specific user to engage (Discord user ID as string)
engagement_type: Optional type - 'activity', 'general', 'status', or None for random
manual_trigger: If True (as string), bypass the "recently engaged" check (for web UI manual triggers)
"""
# Convert manual_trigger string to boolean
manual_trigger_bool = manual_trigger.lower() in ('true', '1', 'yes')
from utils.autonomous import miku_engage_random_user_for_server
try:
await miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type)
await miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool)
# Build detailed message
msg_parts = [f"Autonomous user engagement triggered for server {guild_id}"]
@@ -1550,6 +1585,8 @@ async def trigger_autonomous_engage_for_server(guild_id: int, user_id: str = Non
msg_parts.append(f"targeting user {user_id}")
if engagement_type:
msg_parts.append(f"with {engagement_type} engagement")
if manual_trigger_bool:
msg_parts.append("(manual trigger - bypassing cooldown)")
return {"status": "ok", "message": " ".join(msg_parts)}
except Exception as e: