The Rust SDK is async, type-safe, and built on tokio + reqwest + serde. 38 tests. All protocol types derive Serialize + Deserialize + Clone + Debug. Tested on Linux, macOS, and Windows.
Install
cargo add wechatbot tokio --features tokio/full
Quick start
use wechatbot::{WeChatBot, BotOptions}; #[tokio::main] async fn main() { let bot = WeChatBot::new(BotOptions::default()); let creds = bot.login(false).await.unwrap(); println!("Logged in: {}", creds.account_id); bot.on_message(Box::new(|msg| { println!("{}: {}", msg.user_id, msg.text); })).await; bot.run().await.unwrap(); }
Configuration
let bot = WeChatBot::new(BotOptions { base_url: None, // default: ilinkai.weixin.qq.com cred_path: None, // default: ~/.wechatbot/credentials.json on_qr_url: Some(Box::new(|url| { println!("Scan: {}", url); })), on_error: Some(Box::new(|err| { eprintln!("Error: {}", err); })), });
Message handling
bot.on_message(Box::new(|msg| { match msg.content_type { ContentType::Text => println!("Text: {}", msg.text), ContentType::Image => { for img in &msg.images { println!("Image: {:?}", img.url); } } ContentType::Voice => { for v in &msg.voices { println!("Voice: {:?} ({}ms)", v.text, v.duration_ms.unwrap_or(0)); } } ContentType::File => { for f in &msg.files { println!("File: {:?}", f.file_name); } } ContentType::Video => println!("Video received"), } })).await;
Sending messages
// Reply bot.reply(&msg, "Echo: hello").await?; // Send (needs prior context_token) bot.send(user_id, "Hello").await?; // Typing bot.send_typing(user_id).await?;
Error handling
use wechatbot::WeChatBotError; match result { Err(WeChatBotError::Api { errcode: -14, .. }) => { // session expired β handled automatically } Err(WeChatBotError::NoContext(uid)) => { // no context_token yet } Err(WeChatBotError::Transport(e)) => { // network error } _ => {} }
AES-128-ECB crypto
use wechatbot::{generate_aes_key, encrypt_aes_ecb, decrypt_aes_ecb, decode_aes_key}; let key = generate_aes_key(); let ct = encrypt_aes_ecb(b"Hello", &key); let pt = decrypt_aes_ecb(&ct, &key)?; // Decode protocol key (all 3 formats) let k = decode_aes_key("ABEiM0RVZneImaq7zN3u/w==")?; // base64(raw) let k = decode_aes_key("00112233445566778899aabbccddeeff")?; // hex