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 the first successful inbound message, the account and Admin binding persist the latest recipient and protected conversation context. This lets Admin Chat and NeuBell continue sending after a page reload or process restart when the WeChat-side context is still valid. The Admin integration also performs one startup NeuBell reconciliation and stores per-provider snapshot fingerprints to avoid duplicate recovery messages. Apply the Admin module's latest database migration before enabling this behavior in production, and persist ASP.NET Data Protection keys across deployments; otherwise encrypted bot/context tokens cannot be recovered.
If the WeChat-side context has expired or the Data Protection keys were replaced, send a fresh
message from the phone to establish a new context. 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.14" />
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.