video_info_bot/
video-info-bot.rs1use maxbot::{Dispatcher, MaxClient, SendMessageParamsBuilder};
13use std::time::Duration;
14use tokio::time::timeout;
15
16#[tokio::main]
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18 let bot = MaxClient::from_env().expect("MAXBOT_TOKEN not set");
19 let mut dp = Dispatcher::new(bot);
20
21 dp.on_command("/start", |ctx| async move {
22 ctx.reply_markdown("Отправьте мне любое видео, и я расскажу о нём всё, что знаю! 🎬").await?;
23 Ok(())
24 });
25
26 dp.on_message(|ctx| async move {
27 let chat_id = ctx.chat_id().unwrap();
28
29 let video_token = {
31 let msg = match ctx.message() {
32 Some(m) => m,
33 None => return Ok(()),
34 };
35 let body = match &msg.body {
36 Some(b) => b,
37 None => return Ok(()),
38 };
39 let mut token = None;
40 for att in &body.attachments {
41 if let maxbot::AttachmentData::Video { payload } = att {
42 if let Some(tok) = &payload.token {
43 token = Some(tok.clone());
44 break;
45 }
46 }
47 }
48 token
49 };
50
51 let video_token = match video_token {
52 Some(tok) => tok,
53 None => {
54 ctx.reply_text("Это не видео (не удалось найти видео-вложение).").await?;
55 return Ok(());
56 }
57 };
58
59 let info = match timeout(Duration::from_secs(5), ctx.bot().get_video_info(&video_token)).await {
61 Ok(Ok(i)) => i,
62 Ok(Err(e)) => {
63 ctx.reply_text(&format!("Ошибка получения информации: {}", e)).await?;
64 return Ok(());
65 }
66 Err(_) => {
67 ctx.reply_text("Сервер MAX не ответил вовремя.").await?;
68 return Ok(());
69 }
70 };
71
72 let duration_secs = info.duration / 1000;
74 let duration = Duration::from_secs(duration_secs as u64);
75 let minutes = duration.as_secs() / 60;
76 let seconds = duration.as_secs() % 60;
77 let duration_str = if minutes > 0 {
78 format!("{} мин {} сек", minutes, seconds)
79 } else {
80 format!("{} сек", seconds)
81 };
82
83 let mut available_qualities = Vec::new();
85 let quality_map = [
86 ("mp4_1080", "1080p"),
87 ("mp4_720", "720p"),
88 ("mp4_480", "480p"),
89 ("mp4_360", "360p"),
90 ("mp4_240", "240p"),
91 ("mp4_144", "144p"),
92 ("hls", "HLS"),
93 ];
94 for (key, name) in quality_map.iter() {
95 if info.urls.contains_key(*key) {
96 available_qualities.push(*name);
97 }
98 }
99 let qualities_text = if available_qualities.is_empty() {
100 "неизвестно".to_string()
101 } else {
102 available_qualities.join(", ")
103 };
104
105 let text = format!(
106 "🎥 **Информация о видео**\n\n\
107 📐 Разрешение: {}×{}\n\
108 ⏱ Длительность: {}\n\
109 🎞 Качество: {}",
110 info.width, info.height,
111 duration_str,
112 qualities_text
113 );
114
115 let builder = SendMessageParamsBuilder::new()
116 .text(&text)
117 .chat_id(chat_id)
118 .format_markdown();
119 if let Err(e) = ctx.bot().send_message_builder(builder).await {
120 eprintln!("Ошибка отправки сообщения: {}", e);
121 }
122 Ok(())
123 });
124
125 println!("🎬 Видео-бот запущен. Отправьте видео, чтобы получить информацию.");
126 dp.start_polling().await;
127 Ok(())
128}