Install
| Product | Versions |
|---|---|
| .NET |
README
Senparc.Xncf.WeixinManager
Senparc.Xncf.WeixinManager is an NCF administration module for managing WeChat public-account configuration, users, tags, message handlers, and reusable notification templates.
Features
- Persists
MpAccount,WeixinUser, andUserTagdata with DTOs and service layers. - Supports account discovery, user synchronization, tag management, and WeChat-facing message handling.
- Provides
WeixinService,XncfMpMessageHandler, and template base types for module integrations. - Uses Senparc.Weixin APIs and NCF's multi-database context conventions.
Personal Weixin Bot
The module also supports the personal Weixin Bot channel used by Tencent's official openclaw-weixin package. It implements the iLink HTTP JSON protocol directly and does not require the OpenClaw runtime.
- Open
/Admin/WeixinManager/WeixinClawto scan a QR code and connect an account. - Polls inbound text messages with a persisted
get_updates_bufcursor. - Stores
message_id + seqreceipts for idempotent processing. - Protects bot tokens with ASP.NET Data Protection.
- Exposes
IWeixinClawMessageHandlerfor Admin Chat, NeuBell, or custom routing. - Exposes
IWeixinClawMessageSender/WeixinClawMessageService.SendTextAsync()for outbound text. - Supports outbound images, files, and voice files through
getuploadurl, the iLink CDN upload flow, andsendmessage. - Downloads inbound image, voice, video, and file media from the iLink CDN, decrypts it, and stores it
under the host
App_Data/WeixinClawMediadirectory for authenticated conversation display. - Requests a tenant-scoped private-attachment import through the FileManager Abstractions EventBus contract. The message record keeps the resulting FileManager file ID; if FileManager is unavailable, the original Weixin conversation copy remains usable and the import error is recorded separately.
- Persists the latest inbound user and protected
context_token, so the Admin page can send a reply after the phone sends at least one message. The page reports an actionable error instead of treating a context-less send as delivered. - Persists inbound and outbound text records in
WeixinManager_WeixinClawMessageRecord; the Admin page provides a polling conversation window and showssending,sent, andfailedstates. The window also supports image, file, and voice-file uploads.
Sends require the inbound context_token for the same recipient, preserved without trimming.
Completing a poll updates the cursor/running status without clearing the stored inbound sender or context.
Replying to a stored inbound record uses that record's sender and context; an invalid reply record is
rejected rather than silently sending to a different conversation. Media sends without a reply record
only reuse the latest context when its sender matches the recipient.
An HTTP success with ret=0 means the API accepted the request, not that the phone displayed it.
The official response's message_id is optional: its absence does not make an accepted request fail.
The official ret field is also optional; as in Tencent's sender, a supplied nonzero ret is a business
failure, while an omitted ret is preserved as absent rather than fabricated as zero.
The existing sent state means API submission, not a read/delivery receipt. Business errors still
produce a failed record. Native voice sends support SILK and MP3 encoding declarations only; other
audio formats must be sent as files. Outbound audio is not transcoded, and the module does not invent sample rate,
bit depth, or duration metadata.
Conversation media playback
- Incoming
video_item(item type 5) is downloaded/decrypted and stored as MP4 rather than ignored. Video and audio responses support HTTP Range requests for browser seeking. - SILK voice recordings, including old
.binfiles, are detected from their actual header. The authenticated playback endpoint decodes them to 24-kHz, mono, signed 16-bit PCM WAV on demand. A.playback.wavsidecar is cached; the original recording and its download URL are preserved. - Decoding reuses the existing
DrAbc.SilkSharp2.0.8 dependency. It deliberately uses the file-based codec API: the package's POSIX buffer API incorrectly reads an output-onlyopen_memstream, causing empty or corrupt output. Calls are serialized, input framing is validated, and temporary snapshots/PCM files are removed after conversion. No recording is uploaded to a decoding service. - The legacy native decoder requires at least three packets (normally 60 ms). Short/truncated input, packets exceeding its 5-KB bound, and input/estimated or actual PCM above 50 MB are explicitly rejected before playback instead of invoking unsafe native paths or exhausting memory.
- Deploy the package's native runtime assets alongside the application. Supported bundled targets include Windows x86/x64, Linux x86/x64/ARM/ARM64, and macOS ARM64; unsupported targets produce an explicit playback error. The existing codec dependency is GPL-3.0-or-later.
- Browser-compatible MP4 video is played directly, not transcoded. H.264/AAC has been verified; other codecs still require browser support. The original download remains available if playback fails.
- Videos discarded by older versions cannot be reconstructed from an already-advanced poll cursor; resend them after deploying this update.
The page refreshes connection state immediately when opened and continues periodic refreshes. Initial server-rendered account data uses camelCase, matching the AJAX response. Only the conversation composer remains; the duplicate bottom send form and its visibility/manual-context state have been removed.
Playback tests cover generated SILK, malformed framing, cancellation, cached conversion, video decryption,
and Range-enabled media results. Set WEIXINCLAW_VOICE_SAMPLE to the provided 4.2-second local fixture
when running its opt-in regression test; private recordings are not committed as test assets.
Protocol verification (2026-10-03)
The Weixin Open Documentation ClawBot page
documents the /api/v1/wechat/* login/channel wrapper, not the full direct iLink sendmessage contract.
The direct protocol was cross-checked against Tencent's published
@tencent-weixin/openclaw-weixin 2.4.9 source,
particularly src/api/types.ts, src/api/api.ts, src/messaging/send.ts, and src/cdn/upload.ts.
- JSON property names are case-sensitive on output:
type,text_item.text,image_item.media,voice_item.media, andfile_item.media/file_item.lenmust not use C# property casing. - Text, image, voice, and file messages all use
message_type: 2(BOT) andmessage_state: 2(FINISH). The content type isitem_list[].type: text=1, image=2, voice=3, file=4. - Outbound
msgincludesfrom_user_id: "", the recipient,client_id, message type/state, items, and context;run_idis optional. Server-only inbound fields and null payload branches are omitted. - JSON POSTs use
AuthorizationType: ilink_bot_token,Authorization: Bearer <bot_token>, a random uint32 decimal string encoded as base64 inX-WECHAT-UIN, andContent-Type: application/json. App headers areiLink-App-Id: botandiLink-App-ClientVersion: 132105;base_info.channel_versionis2.4.9, with NCF identified bybot_agent. QR creation is a token-less POST; status polling is GET. - Upload requests use
rawsize/rawfilemd5for plaintext,filesizefor PKCS7-padded AES-128-ECB ciphertext, and a lowercase hexaeskey. Following the official sender, the outgoing mediaaes_keyis base64 of that hex string; filelenis plaintext size as a string. - Contract tests compare complete parsed JSON objects (including field names and value types), authenticated request headers, business-error handling, optional response fields, and uint64 IDs. Pipeline tests exercise the actual send services, decrypt their uploaded ciphertext to verify plaintext/MD5/sizes/key encoding, and confirm that polling preserves a usable reply context.
After deploying, send a fresh message from the phone and reply from NCF to that inbound record.
Verify that the actual phone displays the text and media; unit tests and ret=0 alone cannot prove delivery.
Concrete Admin Chat, NeuBell, Workflow, and Harness routing is implemented by the upper-layer Admin integration rather than this channel module.
Hosted-service tuning
The background WeixinClaw poller can be tuned with the SenparcXncfWeixinManager:WeixinClaw:HostedService
configuration section:
ScanIntervalSeconds- account discovery interval, clamped to 1-300 seconds.ErrorRetryDelaySeconds- delay aftergetupdatesreturns a business error, clamped to 1-300 seconds.ShutdownWaitSeconds- host shutdown grace period for in-flight poll tasks, clamped to 1-60 seconds.NotifyStopTimeoutSeconds- timeout for the best-effortnotifystopcall, clamped to 1-30 seconds.
Installation
<PackageReference Include="Senparc.Xncf.WeixinManager" Version="0.24.13" />
Key API
MpAccountServicemanages account configuration andMpAccountrecords.WeixinServiceprovides module-level WeChat operations.WeixinUser/WeixinUserDtoandUserTag/UserTag_WeixinUserDtorepresent synchronized user and tag data.MpMessageHandlerAttributeandXncfMpMessageHandlerconnect incoming WeChat messages to NCF handlers.WeixinTemplateBaseand theWeixinTemplate_*types support reusable template messages.FindWeixinApiControllerexposes API discovery/management endpoints.
Store AppSecret, access tokens, and encryption keys in secure configuration. Validate WeChat signatures, scope account access by tenant/administrator, and treat synchronized user data as personal information.
Changes from Previous Version
Adoption Assessment
A verified publisher signal is available. Assess fit from the package's supported frameworks, license and dependency graph rather than popularity alone.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.