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
@@ -277,6 +277,14 @@ public static partial class WechatChatClient
if (memberName.Any(char.IsControl) || memberName.Length > 100 ||
message is not null && (message.Any(char.IsControl) || message.Length > 4000))
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "Mention names and text must be single-line, with no control characters.");
var groupMemberNames = new[] { memberName };
if (!string.Equals(memberName, "所有人", StringComparison.Ordinal))
{
var members = await GetGroupMembersPageAsync(session, limit: 10000, offset: 0, cancellationToken: cancellationToken).ConfigureAwait(false);
if (members.HasMore)
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "The group member list exceeds the safe mention-selection bound; no send was attempted.");
groupMemberNames = members.Members.Select(member => member.DisplayName).ToArray();
}
await OpenNamedSessionAsync(main, session, cancellationToken).ConfigureAwait(false);
var input = FindByAutomationId(main, WechatLocators.ChatInput)
?? throw new WxAgentException(WxAgentErrorCode.UiStructureChanged, "Chat input was not found.");
@@ -284,7 +292,7 @@ public static partial class WechatChatClient
throw new WxAgentException(WxAgentErrorCode.ResultUnconfirmed, "The conversation changed before mention input.");
if (!string.IsNullOrEmpty(input.AsTextBox().Text))
throw new WxAgentException(WxAgentErrorCode.InvalidOperationState, "The conversation contains an existing draft; it was not overwritten.");
var baseline = ReadVisible(main).Select(item => item.Fingerprint).ToHashSet(StringComparer.Ordinal);
var baseline = CountFingerprints(ReadVisible(main));
if (main.FindAllDescendants(cf => cf.ByAutomationId(WechatLocators.MentionPopover))
.Any(element => !element.Properties.IsOffscreen.ValueOrDefault))
throw new WxAgentException(WxAgentErrorCode.InvalidOperationState, "An existing mention popup must be dismissed before starting a new operation.");
@@ -299,14 +307,17 @@ public static partial class WechatChatClient
var lists = popovers[0].FindAllDescendants(cf => cf.ByAutomationId(WechatLocators.MentionList));
if (lists.Length != 1)
throw new WxAgentException(WxAgentErrorCode.ControlNotFound, "A unique mention list was not found; no send was attempted.");
var options = lists[0].FindAllDescendants(cf => cf.ByControlType(ControlType.ListItem).And(cf.ByName(memberName)))
.Where(element => !element.Properties.IsOffscreen.ValueOrDefault && !element.BoundingRectangle.IsEmpty)
.ToArray();
if (options.Length != 1)
throw new WxAgentException(WxAgentErrorCode.ControlNotFound, "A unique mention option in a fresh WeChat popup was not found; no send was attempted.");
var options = lists[0].FindAllDescendants(cf => cf.ByControlType(ControlType.ListItem));
var optionSnapshots = options.Select(element => (
Name: (string?)SafeName(element),
IsOffscreen: element.Properties.IsOffscreen.ValueOrDefault,
HasBounds: !element.BoundingRectangle.IsEmpty)).ToArray();
var optionIndex = WechatMentionOptionSelection.FindUniqueVisibleOptionIndex(groupMemberNames, optionSnapshots, memberName);
if (optionIndex < 0)
throw new WxAgentException(WxAgentErrorCode.ControlNotFound, "A unique visible mention option was not found; no send was attempted.");
if (!IsListeningSession(main, session, independent: false))
throw new WxAgentException(WxAgentErrorCode.ResultUnconfirmed, "The conversation changed before mention selection.");
ClickCenter(options[0]);
ClickCenter(options[optionIndex]);
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
input = FindByAutomationId(main, WechatLocators.ChatInput)
?? throw new WxAgentException(WxAgentErrorCode.ControlNotFound, "Chat input disappeared after mention selection.");