refactor(douyu): 日报改为插件定时任务配置驱动

- 新增 get_schedule_actions,注册斗鱼弹幕日报推送动作(douyu_daily_report_push)

- 新增 run_scheduled_action,支持按群执行、手动覆盖日期与强制重生成参数

- 移除 every_minutes(5) 的旧日报 tick 注册,避免与插件调度重复触发
This commit is contained in:
liuwei
2026-04-22 09:43:47 +08:00
parent 693e6dae03
commit 67aead93ca
2 changed files with 146 additions and 1 deletions

View File

@@ -532,8 +532,8 @@ class DouyuPlugin(MessagePluginInterface):
self._status_check_retry_delay_seconds = 1
self._daily_report_llm_client: Optional[UnifiedLLMClient] = None
self._danmu_recorders: Dict[str, DouyuDanmuRecorder] = {}
# 直播状态/鱼吧轮询继续保留在轻量 async_job 中,保障现网行为稳定。
async_job.every_minutes(self._check_interval)(self._scheduled_unified_check_job)
async_job.every_minutes(5)(self._scheduled_daily_report_tick)
@staticmethod
def _format_exception(exc: Exception) -> str:
@@ -589,6 +589,85 @@ class DouyuPlugin(MessagePluginInterface):
except Exception as e:
logger.error(f"斗鱼每日报告任务失败(anchor_day={anchor_day}): {e}")
def get_schedule_actions(self) -> List[Dict[str, Any]]:
"""声明插件可调度动作。
设计说明:
1. 斗鱼“每日报告”迁移到插件任务配置体系,支持在后台可视化启停/改时;
2. 触发时间直接复用配置项 daily_report_time避免出现“两套时间配置”
3. 作用域默认 all_enabled_groups让插件调度系统按群权限先过滤目标群。
"""
trigger_time = str(self._daily_report_time or "09:30").strip() or "09:30"
return [
{
"action_key": "douyu_daily_report_push",
"name": "斗鱼弹幕日报推送",
"description": "按配置时间推送前一天斗鱼弹幕日报",
"trigger_type": "at_times",
"trigger_config": {"time_list": [trigger_time]},
"target_scope": "all_enabled_groups",
"target_config": {},
"payload": {},
"default_enabled": bool(self._daily_report_enable),
}
]
async def run_scheduled_action(self, action_key: str, context: Dict[str, Any]) -> Dict[str, Any]:
"""执行插件调度动作。"""
if action_key != "douyu_daily_report_push":
return {"success": False, "summary": f"不支持动作: {action_key}", "detail": {}}
# 调度器注入 bot保证定时任务也能发消息。
self.bot = context.get("bot") or self.bot
if not self._daily_report_enable:
return {"success": True, "summary": "斗鱼每日报告已关闭,跳过执行", "detail": {"enabled": False}}
if not self.redis_manager or not self.bot:
return {"success": False, "summary": "斗鱼每日报告执行失败:依赖未就绪(redis/bot)", "detail": {}}
payload = context.get("payload") or {}
# 支持后台手动触发时覆盖 anchor_day便于补发历史某天日报。
anchor_day = str(payload.get("anchor_day") or "").strip()
if not anchor_day:
anchor_day = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
force = bool(payload.get("force", False))
force_regenerate = bool(payload.get("force_regenerate", False))
target_groups = [str(g).strip() for g in (context.get("target_groups") or []) if str(g).strip()]
if not target_groups:
target_groups = GroupBotManager.get_group_list()
delivered_groups: List[str] = []
failed_groups: Dict[str, str] = {}
for gid in target_groups:
try:
# 按群推送:内部会再基于斗鱼订阅与插件权限做二次过滤。
delivered = await self._send_daily_reports(
anchor_day=anchor_day,
target_group_id=gid,
force=force,
force_regenerate=force_regenerate,
)
if delivered:
delivered_groups.append(gid)
except Exception as e:
failed_groups[gid] = self._format_exception(e)
return {
"success": len(failed_groups) == 0,
"summary": (
f"斗鱼日报任务完成: 日期{anchor_day}, 目标群{len(target_groups)}个, "
f"成功发送群{len(delivered_groups)}个, 失败群{len(failed_groups)}"
),
"detail": {
"anchor_day": anchor_day,
"force": force,
"force_regenerate": force_regenerate,
"target_groups": target_groups,
"delivered_groups": delivered_groups,
"failed_groups": failed_groups,
},
}
def initialize(self, context: Dict[str, Any]) -> bool:
try:
dbm = DBConnectionManager.get_instance()