Rust libraries
Use these libraries for supported WeChat server operations and official profile storage. They run without the daemon or an official executable. Applications connecting to an existing daemon can use the HTTP API.
| Crate | Purpose |
|---|---|
| wechat-protocol | Transport, authentication, sync and message codecs |
| wechat-profile | Profile keys, history, contacts, cached media and checked writers |
| wechat-media | Shared image inspection and decoding |
| wechat-platform | Private files and OS support |
The Rust crate architecture maps published libraries and internal runtime dependencies. Use the Calls API to connect a calling client to the daemon.
Add dependencies
-
Add the libraries;
1.3.0is their first crates.io release:Terminal window cargo add wechat-protocol@=1.3.0 wechat-profile@=1.3.0 -
Build with Rust 1.93.1+, a C compiler, Make and Perl. All four crates follow the native release version; Cargo resolves the supporting crates automatically.
Read a stopped profile
Stop the profile’s writer or provide a consistent copy, then load your protected keys file. The snapshot flag records that assertion; it does not stop a process.
use wechat_profile::{KeyFile, ListQuery, ProfileLocation, ProfileReader, ReadOptions};
fn contacts(profile: &str, keys_path: &str) -> wechat_profile::Result<()> { let location = ProfileLocation::new(profile)?; let keys = KeyFile::load(keys_path)?; let reader = ProfileReader::open(location, keys, ReadOptions { stopped_or_consistent_snapshot: true, ..Default::default() })?; println!("{} contacts", reader.contacts(&ListQuery::default())?.items.len()); Ok(())}Reading cached media never initiates a download. An application already owning
the profile can use OwnedReaderCache with its own synchronization.
Send one text message
Server operations are mostly methods on
NativeClient,
rather than entries in the crate’s Functions list. The daemon calls the same
library; the caller owns credential storage, recovery and profile writeback.
-
Call
start_qr_login, display the QR privately, poll untilLoginStatus::Approved, then callcomplete_loginfor secretAccountState. -
Save the intended operation, unique task ID and Unix-seconds timestamp before submitting. Pass the recipient’s exact WeChat username:
use wechat_protocol::{wire, AccountState, NativeClient, TextSendResult};fn send_once(client: &NativeClient,state: &mut AccountState,recipient: &str,text: &str,task_id: &str,created_at: u32,) -> anyhow::Result<TextSendResult> {let client_id = wire::client_message_id(task_id.as_bytes());anyhow::ensure!(client_id != 0, "Choose another task ID");client.send_text(state, recipient, text, created_at, client_id)} -
Check
accepted,returned_destination_matchesandreturned_client_id_matches. An accepted receipt includes a decimal-stringserver_message_id; it does not establish recipient playback or history writeback.
Run the source examples
From a repository checkout:
cargo run --manifest-path packages/native-client-rust/Cargo.toml -p wechat-protocol --example send_text -- RECIPIENT UNIQUE_TASK_ID "Hello from the Rust example"After QR approval, the example submits once and prints a receipt with
"accepted": true on server acceptance. qr_login demonstrates login alone;
sync_once summarizes one page; protobuf demonstrates a local codec.
--help makes no network requests. A persistent receiver must handle and retain
sync commands before committing the next cursor; sync_once saves no checkpoint.
Profile writes
The library implements official storage formats; account policy and recovery belong to its caller. These prefixes describe our API, not official-client names:
| Prefix | Usual meaning |
|---|---|
stage_* | Prepare bytes without changing the profile |
apply_* | Apply a logical profile update |
publish_* | Install bytes at local profile paths |
Both apply_* and publish_* write data, with overlap: publish_saved_key_info
can change a database and a file. Neither prefix guarantees whole-operation
atomicity. New mutations use apply_*; existing publish_* names stay compatible.
For MMKV, staging constructs encrypted data and matching .crc metadata in
memory. Publication installs those bytes through temporary files into the
profile’s existing paths. WriteOptions::durable_intent_id references the caller’s
previously saved recovery record; the library cannot prove that record exists.