feat: support long text and safe attachment batches
Build web service image / build (push) Successful in 1m15s

This commit is contained in:
2026-09-30 09:16:36 +08:00
parent a977902b25
commit edba7d0d38
26 changed files with 720 additions and 82 deletions
@@ -4,10 +4,16 @@ public static class WechatSendConfirmation
{
public static bool IsMentionToken(string text) => text.TrimEnd() == "\uFFFC";
public static bool MatchesMention(ChatMessageSnapshot message, IReadOnlySet<string> baseline,
public static bool IsNewOccurrence(string fingerprint,
IReadOnlyDictionary<string, int> baselineCounts, IReadOnlyDictionary<string, int> currentCounts) =>
currentCounts.TryGetValue(fingerprint, out var currentCount)
&& currentCount > (baselineCounts.TryGetValue(fingerprint, out var baselineCount) ? baselineCount : 0);
public static bool MatchesMention(ChatMessageSnapshot message,
IReadOnlyDictionary<string, int> baselineCounts, IReadOnlyDictionary<string, int> currentCounts,
string memberName, string? body)
{
if (baseline.Contains(message.Fingerprint) || message.Type != ChatMessageType.Text) return false;
if (!IsNewOccurrence(message.Fingerprint, baselineCounts, currentCounts) || message.Type != ChatMessageType.Text) return false;
var expected = "@" + memberName + (string.IsNullOrEmpty(body) ? "" : " " + body);
return string.Equals(NormalizeWhitespace(message.Text), NormalizeWhitespace(expected), StringComparison.Ordinal);
}
@@ -16,10 +22,11 @@ public static class WechatSendConfirmation
string.Join(' ', text.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries));
// UIA proves only a fresh matching visible row, not delivery or sender identity.
public static bool Matches(ChatMessageSnapshot message, IReadOnlySet<string> baseline,
public static bool Matches(ChatMessageSnapshot message,
IReadOnlyDictionary<string, int> baselineCounts, IReadOnlyDictionary<string, int> currentCounts,
ChatMessageType type, string? expectedText)
{
if (baseline.Contains(message.Fingerprint) || message.Type != type) return false;
if (!IsNewOccurrence(message.Fingerprint, baselineCounts, currentCounts) || message.Type != type) return false;
if (expectedText is null) return true;
return type == ChatMessageType.File
? message.Text.Split('\n').Any(line => string.Equals(line.TrimEnd('\r'), expectedText, StringComparison.Ordinal))