# API 使用文档
本文档详细介绍WeChat SDK for Rust的所有API接口和使用方法。
## 📑 目录
- [核心API](#核心api)
- [公众号API](#公众号api)
- [小程序API](#小程序api)
- [加密解密API](#加密解密api)
- [错误处理](#错误处理)
## 🔧 核心API
### WeChat 客户端
#### 创建客户端
```rust
use wechat_sdk::WeChat;
// 使用Builder模式创建
let client = WeChat::builder()
.app_id("wx1234567890123456")
.app_secret("your_32_char_app_secret")
.timeout(std::time::Duration::from_secs(30))
.build()?;
// 从配置创建
let config = WeChatConfig::from_env()?;
let client = config.build_client()?;
```
#### 客户端方法
```rust
impl WeChat {
// 获取核心客户端
pub fn core(&self) -> &Client;
// 获取公众号客户端 (需要 "official" 特性)
#[cfg(feature = "official")]
pub fn official(&self) -> OfficialClient;
// 获取小程序客户端 (需要 "miniapp" 特性)
#[cfg(feature = "miniapp")]
pub fn miniapp(&self) -> MiniAppClient;
}
```
## 📞 公众号API
### 消息管理
#### 发送客服消息
```rust
// 文本消息
client.official()
.message()
.to("user_openid")
.text("Hello World!")
.send().await?;
// 图片消息
client.official()
.message()
.to("user_openid")
.image("media_id")
.send().await?;
// 语音消息
client.official()
.message()
.to("user_openid")
.voice("media_id")
.send().await?;
// 视频消息
client.official()
.message()
.to("user_openid")
.video("media_id")
.title("视频标题")
.description("视频描述")
.send().await?;
// 图文消息
let articles = vec![
Article {
title: "文章标题".to_string(),
description: "文章描述".to_string(),
url: "https://example.com".to_string(),
pic_url: "https://example.com/pic.jpg".to_string(),
}
];
client.official()
.message()
.to("user_openid")
.news(articles)
.send().await?;
```
#### 模板消息
```rust
use std::collections::HashMap;
let mut template_data = HashMap::new();
template_data.insert("first", "您好,您有新的订单!");
template_data.insert("keyword1", "订单号:12345");
template_data.insert("keyword2", "商品:Rust编程指南");
template_data.insert("remark", "请及时处理");
client.official()
.template()
.to("user_openid")
.template_id("template_id_here")
.url("https://example.com/order/12345") // 可选
.data(template_data)
.send().await?;
```
#### 群发消息
```rust
// 按标签群发
client.official()
.broadcast()
.tag_id(100) // 标签ID
.text("群发消息内容")
.send().await?;
// 按OpenID列表群发
let openids = vec!["openid1", "openid2", "openid3"];
client.official()
.broadcast()
.to_users(openids)
.text("定向群发消息")
.send().await?;
// 全部用户群发
client.official()
.broadcast()
.to_all()
.text("全员通知")
.send().await?;
```
### 用户管理
#### 获取用户信息
```rust
// 获取单个用户信息
let user_info = client.official()
.user()
.get("user_openid")
.await?;
println!("用户昵称: {}", user_info.nickname);
println!("用户头像: {}", user_info.headimgurl);
// 批量获取用户信息
let openids = vec!["openid1", "openid2"];
let users = client.official()
.user()
.batch_get(openids)
.await?;
```
#### 用户标签管理
```rust
// 创建标签
let tag = client.official()
.user()
.create_tag("VIP用户")
.await?;
// 获取所有标签
let tags = client.official()
.user()
.get_tags()
.await?;
// 给用户打标签
client.official()
.user()
.tag_users(tag.id, vec!["openid1", "openid2"])
.await?;
// 取消用户标签
client.official()
.user()
.untag_users(tag.id, vec!["openid1"])
.await?;
```
#### 获取关注者列表
```rust
// 获取关注者列表
let followers = client.official()
.user()
.get_followers(None) // next_openid,首次传None
.await?;
println!("关注者总数: {}", followers.total);
println!("本次返回数量: {}", followers.count);
// 分页获取
let mut next_openid = followers.next_openid;
while let Some(openid) = next_openid {
let page = client.official()
.user()
.get_followers(Some(openid))
.await?;
next_openid = page.next_openid;
// 处理这一页的用户...
}
```
### 素材管理
#### 上传素材
```rust
use std::path::Path;
// 上传临时素材
let media = client.official()
.media()
.upload_temp("image", Path::new("photo.jpg"))
.await?;
println!("Media ID: {}", media.media_id);
// 上传永久素材
let permanent_media = client.official()
.media()
.upload_permanent("image", Path::new("logo.jpg"))
.title("公司Logo") // 可选,仅对视频有效
.introduction("公司品牌标识") // 可选,仅对视频有效
.await?;
```
#### 下载素材
```rust
// 下载素材
let media_data = client.official()
.media()
.download("media_id")
.await?;
// 保存到文件
std::fs::write("downloaded_media.jpg", media_data)?;
```
#### 素材列表
```rust
// 获取永久素材列表
let media_list = client.official()
.media()
.list_permanent("image", 0, 20) // 类型,偏移量,数量
.await?;
for item in media_list.items {
println!("Media ID: {}, Name: {}", item.media_id, item.name);
}
```
### 自定义菜单
#### 创建菜单
```rust
use wechat_sdk::official::menu::*;
let menu = Menu {
button: vec![
Button::Click {
name: "今日歌曲".to_string(),
key: "V1001_TODAY_MUSIC".to_string(),
},
Button::View {
name: "官网".to_string(),
url: "https://www.example.com/".to_string(),
},
Button::SubMenu {
name: "菜单".to_string(),
sub_button: vec![
Button::View {
name: "搜索".to_string(),
url: "https://www.google.com/".to_string(),
},
Button::Click {
name: "赞一下我们".to_string(),
key: "V1001_GOOD".to_string(),
},
],
},
],
};
client.official()
.menu()
.create(menu)
.await?;
```
#### 查询菜单
```rust
let current_menu = client.official()
.menu()
.get()
.await?;
println!("当前菜单: {:?}", current_menu);
```
#### 删除菜单
```rust
client.official()
.menu()
.delete()
.await?;
```
### 网页授权
#### 生成授权URL
```rust
let auth_url = client.official()
.oauth()
.authorize_url(
"https://example.com/callback", // 回调URL
"state_value", // 状态值
"snsapi_userinfo", // 作用域
)?;
println!("请访问: {}", auth_url);
```
#### 获取访问令牌
```rust
// 用code换取access_token
let oauth_token = client.official()
.oauth()
.access_token("authorization_code")
.await?;
// 刷新访问令牌
let refreshed_token = client.official()
.oauth()
.refresh_token(&oauth_token.refresh_token)
.await?;
```
#### 获取用户信息
```rust
let user_info = client.official()
.oauth()
.user_info(&oauth_token.access_token, &oauth_token.openid)
.await?;
println!("用户昵称: {}", user_info.nickname);
```
## 📲 小程序API
### 登录和授权
#### 登录凭证校验
```rust
// code换session
let session = client.miniapp()
.auth()
.code_to_session("js_code_from_miniapp")
.call().await?;
println!("OpenID: {}", session.openid);
println!("Session Key: {}", session.session_key);
if let Some(unionid) = session.unionid {
println!("UnionID: {}", unionid);
}
```
#### 获取访问令牌
```rust
let access_token = client.miniapp()
.auth()
.get_access_token()
.await?;
println!("Access Token: {}", access_token.access_token);
```
### 数据解密
#### 用户数据解密
```rust
let user_info = client.miniapp()
.crypto()
.decrypt_data(
&session.session_key,
"encrypted_data_from_miniapp",
"iv_from_miniapp"
).await?;
println!("用户昵称: {}", user_info.nick_name);
println!("用户头像: {}", user_info.avatar_url);
println!("性别: {}", user_info.gender);
println!("城市: {}", user_info.city);
```
#### 手机号解密
```rust
let phone_info = client.miniapp()
.crypto()
.decrypt_phone(
&session.session_key,
"encrypted_data_for_phone",
"iv_for_phone"
).await?;
println!("手机号: {}", phone_info.phone_number);
println!("纯手机号: {}", phone_info.pure_phone_number);
println!("国家码: {}", phone_info.country_code);
```
### 订阅消息
#### 发送订阅消息
```rust
use serde_json::json;
let template_data = json!({
"thing1": {
"value": "订单确认"
},
"time2": {
"value": "2023-12-01 14:30:00"
},
"thing3": {
"value": "您的订单已确认,正在处理中"
}
});
client.miniapp()
.message()
.subscribe("user_openid")
.template_id("template_id_here")
.page("pages/order/detail?id=123") // 可选
.data(template_data)
.miniprogram_state("formal") // 可选:developer/trial/formal
.send().await?;
```
### 小程序码
#### 获取小程序码
```rust
// 获取小程序码(适用于需要的码数量较少的业务场景)
let qr_code = client.miniapp()
.qrcode()
.get("pages/index", None) // 页面路径,查询参数
.width(430) // 可选,默认430
.await?;
std::fs::write("miniapp_qrcode.jpg", qr_code)?;
// 获取小程序码(适用于需要的码数量极多的业务场景)
let unlimited_qr = client.miniapp()
.qrcode()
.get_unlimited("scene_value", "pages/index")
.width(430)
.await?;
```
### 数据分析
#### 获取用户访问数据
```rust
use chrono::{Utc, Duration};
let end_date = Utc::now().date_naive();
let start_date = end_date - Duration::days(7);
// 获取日访问趋势
let daily_visit = client.miniapp()
.datacube()
.get_daily_visit_trend(start_date, end_date)
.await?;
for data in daily_visit.list {
println!("日期: {}, 访问人数: {}", data.ref_date, data.session_cnt);
}
// 获取用户画像数据
let user_portrait = client.miniapp()
.datacube()
.get_user_portrait(start_date, end_date)
.await?;
```
## 🔐 加密解密API
### 消息加解密
```rust
use wechat_sdk::crypto::MessageCrypto;
let crypto = MessageCrypto::new("token", "encoding_aes_key", "app_id")?;
// 解密消息
let decrypted = crypto.decrypt("encrypted_msg", "msg_signature", "timestamp", "nonce")?;
println!("解密后的消息: {}", decrypted);
// 加密回复
let encrypted = crypto.encrypt("reply_message")?;
```
### 数据签名验证
```rust
use wechat_sdk::signature;
// 验证微信服务器签名
let is_valid = signature::verify_signature(
"your_token",
"signature_from_wechat",
"timestamp",
"nonce"
)?;
if is_valid {
println!("签名验证通过");
}
// 生成JS-SDK签名
let js_signature = signature::generate_js_signature(
"jsapi_ticket",
"noncestr",
"timestamp",
"url"
)?;
```
## ❌ 错误处理
### 错误类型
```rust
use wechat_sdk::{WeChatError, Result};
#[derive(thiserror::Error, Debug)]
pub enum WeChatError {
#[error("HTTP request failed: {0}")]
Http(#[from] reqwest::Error),
#[error("WeChat API error: {code} - {message}")]
Api { code: i32, message: String },
#[error("Authentication failed: {0}")]
Auth(String),
#[error("Invalid configuration: {0}")]
Config(String),
#[error("Signature verification failed")]
Signature,
#[error("Encryption/Decryption failed: {0}")]
Crypto(String),
// ... 其他错误类型
}
```
### 错误处理最佳实践
```rust
use wechat_sdk::{WeChat, WeChatError};
async fn handle_wechat_api() {
let client = WeChat::builder()
.app_id("app_id")
.app_secret("app_secret")
.build()
.unwrap();
match client.official().message().to("openid").text("hello").send().await {
Ok(_) => println!("消息发送成功"),
Err(WeChatError::Api { code, message }) => {
match code {
40001 => {
// access_token过期,重新获取
println!("Access token过期,需要重新获取");
}
40003 => {
// openid无效
println!("无效的openid: {}", message);
}
45015 => {
// 回复时间超过限制
println!("回复时间超过限制");
}
_ => {
println!("微信API错误: {} - {}", code, message);
}
}
}
Err(WeChatError::Http(e)) => {
println!("网络请求失败: {}", e);
// 可以考虑重试
}
Err(e) => {
println!("其他错误: {}", e);
}
}
}
```
### 重试机制
```rust
use tokio::time::{sleep, Duration};
async fn send_message_with_retry(client: &WeChat, openid: &str, content: &str) -> Result<(), WeChatError> {
let max_retries = 3;
let mut attempts = 0;
while attempts < max_retries {
match client.official().message().to(openid).text(content).send().await {
Ok(_) => return Ok(()),
Err(WeChatError::Http(_)) if attempts + 1 < max_retries => {
attempts += 1;
let delay = Duration::from_millis(100 * 2_u64.pow(attempts));
println!("网络错误,{}ms后重试 (尝试 {}/{})", delay.as_millis(), attempts + 1, max_retries);
sleep(delay).await;
}
Err(e) => return Err(e),
}
}
unreachable!()
}
```
## 🔧 高级用法
### 中间件支持
```rust
use wechat_sdk::middleware::*;
let client = WeChat::builder()
.app_id("app_id")
.app_secret("app_secret")
.middleware(RetryMiddleware::new(3)) // 重试中间件
.middleware(LoggingMiddleware::new()) // 日志中间件
.middleware(RateLimitMiddleware::new(10)) // 限流中间件
.build()?;
```
### 自定义HTTP客户端
```rust
use reqwest::Client;
use std::time::Duration;
let http_client = Client::builder()
.timeout(Duration::from_secs(30))
.user_agent("MyApp/1.0")
.build()?;
let client = WeChat::builder()
.app_id("app_id")
.app_secret("app_secret")
.http_client(http_client)
.build()?;
```
---
## 📚 更多资源
- [快速开始指南](./quickstart.md)
- [配置指南](./configuration.md)
- [最佳实践](./best-practices.md)
- [示例代码](../examples/)
- [API文档](https://docs.rs/wechat-sdk)