From a499daa58c2b26b42ca3c488351c596da6562a0d Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Mon, 23 Mar 2026 17:49:43 +0800 Subject: [PATCH 1/2] Refactor crontab trigger check into HasEnabledTriggerRule method --- .../Services/CrontabService.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs index c8838b334..77a2740a4 100644 --- a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs +++ b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs @@ -116,6 +116,8 @@ public async Task ScheduledTimeArrived(CrontabItem item) { _logger.LogDebug($"ScheduledTimeArrived {item}"); + if (!await HasEnabledTriggerRule(item)) return; + await HookEmitter.Emit(_services, async hook => { if (hook.Triggers == null || hook.Triggers.Contains(item.Title)) @@ -127,4 +129,19 @@ await HookEmitter.Emit(_services, async hook => } }, item.AgentId); } + + private async Task HasEnabledTriggerRule(CrontabItem item) + { + var agentService = _services.GetRequiredService(); + if(string.IsNullOrEmpty(item.AgentId)) return true; + + var agent = await agentService.GetAgent(item.AgentId); + if (agent == null) + { + _logger.LogWarning("Agent {AgentId} is not found", item.AgentId); + return false; + } + + return agent.Rules.Any(r => r.TriggerName == item.Title && !r.Disabled); + } } From 5fe71276a7dfaf4df24f8b152546b63b20ce66f8 Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Tue, 24 Mar 2026 10:49:42 +0800 Subject: [PATCH 2/2] optimize HasEnabledTriggerRule --- .../BotSharp.Core.Crontab/Services/CrontabService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs index 77a2740a4..3a2b05dbb 100644 --- a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs +++ b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs @@ -130,10 +130,15 @@ await HookEmitter.Emit(_services, async hook => }, item.AgentId); } + /// + /// Returns whether the trigger is treated as enabled for this schedule: true unless a rule with the + /// same trigger name exists and is explicitly disabled (opt-out). Missing rules do not block. + /// private async Task HasEnabledTriggerRule(CrontabItem item) { var agentService = _services.GetRequiredService(); - if(string.IsNullOrEmpty(item.AgentId)) return true; + // No agent context: do not gate (legacy / callers without AgentId). + if (string.IsNullOrEmpty(item.AgentId)) return true; var agent = await agentService.GetAgent(item.AgentId); if (agent == null) @@ -142,6 +147,7 @@ private async Task HasEnabledTriggerRule(CrontabItem item) return false; } - return agent.Rules.Any(r => r.TriggerName == item.Title && !r.Disabled); + // Opt-out only: block when a matching trigger rule exists and Disabled is true. + return !agent.Rules.Any(r => r.TriggerName == item.Title && r.Disabled); } }