Skip to main content

video_info_bot/
video-info-bot.rs

1//! Демо-бот «Информация о видео»
2//!
3//! Бот получает видеофайл, извлекает его токен,
4//! запрашивает метаданные через API MAX и отправляет сообщение с информацией.
5//!
6//! # Запуск
7//! ```bash
8//! export MAXBOT_TOKEN="ваш_токен"
9//! cargo run --example video-info-bot
10//! ```
11
12use 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        // Ищем видео вложение
30        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        // Получаем информацию с таймаутом
60        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        // Длительность приходит в миллисекундах
73        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        // Собираем доступные качества (без ссылок)
84        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}