Skip to content

Commit 757a37c

Browse files
committed
chore: trim core API surface and refresh docs
1 parent e76106d commit 757a37c

91 files changed

Lines changed: 997 additions & 3319 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ BotRS 是一个用 Rust 实现的 QQ 频道机器人框架,基于 [QQ 频道
1818

1919
```toml
2020
[dependencies]
21-
botrs = "0.11.0"
21+
botrs = "0.13.0"
2222
tokio = { version = "1.0", features = ["full"] }
2323
tracing = "0.1"
2424
tracing-subscriber = "0.3"
@@ -28,8 +28,7 @@ async-trait = "0.1"
2828
### 基础示例
2929

3030
```rust,no_run
31-
use botrs::{Client, Context, EventHandler, Intents, Token, Message};
32-
use botrs::models::gateway::Ready;
31+
use botrs::{Client, Context, EventHandler, Intents, Message, Ready, Token};
3332
use botrs::models::message::MessageParams;
3433
use tracing::info;
3534

docs/.vitepress/config.mts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default defineConfig({
2424
{ text: "API Reference", link: "/api/client" },
2525
{ text: "Examples", link: "/examples/getting-started" },
2626
{
27-
text: "v0.2.5",
27+
text: "v0.13.0",
2828
items: [
2929
{ text: "Changelog", link: "/changelog" },
3030
{ text: "Contributing", link: "/contributing" },
@@ -111,11 +111,11 @@ export default defineConfig({
111111
],
112112
},
113113
{
114-
text: "Migration Guide",
114+
text: "Reference",
115115
items: [
116116
{
117-
text: "v0.2.0 Message API",
118-
link: "/guide/migration-v0.2.0",
117+
text: "Message API Shape",
118+
link: "/guide/message-api",
119119
},
120120
{
121121
text: "From Python",
@@ -263,7 +263,7 @@ export default defineConfig({
263263
{ text: "API 参考", link: "/zh/api/client" },
264264
{ text: "示例", link: "/zh/examples/getting-started" },
265265
{
266-
text: "v0.2.5",
266+
text: "v0.13.0",
267267
items: [
268268
{ text: "更新日志", link: "/zh/changelog" },
269269
{ text: "贡献指南", link: "/zh/contributing" },
@@ -350,11 +350,11 @@ export default defineConfig({
350350
],
351351
},
352352
{
353-
text: "迁移指南",
353+
text: "参考",
354354
items: [
355355
{
356-
text: "v0.2.0 消息 API",
357-
link: "/zh/guide/migration-v0.2.0",
356+
text: "消息 API 形态",
357+
link: "/zh/guide/message-api",
358358
},
359359
{
360360
text: "从 Python 迁移",

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ When releasing new versions:
173173
1. Update changelog
174174
2. Update version references in code examples
175175
3. Add migration guides if needed
176-
4. Update any deprecated feature warnings
176+
4. Update any feature notes that users need to see
177177

178178
## Getting Help
179179

@@ -184,4 +184,4 @@ When releasing new versions:
184184

185185
## License
186186

187-
This documentation is licensed under the MIT License, same as the BotRS project.
187+
This documentation is licensed under the MIT License, same as the BotRS project.

docs/api/bot-api.md

Lines changed: 64 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,103 @@
11
# BotApi
22

3-
`BotApi` is the synchronous-style facade over the QQ Bot Open API. It owns the HTTP client, builds requests, signs them with a `Token`, and returns parsed model types. Every method is `async` and returns `Result<T, BotError>`.
3+
`BotApi` is the REST client used by a bot while handling events. After a gateway event arrives, handlers usually call it through `Context` to send replies, recall channel messages, upload group/C2C files, manage announcements, schedules and pins, inspect reaction users, or create API permission requests.
44

5-
## Construction
5+
When your bot is driven by `Client`, you normally do not construct `BotApi` yourself. Every event callback receives a `Context` that already owns the shared API client:
66

77
```rust
8-
use botrs::{BotApi, http::HttpClient, Token};
8+
let params = MessageParams::new_text("pong").with_reply(message_id);
9+
ctx.send_message(&channel_id, params).await?;
10+
```
11+
12+
Construct `BotApi` manually only when you want to call REST without running the gateway:
913

10-
let http = HttpClient::new(/* timeout secs */ 30, /* sandbox */ false)?;
14+
```rust
15+
let http = HttpClient::new(30, false)?;
1116
let token = Token::new("app_id", "secret");
1217
let api = BotApi::new(http, token);
1318

1419
let me = api.get_bot_info().await?;
1520
```
1621

17-
`BotApi` is `Clone` and cheap to clone; the inner HTTP client is reference-counted. For a bot client driven by `Client`, `Context` dereferences to the same `BotApi`, so handler code can call `ctx.send_message(...)` directly.
18-
19-
## Method index
20-
21-
Every method takes `&self` plus endpoint-specific arguments and returns `Result<…>`. The token is stored on `BotApi`. The lists below group the 100+ routes by domain. Look up parameter and response types in [Models](./models/messages.md), [Guilds & Channels](./models/guilds-channels.md), and [Other Types](./models/other-types.md).
22-
23-
### Bot identity
24-
25-
- `get_bot_info``/users/@me`, returns `BotInfo`.
26-
- `get_gateway` — gateway URL + recommended shard count.
27-
28-
### Guilds
29-
30-
- `get_guild` / `get_guilds` / `get_guilds_with_pager`
31-
- guild members: `get_guild_member`, `get_guild_members`, `get_guild_members_with_pager`
32-
- role members: `get_guild_role_members`, `get_guild_role_members_with_pager`
33-
- mute: `mute_all`, `cancel_mute_all`, `mute_member`, `mute_multi_member`, `multi_member_mute`, `cancel_mute_multi_member`
34-
35-
### Channels
36-
37-
- `get_channel`, `get_channels`
38-
- `create_channel`, `create_private_channel`, `update_channel`, `delete_channel`
39-
- permissions: `get_channel_user_permissions`, `get_channel_role_permissions`, `update_channel_user_permissions`, `update_channel_role_permissions`, `put_channel_permissions`, `put_channel_roles_permissions`
40-
41-
### Roles
42-
43-
- `get_guild_roles`
44-
- `create_guild_role`, `update_guild_role`, `delete_guild_role`
45-
- assign / remove: `create_guild_role_member`, `delete_guild_role_member`, `delete_member`, `delete_member_with_options`
46-
47-
### Messages (channel)
48-
49-
- `get_message`, `get_messages`
50-
- send: `send_message`.
51-
- edit: `edit_message`.
52-
- recall: `recall_message`.
53-
54-
### Direct messages
55-
56-
- create session: `create_direct_message`.
57-
- send: `send_direct_message`.
58-
- recall: `retract_dm_message`.
59-
- setting guide: `post_dm_setting_guide`, `post_dm_setting_guide_message`.
60-
61-
### Group / C2C messages
62-
63-
- send: `send_group_message`, `send_c2c_message`.
64-
- recall: `retract_group_message`, `retract_c2c_message`.
65-
- file upload: `post_group_file`, `post_c2c_file`.
66-
67-
### Reactions
68-
69-
- `put_reaction`, `delete_reaction`, `delete_own_message_reaction`
70-
- `create_message_reaction`, `get_reaction_users`, `get_message_reaction_users`
71-
72-
### Pins
22+
## Current Surface
7323

74-
- `put_pin`, `delete_pin`, `get_pins`, `clean_pins`
24+
`BotApi` covers these paths:
7525

76-
### Announces
26+
| Area | Methods |
27+
| --- | --- |
28+
| Bot identity and gateway discovery | `get_bot_info`, `get_gateway` |
29+
| Guild channel messages | `send_message`, `recall_message` |
30+
| Group and C2C messages | `send_group_message`, `send_c2c_message` |
31+
| Direct messages | `create_direct_message`, `send_direct_message` |
32+
| Group/C2C files | `post_group_file`, `post_c2c_file` |
33+
| Announcements | `create_announce`, `create_recommend_announce`, `delete_announce` |
34+
| Schedules | `get_schedules`, `get_schedule`, `create_schedule`, `update_schedule`, `delete_schedule` |
35+
| API permissions | `get_api_permissions`, `post_permission_demand` |
36+
| Reactions | `put_reaction`, `delete_reaction`, `get_reaction_users` |
37+
| Pins | `put_pin`, `delete_pin`, `get_pins` |
7738

78-
- guild: `create_guild_announce`, `delete_guild_announce`, `clean_guild_announces`, `create_guild_recommend_announce`, `create_recommend_announce`
79-
- channel: `create_channel_announce`, `delete_channel_announce`, `clean_channel_announces`
80-
- shorthand: `create_announce`, `delete_announce`
39+
## Sending Messages
8140

82-
### Schedules
41+
Message sending uses parameter structs:
8342

84-
- `get_schedules`, `get_schedule`, `create_schedule`, `update_schedule`, `delete_schedule`
85-
86-
### API permissions
87-
88-
- `get_api_permissions`, `post_permission_demand`, `require_api_permissions`
89-
90-
### Audio / voice
91-
92-
- `post_audio` (uses `AudioControl`), `update_audio`
93-
- `on_microphone`, `off_microphone`, `list_voice_channel_members`
43+
```rust
44+
let params = MessageParams::new_text("hello");
45+
ctx.send_message(&channel_id, params).await?;
9446

95-
### Setting guide
47+
let params = GroupMessageParams::new_text("hello group");
48+
ctx.send_group_message(&group_openid, params).await?;
49+
```
9650

97-
- `post_setting_guide`, `post_setting_guide_message`
51+
Guild channel messages and DMs use `MessageParams` / `DirectMessageParams`. Group and C2C messages use `GroupMessageParams` / `C2CMessageParams`, matching QQ's open-message shape. For ark, embed, markdown, keyboard, or media payloads, set the corresponding field on the parameter struct.
9852

99-
### Interaction
53+
## Files and Media
10054

101-
- `put_interaction` — acknowledges a button/interaction event.
55+
Group and C2C media sending is a two-step flow: upload the file to receive a `Media`, then place that media object into a message parameter struct. `file_type` follows the platform values: commonly 1 image, 2 video, 3 audio, 4 file.
10256

103-
### Webhook sessions
57+
```rust
58+
let media = ctx
59+
.post_group_file(&group_openid, 1, "https://example.com/image.png", None)
60+
.await?;
10461

105-
- `create_session`, `check_sessions`, `session_list`, `remove_session`
62+
let mut params = GroupMessageParams::default();
63+
params.msg_type = 7;
64+
params.media = Some(media);
65+
ctx.send_group_message(&group_openid, params).await?;
66+
```
10667

107-
### Message setting
68+
When `srv_send_msg` is `Some(true)`, the platform sends the uploaded file directly, so you usually do not need a separate media message.
10869

109-
- `get_message_setting` — guild push and DM toggles.
70+
## Announcements, Schedules, Pins, Permissions
11071

111-
## Worked examples
72+
These APIs are direct wrappers around their protocol payloads:
11273

113-
**Reply to an @-mention with a keyboard.** Build the keyboard once, attach to `MessageParams`, and dispatch with `send_message`.
74+
- Announcements can be created from an existing message or from a list of recommended channels.
75+
- Schedules support listing, fetching one item, creating, updating, and deleting.
76+
- Pins support pinning one message, unpinning one message, and listing pinned message ids.
77+
- API permission requests take `channel_id`, `APIPermissionDemandIdentify`, and a description.
11478

11579
```rust
116-
let keyboard = Keyboard {
117-
content: Some(KeyboardContent {
118-
rows: Some(vec![KeyboardRow {
119-
buttons: Some(vec![KeyboardButton {
120-
id: Some("ok".into()),
121-
render_data: Some(KeyboardButtonRenderData {
122-
label: Some("OK".into()),
123-
style: Some(1),
124-
..Default::default()
125-
}),
126-
action: Some(KeyboardButtonAction {
127-
action_type: Some(1),
128-
permission: Some(KeyboardButtonPermission {
129-
permission_type: Some(2),
130-
..Default::default()
131-
}),
132-
data: Some("ok".into()),
133-
..Default::default()
134-
}),
135-
..Default::default()
136-
}]),
137-
}]),
138-
..Default::default()
139-
}),
140-
..Default::default()
80+
let identify = APIPermissionDemandIdentify {
81+
path: "/channels/{channel_id}/messages".to_string(),
82+
method: "POST".to_string(),
14183
};
14284

143-
let mut params = MessageParams::new_text("Choose:")
144-
.with_reply(message.id.as_deref().unwrap_or(""));
145-
params.keyboard = Some(keyboard);
146-
147-
api.send_message(&channel_id, params).await?;
148-
```
149-
150-
**Paginated member listing.** Use the pager helper to avoid manually threading `after`.
151-
152-
```rust
153-
let pager = ctx
154-
.get_guild_members_with_pager(&guild_id, &GuildMembersPager::default())
85+
ctx.post_permission_demand(&guild_id, &channel_id, identify, "Need to send replies")
15586
.await?;
156-
for member in pager.items {
157-
/* ... */
158-
}
15987
```
16088

161-
**Update channel permissions safely.** The `validate()` helper rejects non-numeric strings before they reach the server.
89+
## Errors
90+
91+
All methods return `botrs::Result<T>`. In event handlers, handle errors locally because `EventHandler` methods return `()`:
16292

16393
```rust
164-
let body = UpdateChannelPermissions::new(Some("1024"), Some("0"));
165-
body.validate()?;
166-
api.update_channel_user_permissions(&channel_id, &user_id, &body).await?;
94+
if let Err(err) = ctx.send_message(&channel_id, params).await {
95+
tracing::warn!("send failed: {err}");
96+
}
16797
```
16898

169-
## Error handling
170-
171-
Every call returns `Result<T, BotError>`. Match on `BotError` to distinguish:
172-
173-
- `BotError::Http` — transport-level failures (timeout, DNS).
174-
- `BotError::Api { code, message, .. }` — non-2xx response with the QQ-defined error code.
175-
- `BotError::Auth` — token signing or refresh failure.
176-
- `BotError::InvalidData` — local validation failure (e.g. malformed permission string).
177-
178-
For 429 responses, `BotError::Api` carries the `Retry-After` hint when present; the framework does not retry automatically — wrap calls with your own backoff if you need that behavior.
179-
180-
## See also
99+
## See Also
181100

182-
- [Client](./client.md) — high-level bot loop that owns a `BotApi`.
183-
- [Context](./context.md) — request-scoped wrapper exposing the same routes during event handling.
184-
- [Models](./models/messages.md) — request and response struct definitions.
185-
- [Token](./token.md) — credential management and refresh.
101+
- [Context](./context.md)
102+
- [Messages](./models/messages.md)
103+
- [Other types](./models/other-types.md)

0 commit comments

Comments
 (0)