Skip to main content

onebot_api/message/
send_segment.rs

1use super::utils::*;
2use serde::Serialize;
3
4pub trait SendSegmentData: Clone + Serialize {
5	fn into_send_segment(self) -> SendSegment;
6}
7
8impl<T: SendSegmentData> From<T> for SendSegment {
9	fn from(value: T) -> Self {
10		value.into_send_segment()
11	}
12}
13
14#[derive(Serialize, Debug, Clone)]
15#[serde(tag = "type")]
16pub enum SendSegment {
17	#[serde(rename = "text")]
18	Text { data: TextData },
19
20	#[serde(rename = "face")]
21	Face { data: FaceData },
22
23	#[serde(rename = "image")]
24	Image { data: ImageData },
25
26	#[serde(rename = "record")]
27	Record { data: RecordData },
28
29	#[serde(rename = "video")]
30	Video { data: VideoData },
31
32	#[serde(rename = "at")]
33	At { data: AtData },
34
35	#[serde(rename = "rps")]
36	Rps { data: RpsData },
37
38	#[serde(rename = "dice")]
39	Dice { data: DiceData },
40
41	#[serde(rename = "shake")]
42	Shake { data: ShakeData },
43
44	#[serde(rename = "poke")]
45	Poke { data: PokeData },
46
47	#[serde(rename = "anonymous")]
48	Anonymous { data: AnonymousData },
49
50	#[serde(rename = "share")]
51	Share { data: ShareData },
52
53	#[serde(rename = "contact")]
54	Contact { data: ContactData },
55
56	#[serde(rename = "location")]
57	Location { data: LocationData },
58
59	#[serde(rename = "music")]
60	Music { data: MusicData },
61
62	#[serde(rename = "reply")]
63	Reply { data: ReplyData },
64
65	#[serde(rename = "forward")]
66	Forward { data: ForwardData },
67
68	#[serde(rename = "node")]
69	Node { data: NodeData },
70
71	#[serde(rename = "xml")]
72	Xml { data: XmlData },
73
74	#[serde(rename = "json")]
75	Json { data: JsonData },
76}
77
78#[derive(Serialize, Debug, Clone)]
79pub struct TextData {
80	/// # 说明
81	/// 纯文本内容
82	pub text: String,
83}
84
85impl SendSegmentData for TextData {
86	fn into_send_segment(self) -> SendSegment {
87		SendSegment::Text { data: self }
88	}
89}
90
91#[derive(Serialize, Debug, Clone)]
92pub struct FaceData {
93	/// # 说明
94	/// QQ 表情 ID
95	/// # 可能的值
96	/// 见 [QQ 表情 ID 表](https://github.com/richardchien/coolq-http-api/wiki/%E8%A1%A8%E6%83%85-CQ-%E7%A0%81-ID-%E8%A1%A8)
97	pub id: String,
98}
99
100impl SendSegmentData for FaceData {
101	fn into_send_segment(self) -> SendSegment {
102		SendSegment::Face { data: self }
103	}
104}
105
106#[derive(Serialize, Debug, Clone)]
107pub struct ImageData {
108	/// # 说明
109	/// 图片文件名
110	/// # TIPS
111	/// 发送时,`file` 参数除了支持使用收到的图片文件名直接发送外,还支持:
112	/// - 绝对路径,例如 `file:///C:\\Users\Richard\Pictures\1.png`,格式使用 [`file` URI](https://tools.ietf.org/html/rfc8089)
113	/// - 网络 URL,例如 `http://i1.piimg.com/567571/fdd6e7b6d93f1ef0.jpg`
114	/// - Base64 编码,例如 `base64://iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAKElEQVQ4EWPk5+RmIBcwkasRpG9UM4mhNxpgowFGMARGEwnBIEJVAAAdBgBNAZf+QAAAAABJRU5ErkJggg==`
115	pub file: String,
116	#[serde(rename = "type")]
117	/// # 说明
118	/// 图片类型,`flash` 表示闪照,无此参数表示普通图片
119	/// # 可能的值
120	/// `flash`
121	pub image_type: Option<ImageType>,
122	/// # 说明
123	/// 只在通过网络 URL 发送时有效,表示是否使用已缓存的文件,默认 `1`
124	/// # 可能的值
125	/// `0` `1`
126	pub cache: Option<bool>,
127	/// # 说明
128	/// 只在通过网络 URL 发送时有效,表示是否通过代理下载文件(需通过环境变量或配置文件配置代理),默认 `1`
129	/// # 可能的值
130	/// `0` `1`
131	pub proxy: Option<bool>,
132	/// # 说明
133	/// 只在通过网络 URL 发送时有效,单位秒,表示下载网络文件的超时时间,默认不超时
134	pub timeout: Option<i32>,
135}
136
137impl SendSegmentData for ImageData {
138	fn into_send_segment(self) -> SendSegment {
139		SendSegment::Image { data: self }
140	}
141}
142
143#[derive(Serialize, Debug, Clone)]
144pub struct RecordData {
145	/// # 说明
146	/// 语音文件名
147	/// # TIPS
148	/// 发送时,`file` 参数除了支持使用收到的语音文件名直接发送外,还支持其它形式,参考 [`ImageData::file`]。
149	pub file: String,
150	/// # 说明
151	/// 发送时可选,默认 `0`,设置为 `1` 表示变声
152	/// # 可能的值
153	/// `0` `1`
154	pub magic: Option<String>,
155	/// # 说明
156	/// 只在通过网络 URL 发送时有效,表示是否使用已缓存的文件,默认 `1`
157	/// # 可能的值
158	/// `0` `1`
159	pub cache: Option<bool>,
160	/// # 说明
161	/// 只在通过网络 URL 发送时有效,表示是否通过代理下载文件(需通过环境变量或配置文件配置代理),默认 `1`
162	/// # 可能的值
163	/// `0` `1`
164	pub proxy: Option<bool>,
165	/// # 说明
166	/// 只在通过网络 URL 发送时有效,单位秒,表示下载网络文件的超时时间,默认不超时
167	pub timeout: Option<i32>,
168}
169
170impl SendSegmentData for RecordData {
171	fn into_send_segment(self) -> SendSegment {
172		SendSegment::Record { data: self }
173	}
174}
175
176#[derive(Serialize, Debug, Clone)]
177pub struct VideoData {
178	/// # 说明
179	/// 视频文件名
180	/// # TIPS
181	/// 发送时,`file` 参数除了支持使用收到的语音文件名直接发送外,还支持其它形式,参考 [`ImageData::file`]。
182	pub file: String,
183	/// # 说明
184	/// 只在通过网络 URL 发送时有效,表示是否使用已缓存的文件,默认 `1`
185	/// # 可能的值
186	/// `0` `1`
187	pub cache: Option<bool>,
188	/// # 说明
189	/// 只在通过网络 URL 发送时有效,表示是否通过代理下载文件(需通过环境变量或配置文件配置代理),默认 `1`
190	/// # 可能的值
191	/// `0` `1`
192	pub proxy: Option<bool>,
193	/// # 说明
194	/// 只在通过网络 URL 发送时有效,单位秒,表示下载网络文件的超时时间,默认不超时
195	pub timeout: Option<i32>,
196}
197
198impl SendSegmentData for VideoData {
199	fn into_send_segment(self) -> SendSegment {
200		SendSegment::Video { data: self }
201	}
202}
203
204#[derive(Serialize, Debug, Clone)]
205pub struct AtData {
206	/// # 说明
207	/// @的 QQ 号,`all` 表示全体成员
208	/// # 可能的值
209	/// QQ 号、`all`
210	pub qq: AtType,
211}
212
213impl SendSegmentData for AtData {
214	fn into_send_segment(self) -> SendSegment {
215		SendSegment::At { data: self }
216	}
217}
218
219#[derive(Serialize, Debug, Clone)]
220pub struct RpsData {}
221
222impl SendSegmentData for RpsData {
223	fn into_send_segment(self) -> SendSegment {
224		SendSegment::Rps { data: self }
225	}
226}
227
228#[derive(Serialize, Debug, Clone)]
229pub struct DiceData {}
230
231impl SendSegmentData for DiceData {
232	fn into_send_segment(self) -> SendSegment {
233		SendSegment::Dice { data: self }
234	}
235}
236
237#[derive(Serialize, Debug, Clone)]
238pub struct ShakeData {}
239
240impl SendSegmentData for ShakeData {
241	fn into_send_segment(self) -> SendSegment {
242		SendSegment::Shake { data: self }
243	}
244}
245
246#[derive(Serialize, Debug, Clone)]
247pub struct PokeData {
248	#[serde(rename = "type")]
249	/// # 说明
250	/// 类型
251	/// # 可能的值
252	/// 见 [Mirai 的 PokeMessage 类](https://github.com/mamoe/mirai/blob/f5eefae7ecee84d18a66afce3f89b89fe1584b78/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/HummerMessage.kt#L49)
253	pub poke_type: String,
254	/// # 说明
255	/// ID
256	/// # 可能的值
257	/// 同上
258	pub id: String,
259}
260
261impl SendSegmentData for PokeData {
262	fn into_send_segment(self) -> SendSegment {
263		SendSegment::Poke { data: self }
264	}
265}
266
267#[derive(Serialize, Debug, Clone)]
268pub struct AnonymousData {
269	/// # 说明
270	/// 可选,表示无法匿名时是否继续发送
271	/// # 可能的值
272	/// `0` `1`
273	pub ignore: Option<bool>,
274}
275
276impl SendSegmentData for AnonymousData {
277	fn into_send_segment(self) -> SendSegment {
278		SendSegment::Anonymous { data: self }
279	}
280}
281
282#[derive(Serialize, Debug, Clone)]
283pub struct ShareData {
284	/// # 说明
285	/// URL
286	pub url: String,
287	/// # 说明
288	/// 标题
289	pub title: String,
290	/// # 说明
291	/// 发送时可选,内容描述
292	pub content: String,
293	/// # 说明
294	/// 发送时可选,图片 URL
295	pub image: String,
296}
297
298impl SendSegmentData for ShareData {
299	fn into_send_segment(self) -> SendSegment {
300		SendSegment::Share { data: self }
301	}
302}
303
304#[derive(Serialize, Debug, Clone)]
305pub struct ContactData {
306	#[serde(rename = "type")]
307	/// # 说明
308	/// 推荐好友/群
309	pub contact_type: ContactType,
310	/// # 说明
311	/// 被推荐人的 QQ 号/被推荐群的群号
312	pub id: String,
313}
314
315impl SendSegmentData for ContactData {
316	fn into_send_segment(self) -> SendSegment {
317		SendSegment::Contact { data: self }
318	}
319}
320
321#[derive(Serialize, Debug, Clone)]
322pub struct LocationData {
323	/// # 说明
324	/// 纬度
325	pub lat: String,
326	/// # 说明
327	/// 经度
328	pub lon: String,
329	/// # 说明
330	/// 发送时可选,标题
331	pub title: Option<String>,
332	/// # 说明
333	/// 发送时可选,内容描述
334	pub content: Option<String>,
335}
336
337impl SendSegmentData for LocationData {
338	fn into_send_segment(self) -> SendSegment {
339		SendSegment::Location { data: self }
340	}
341}
342
343#[derive(Serialize, Debug, Clone)]
344pub struct MusicData {
345	#[serde(rename = "type")]
346	/// # 说明
347	/// 分别表示使用 QQ 音乐、网易云音乐、虾米音乐 / 表示音乐自定义分享
348	/// # 可能的值
349	/// `qq` `163` `xm` `custom`
350	pub music_type: MusicType,
351	/// # 说明
352	/// 歌曲 ID
353	pub id: Option<String>,
354	/// # 说明
355	/// 点击后跳转目标 URL
356	pub url: Option<String>,
357	/// # 说明
358	/// 音乐 URL
359	pub audio: Option<String>,
360	/// # 说明
361	/// 标题
362	pub title: Option<String>,
363	/// # 说明
364	/// 发送时可选,内容描述
365	pub content: Option<String>,
366	/// # 说明
367	/// 发送时可选,图片 URL
368	pub image: Option<String>,
369}
370
371impl SendSegmentData for MusicData {
372	fn into_send_segment(self) -> SendSegment {
373		SendSegment::Music { data: self }
374	}
375}
376
377#[derive(Serialize, Debug, Clone)]
378pub struct ReplyData {
379	/// # 说明
380	/// 回复时引用的消息 ID
381	pub id: String,
382}
383
384impl SendSegmentData for ReplyData {
385	fn into_send_segment(self) -> SendSegment {
386		SendSegment::Reply { data: self }
387	}
388}
389
390#[derive(Serialize, Debug, Clone)]
391pub struct ForwardData {}
392
393impl SendSegmentData for ForwardData {
394	fn into_send_segment(self) -> SendSegment {
395		SendSegment::Forward { data: self }
396	}
397}
398
399#[derive(Serialize, Debug, Clone)]
400pub struct NodeData {
401	/// # 说明
402	/// 转发的消息 ID
403	pub id: Option<String>,
404	/// # 说明
405	/// 发送者 QQ 号
406	pub user_id: Option<String>,
407	/// # 说明
408	/// 发送者昵称
409	pub nickname: Option<String>,
410	/// # 说明
411	/// 消息内容,支持发送消息时的 `message` 数据类型,见 [API 的参数](https://github.com/botuniverse/onebot-11/blob/master/api/#%E5%8F%82%E6%95%B0)
412	pub content: Option<Vec<SendSegment>>,
413}
414
415impl SendSegmentData for NodeData {
416	fn into_send_segment(self) -> SendSegment {
417		SendSegment::Node { data: self }
418	}
419}
420
421#[derive(Serialize, Debug, Clone)]
422pub struct XmlData {
423	/// # 说明
424	/// XML 内容
425	pub data: String,
426}
427
428impl SendSegmentData for XmlData {
429	fn into_send_segment(self) -> SendSegment {
430		SendSegment::Xml { data: self }
431	}
432}
433
434#[derive(Serialize, Debug, Clone)]
435pub struct JsonData {
436	/// 说明
437	/// JSON 内容
438	pub data: String,
439}
440
441impl SendSegmentData for JsonData {
442	fn into_send_segment(self) -> SendSegment {
443		SendSegment::Json { data: self }
444	}
445}