Skip to main content

vk_bot_api/
models.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5/// Main update type from VK
6#[derive(Debug, Clone, Deserialize, Serialize)]
7pub struct Update {
8    /// Update type
9    #[serde(rename = "type")]
10    pub update_type: String,
11    /// Update object
12    pub object: Value,
13    /// Group ID
14    pub group_id: i64,
15    /// Event ID (for callbacks)
16    #[serde(default)]
17    pub event_id: Option<String>,
18}
19
20/// Event types
21#[derive(Debug, Clone)]
22pub enum Event {
23    /// New message
24    MessageNew(Message),
25    /// Message edited
26    MessageEdit(Message),
27    /// Message reply
28    MessageReply(Message),
29    /// Message allow
30    MessageAllow(MessageAllow),
31    /// Message deny
32    MessageDeny(MessageDeny),
33    /// Message typing state
34    MessageTypingState(MessageTypingState),
35    /// Message event (callback)
36    MessageEvent(MessageEvent),
37    /// Unknown event
38    Unknown(String, Value),
39}
40
41impl Event {
42    /// Convert update to event
43    pub fn from_update(update: &Update) -> Self {
44        match update.update_type.as_str() {
45            "message_new" => {
46                if let Ok(message) = serde_json::from_value(update.object["message"].clone()) {
47                    Event::MessageNew(message)
48                } else {
49                    Event::Unknown(update.update_type.clone(), update.object.clone())
50                }
51            }
52            "message_edit" => {
53                if let Ok(message) = serde_json::from_value(update.object.clone()) {
54                    Event::MessageEdit(message)
55                } else {
56                    Event::Unknown(update.update_type.clone(), update.object.clone())
57                }
58            }
59            "message_reply" => {
60                if let Ok(message) = serde_json::from_value(update.object.clone()) {
61                    Event::MessageReply(message)
62                } else {
63                    Event::Unknown(update.update_type.clone(), update.object.clone())
64                }
65            }
66            "message_allow" => {
67                if let Ok(message_allow) = serde_json::from_value(update.object.clone()) {
68                    Event::MessageAllow(message_allow)
69                } else {
70                    Event::Unknown(update.update_type.clone(), update.object.clone())
71                }
72            }
73            "message_deny" => {
74                if let Ok(message_deny) = serde_json::from_value(update.object.clone()) {
75                    Event::MessageDeny(message_deny)
76                } else {
77                    Event::Unknown(update.update_type.clone(), update.object.clone())
78                }
79            }
80            "message_typing_state" => {
81                if let Ok(typing_state) = serde_json::from_value(update.object.clone()) {
82                    Event::MessageTypingState(typing_state)
83                } else {
84                    Event::Unknown(update.update_type.clone(), update.object.clone())
85                }
86            }
87            "message_event" => {
88                if let Ok(message_event) = serde_json::from_value(update.object.clone()) {
89                    Event::MessageEvent(message_event)
90                } else {
91                    Event::Unknown(update.update_type.clone(), update.object.clone())
92                }
93            }
94            _ => Event::Unknown(update.update_type.clone(), update.object.clone()),
95        }
96    }
97}
98
99/// Message structure
100#[derive(Debug, Clone, Deserialize, Serialize)]
101pub struct Message {
102    /// Message ID
103    pub id: i64,
104    /// Sender ID
105    pub from_id: i64,
106    /// Message text
107    pub text: String,
108    /// Peer ID (user/chat ID)
109    pub peer_id: i64,
110    /// Conversation message ID
111    #[serde(default)]
112    pub conversation_message_id: Option<i64>,
113    /// Date of sending (Unix timestamp)
114    pub date: i64,
115    /// Message attachments
116    #[serde(default)]
117    pub attachments: Vec<Attachment>,
118    /// Reply message (if any)
119    #[serde(default)]
120    pub reply_message: Option<Box<Message>>,
121    /// Forwarded messages
122    #[serde(default)]
123    pub fwd_messages: Vec<Message>,
124    /// Important flag
125    #[serde(default)]
126    pub important: bool,
127    /// Random ID
128    #[serde(default)]
129    pub random_id: Option<i64>,
130    /// Payload (for buttons)
131    #[serde(default)]
132    pub payload: Option<String>,
133    /// Geo location
134    #[serde(default)]
135    pub geo: Option<Geo>,
136    /// Action (for chat actions)
137    #[serde(default)]
138    pub action: Option<Action>,
139}
140
141/// Message action (for chat events)
142#[derive(Debug, Clone, Deserialize, Serialize)]
143pub struct Action {
144    /// Action type
145    #[serde(rename = "type")]
146    pub action_type: String,
147    /// Member ID (for chat_invite_user, chat_kick_user)
148    #[serde(default)]
149    pub member_id: Option<i64>,
150    /// Text (for chat_title_update)
151    #[serde(default)]
152    pub text: Option<String>,
153    /// Email (for chat_invite_user_by_link)
154    #[serde(default)]
155    pub email: Option<String>,
156}
157
158/// Geo location
159#[derive(Debug, Clone, Deserialize, Serialize)]
160pub struct Geo {
161    /// Place ID
162    #[serde(default)]
163    pub place: Option<Place>,
164    /// Coordinates
165    pub coordinates: Coordinates,
166}
167
168/// Place information
169#[derive(Debug, Clone, Deserialize, Serialize)]
170pub struct Place {
171    /// Place ID
172    pub id: i64,
173    /// Title
174    pub title: String,
175    /// Latitude
176    pub latitude: f64,
177    /// Longitude
178    pub longitude: f64,
179    /// Created timestamp
180    pub created: i64,
181    /// Icon URL
182    #[serde(default)]
183    pub icon: Option<String>,
184    /// Country
185    #[serde(default)]
186    pub country: Option<String>,
187    /// City
188    #[serde(default)]
189    pub city: Option<String>,
190}
191
192/// Coordinates
193#[derive(Debug, Clone, Deserialize, Serialize)]
194pub struct Coordinates {
195    /// Latitude
196    pub latitude: f64,
197    /// Longitude
198    pub longitude: f64,
199}
200
201/// Message allow event
202#[derive(Debug, Clone, Deserialize, Serialize)]
203pub struct MessageAllow {
204    /// User ID
205    pub user_id: i64,
206    /// Key
207    pub key: String,
208}
209
210/// Message deny event
211#[derive(Debug, Clone, Deserialize, Serialize)]
212pub struct MessageDeny {
213    /// User ID
214    pub user_id: i64,
215}
216
217/// Message typing state event
218#[derive(Debug, Clone, Deserialize, Serialize)]
219pub struct MessageTypingState {
220    /// User ID
221    pub user_id: i64,
222    /// Peer ID
223    pub peer_id: i64,
224    /// State
225    pub state: String,
226}
227
228/// Message callback event
229#[derive(Debug, Clone, Deserialize, Serialize)]
230pub struct MessageEvent {
231    /// User ID
232    pub user_id: i64,
233    /// Peer ID
234    pub peer_id: i64,
235    /// Event ID
236    pub event_id: String,
237    /// Payload
238    #[serde(default)]
239    pub payload: Option<HashMap<String, Value>>,
240    /// Conversation message ID
241    #[serde(default)]
242    pub conversation_message_id: Option<i64>,
243}
244
245/// Message attachment
246#[derive(Debug, Clone, Deserialize, Serialize)]
247pub struct Attachment {
248    /// Attachment type
249    #[serde(rename = "type")]
250    pub attachment_type: String,
251    /// Photo
252    #[serde(default)]
253    pub photo: Option<Photo>,
254    /// Video
255    #[serde(default)]
256    pub video: Option<Video>,
257    /// Audio
258    #[serde(default)]
259    pub audio: Option<Audio>,
260    /// Document
261    #[serde(default)]
262    pub doc: Option<Document>,
263    /// Link
264    #[serde(default)]
265    pub link: Option<Link>,
266    /// Market item
267    #[serde(default)]
268    pub market: Option<Market>,
269    /// Market album
270    #[serde(default)]
271    pub market_album: Option<MarketAlbum>,
272    /// Wall post
273    #[serde(default)]
274    pub wall: Option<WallPost>,
275    /// Wall reply
276    #[serde(default)]
277    pub wall_reply: Option<WallReply>,
278    /// Sticker
279    #[serde(default)]
280    pub sticker: Option<Sticker>,
281    /// Gift
282    #[serde(default)]
283    pub gift: Option<Gift>,
284    /// Poll
285    #[serde(default)]
286    pub poll: Option<Poll>,
287    /// Audio message
288    #[serde(default)]
289    pub audio_message: Option<AudioMessage>,
290}
291
292/// Photo attachment
293#[derive(Debug, Clone, Deserialize, Serialize)]
294pub struct Photo {
295    /// Photo ID
296    pub id: i64,
297    /// Owner ID
298    pub owner_id: i64,
299    /// Access key
300    #[serde(default)]
301    pub access_key: Option<String>,
302    /// Photo sizes
303    pub sizes: Vec<PhotoSize>,
304    /// Text
305    #[serde(default)]
306    pub text: Option<String>,
307    /// Date
308    pub date: i64,
309    /// Width
310    #[serde(default)]
311    pub width: Option<i32>,
312    /// Height
313    #[serde(default)]
314    pub height: Option<i32>,
315}
316
317/// Photo size
318#[derive(Debug, Clone, Deserialize, Serialize)]
319pub struct PhotoSize {
320    /// Size type
321    #[serde(rename = "type")]
322    pub size_type: String,
323    /// URL
324    pub url: String,
325    /// Width
326    pub width: i32,
327    /// Height
328    pub height: i32,
329}
330
331/// Video attachment
332#[derive(Debug, Clone, Deserialize, Serialize)]
333pub struct Video {
334    /// Video ID
335    pub id: i64,
336    /// Owner ID
337    pub owner_id: i64,
338    /// Title
339    pub title: String,
340    /// Description
341    #[serde(default)]
342    pub description: Option<String>,
343    /// Duration
344    pub duration: i32,
345    /// Images
346    pub image: Vec<VideoImage>,
347    /// First frame images
348    #[serde(default)]
349    pub first_frame: Vec<VideoImage>,
350    /// Date
351    pub date: i64,
352    /// Views
353    #[serde(default)]
354    pub views: Option<i32>,
355    /// Comments
356    #[serde(default)]
357    pub comments: Option<i32>,
358    /// Access key
359    #[serde(default)]
360    pub access_key: Option<String>,
361    /// Player URL
362    #[serde(default)]
363    pub player: Option<String>,
364}
365
366/// Video image
367#[derive(Debug, Clone, Deserialize, Serialize)]
368pub struct VideoImage {
369    /// URL
370    pub url: String,
371    /// Width
372    pub width: i32,
373    /// Height
374    pub height: i32,
375}
376
377/// Audio attachment
378#[derive(Debug, Clone, Deserialize, Serialize)]
379pub struct Audio {
380    /// Audio ID
381    pub id: i64,
382    /// Owner ID
383    pub owner_id: i64,
384    /// Artist
385    pub artist: String,
386    /// Title
387    pub title: String,
388    /// Duration
389    pub duration: i32,
390    /// URL
391    #[serde(default)]
392    pub url: Option<String>,
393    /// Date
394    pub date: i64,
395    /// Album ID
396    #[serde(default)]
397    pub album_id: Option<i64>,
398    /// Genre ID
399    #[serde(default)]
400    pub genre_id: Option<i64>,
401}
402
403/// Document attachment
404#[derive(Debug, Clone, Deserialize, Serialize)]
405pub struct Document {
406    /// Document ID
407    pub id: i64,
408    /// Owner ID
409    pub owner_id: i64,
410    /// Title
411    pub title: String,
412    /// Size
413    pub size: i64,
414    /// Extension
415    pub ext: String,
416    /// URL
417    pub url: String,
418    /// Date
419    pub date: i64,
420    /// Type
421    #[serde(default)]
422    pub r#type: Option<i32>,
423    /// Preview
424    #[serde(default)]
425    pub preview: Option<DocumentPreview>,
426}
427
428/// Document preview
429#[derive(Debug, Clone, Deserialize, Serialize)]
430pub struct DocumentPreview {
431    /// Photo
432    #[serde(default)]
433    pub photo: Option<DocumentPreviewPhoto>,
434    /// Graffiti
435    #[serde(default)]
436    pub graffiti: Option<Graffiti>,
437    /// Audio message
438    #[serde(default)]
439    pub audio_message: Option<AudioMessage>,
440}
441
442/// Document preview photo
443#[derive(Debug, Clone, Deserialize, Serialize)]
444pub struct DocumentPreviewPhoto {
445    /// Sizes
446    pub sizes: Vec<PhotoSize>,
447}
448
449/// Graffiti
450#[derive(Debug, Clone, Deserialize, Serialize)]
451pub struct Graffiti {
452    /// Src
453    pub src: String,
454    /// Width
455    pub width: i32,
456    /// Height
457    pub height: i32,
458}
459
460/// Audio message
461#[derive(Debug, Clone, Deserialize, Serialize)]
462pub struct AudioMessage {
463    /// Duration
464    pub duration: i32,
465    /// Waveform
466    pub waveform: Vec<i32>,
467    /// Link OGG
468    pub link_ogg: String,
469    /// Link MP3
470    pub link_mp3: String,
471}
472
473/// Link attachment
474#[derive(Debug, Clone, Deserialize, Serialize)]
475pub struct Link {
476    /// URL
477    pub url: String,
478    /// Title
479    #[serde(default)]
480    pub title: Option<String>,
481    /// Caption
482    #[serde(default)]
483    pub caption: Option<String>,
484    /// Description
485    #[serde(default)]
486    pub description: Option<String>,
487    /// Photo
488    #[serde(default)]
489    pub photo: Option<Photo>,
490}
491
492/// Market item
493#[derive(Debug, Clone, Deserialize, Serialize)]
494pub struct Market {
495    /// Item ID
496    pub id: i64,
497    /// Owner ID
498    pub owner_id: i64,
499    /// Title
500    pub title: String,
501    /// Description
502    pub description: String,
503    /// Price
504    pub price: MarketPrice,
505    /// Photos
506    pub photos: Vec<Photo>,
507    /// Date
508    pub date: i64,
509    /// Access key
510    #[serde(default)]
511    pub access_key: Option<String>,
512}
513
514/// Market price
515#[derive(Debug, Clone, Deserialize, Serialize)]
516pub struct MarketPrice {
517    /// Amount
518    pub amount: String,
519    /// Currency
520    pub currency: Currency,
521    /// Text
522    pub text: String,
523}
524
525/// Currency
526#[derive(Debug, Clone, Deserialize, Serialize)]
527pub struct Currency {
528    /// Currency ID
529    pub id: i64,
530    /// Name
531    pub name: String,
532}
533
534/// Market album
535#[derive(Debug, Clone, Deserialize, Serialize)]
536pub struct MarketAlbum {
537    /// Album ID
538    pub id: i64,
539    /// Owner ID
540    pub owner_id: i64,
541    /// Title
542    pub title: String,
543    /// Photo
544    #[serde(default)]
545    pub photo: Option<Photo>,
546}
547
548/// Wall post
549#[derive(Debug, Clone, Deserialize, Serialize)]
550pub struct WallPost {
551    /// Post ID
552    pub id: i64,
553    /// Owner ID
554    pub owner_id: i64,
555    /// From ID
556    pub from_id: i64,
557    /// Date
558    pub date: i64,
559    /// Text
560    pub text: String,
561    /// Attachments
562    #[serde(default)]
563    pub attachments: Vec<Attachment>,
564}
565
566/// Wall reply
567#[derive(Debug, Clone, Deserialize, Serialize)]
568pub struct WallReply {
569    /// Reply ID
570    pub id: i64,
571    /// From ID
572    pub from_id: i64,
573    /// Date
574    pub date: i64,
575    /// Text
576    pub text: String,
577}
578
579/// Sticker
580#[derive(Debug, Clone, Deserialize, Serialize)]
581pub struct Sticker {
582    /// Product ID
583    pub product_id: i64,
584    /// Sticker ID
585    pub sticker_id: i64,
586    /// Images
587    pub images: Vec<StickerImage>,
588    /// Images with background
589    #[serde(default)]
590    pub images_with_background: Vec<StickerImage>,
591}
592
593/// Sticker image
594#[derive(Debug, Clone, Deserialize, Serialize)]
595pub struct StickerImage {
596    /// URL
597    pub url: String,
598    /// Width
599    pub width: i32,
600    /// Height
601    pub height: i32,
602}
603
604/// Gift
605#[derive(Debug, Clone, Deserialize, Serialize)]
606pub struct Gift {
607    /// Gift ID
608    pub id: i64,
609    /// Thumbnail 256px
610    pub thumb_256: String,
611    /// Thumbnail 96px
612    pub thumb_96: String,
613    /// Thumbnail 48px
614    pub thumb_48: String,
615}
616
617/// Poll
618#[derive(Debug, Clone, Deserialize, Serialize)]
619pub struct Poll {
620    /// Poll ID
621    pub id: i64,
622    /// Owner ID
623    pub owner_id: i64,
624    /// Created
625    pub created: i64,
626    /// Question
627    pub question: String,
628    /// Votes
629    pub votes: i64,
630    /// Answers
631    pub answers: Vec<PollAnswer>,
632    /// Anonymous
633    pub anonymous: bool,
634    /// Multiple
635    #[serde(default)]
636    pub multiple: Option<bool>,
637    /// End date
638    #[serde(default)]
639    pub end_date: Option<i64>,
640}
641
642/// Poll answer
643#[derive(Debug, Clone, Deserialize, Serialize)]
644pub struct PollAnswer {
645    /// Answer ID
646    pub id: i64,
647    /// Text
648    pub text: String,
649    /// Votes
650    pub votes: i64,
651    /// Rate
652    pub rate: f64,
653}