diff --git a/src/TelegramPanel.Core/Services/Telegram/AccountTelegramToolsService.cs b/src/TelegramPanel.Core/Services/Telegram/AccountTelegramToolsService.cs index f5a76e6..eb5d95e 100644 --- a/src/TelegramPanel.Core/Services/Telegram/AccountTelegramToolsService.cs +++ b/src/TelegramPanel.Core/Services/Telegram/AccountTelegramToolsService.cs @@ -1151,6 +1151,7 @@ public class AccountTelegramToolsService Func? messageFilter = null, IReadOnlyCollection? allowedSenderUsernames = null, bool restrictToAllowedUsernames = false, + bool stopOnUnmatchedMention = false, CancellationToken cancellationToken = default) { if (timeoutSeconds < 3) @@ -1164,7 +1165,15 @@ public class AccountTelegramToolsService var waitStartedAt = DateTimeOffset.UtcNow.AddSeconds(-2); var update = await _updateHub.WaitForAsync( accountId, - x => IsCandidateVerificationMessage(x, target, currentUsername, sentMessageId, messageFilter, allowedSenderUsernames, restrictToAllowedUsernames), + x => IsCandidateVerificationMessage( + x, + target, + currentUsername, + sentMessageId, + messageFilter, + allowedSenderUsernames, + restrictToAllowedUsernames, + stopOnUnmatchedMention), waitStartedAt, TimeSpan.FromSeconds(timeoutSeconds), cancellationToken); @@ -1172,6 +1181,14 @@ public class AccountTelegramToolsService if (update == null) return (false, $"等待验证消息超时({timeoutSeconds} 秒)", null); + if (messageFilter != null + && stopOnUnmatchedMention + && !messageFilter(update) + && IsMentionOrReply(update, currentUsername, sentMessageId)) + { + return (false, "验证消息未命中关键词/正则,已跳过", null); + } + var candidate = await BuildVerificationCandidateAsync( client, update.Message, @@ -1280,7 +1297,8 @@ public class AccountTelegramToolsService int sentMessageId, Func? messageFilter, IReadOnlyCollection? allowedSenderUsernames, - bool restrictToAllowedUsernames) + bool restrictToAllowedUsernames, + bool stopOnUnmatchedMention) { if (!IsSamePeer(target.Peer, update.Message.peer_id)) return false; @@ -1297,16 +1315,32 @@ public class AccountTelegramToolsService } if (messageFilter != null) - return messageFilter(update); + { + if (messageFilter(update)) + return true; - var mentionsAccount = ContainsUsernameMention(update.Message.message, currentUsername); - var replyToSent = update.ReplyToMessageId == sentMessageId; - if (!mentionsAccount && !replyToSent) + if (stopOnUnmatchedMention && IsMentionOrReply(update, currentUsername, sentMessageId)) + return true; + + return false; + } + + if (!IsMentionOrReply(update, currentUsername, sentMessageId)) return false; return LooksLikeVerificationChallenge(update); } + private static bool IsMentionOrReply( + TelegramAccountMessageUpdate update, + string? currentUsername, + int sentMessageId) + { + var mentionsAccount = ContainsUsernameMention(update.Message.message, currentUsername); + var replyToSent = update.ReplyToMessageId == sentMessageId; + return mentionsAccount || replyToSent; + } + private static bool IsSenderInAllowedUsernames( TelegramAccountMessageUpdate update, IReadOnlyCollection? allowedUsernames) diff --git a/src/TelegramPanel.Web/Services/UserChatActiveAiVerificationService.cs b/src/TelegramPanel.Web/Services/UserChatActiveAiVerificationService.cs index 52de25e..90d2d12 100644 --- a/src/TelegramPanel.Web/Services/UserChatActiveAiVerificationService.cs +++ b/src/TelegramPanel.Web/Services/UserChatActiveAiVerificationService.cs @@ -72,10 +72,16 @@ public sealed class UserChatActiveAiVerificationService messageFilter, restrictToAllowedUsernames ? allowedUsernames : null, restrictToAllowedUsernames, + messageFilter != null, cancellationToken); if (!wait.Success || wait.Candidate == null) + { + if (IsVerificationSkipped(wait.Error)) + return (true, null, "未命中关键词/正则,跳过验证"); + return (false, wait.Error, null); + } var candidate = wait.Candidate; var image = candidate.ImageJpegBytes is { Length: > 0 } @@ -287,4 +293,14 @@ public sealed class UserChatActiveAiVerificationService .Replace("\r", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal); } + + private static bool IsVerificationSkipped(string? error) + { + if (string.IsNullOrWhiteSpace(error)) + return false; + + return error.Contains("未命中关键词", StringComparison.OrdinalIgnoreCase) + || error.Contains("未命中正则", StringComparison.OrdinalIgnoreCase) + || error.Contains("跳过验证", StringComparison.OrdinalIgnoreCase); + } }