ask_phone_bot/
ask-phone-bot.rs1use maxbot::{Dispatcher, MaxClient, Attachment, InlineKeyboardButton, InlineKeyboardBuilder, SendMessageParamsBuilder};
5use maxbot::vcard::parse_vcard;
6use std::env;
7
8#[tokio::main]
9async fn main() -> Result<(), Box<dyn std::error::Error>> {
10 let token = env::var("MAXBOT_TOKEN").expect("MAXBOT_TOKEN not set");
11 let real_token = env::var("MAXBOT_REAL_TOKEN").unwrap_or_else(|_| token.clone());
12
13 let mut check_hash = true;
14 let mut client = MaxClient::new(token);
15 if let Ok(proxy_url) = env::var("MAXBOT_PROXY") {
16 client.set_base_url(proxy_url);
17 if real_token.starts_with("Basic ") {
18 check_hash = false;
19 }
20 }
21
22 if !check_hash {
23 println!("Токен бота подменён. Требуется указать MAXBOT_REAL_TOKEN для проверки номера телефона.");
24 }
25
26 let bot = client;
27 let mut dp = Dispatcher::new(bot);
28
29 dp.on_command("/start", |ctx| async move {
31 let chat_id = ctx.chat_id().unwrap();
32 let keyboard = InlineKeyboardBuilder::new()
33 .button(InlineKeyboardButton::request_contact("Передать 🔀"))
34 .build()?;
35 let body = SendMessageParamsBuilder::new()
36 .text("Предоставьте свои данные")
37 .chat_id(chat_id)
38 .attachment(Attachment::inline_keyboard(keyboard))
39 .build();
40 ctx.bot().send_message(body).await?;
41 Ok(())
42 });
43
44 let check_bytes = real_token.into_bytes();
46
47 dp.on_message(move |ctx| {
49 let token_bytes = check_bytes.clone();
50 async move {
51 let msg = match ctx.message() {
52 Some(m) => m,
53 None => return Ok(()),
54 };
55 let attachments = match &msg.body {
56 Some(b) => &b.attachments,
57 None => return Ok(()),
58 };
59 for att in attachments {
60 if let maxbot::AttachmentData::Contact { payload } = att {
61 let mut response = String::from("Вы предоставили следующую информацию:\n");
62 let mut has_phone = false;
63
64 if let Some(vcf) = &payload.vcf_info {
66 match parse_vcard(vcf) {
67 Ok(card) => {
68 if let Some(fn_) = card.get_formatted_name() {
69 response.push_str(&format!("Имя: {}\n", fn_));
70 }
71 for phone in card.get_phone_numbers() {
72 response.push_str(&format!("Телефон: {}\n", phone));
73 has_phone = !phone.is_empty();
74 }
75 for email in card.get_emails() {
76 response.push_str(&format!("Email: {}\n", email));
77 }
78 }
79 Err(e) => response.push_str(&format!("Ошибка чтения vCard: {}\n", e)),
80 }
81 } else {
82 if let Some(name) = &payload.name {
83 response.push_str(&format!("Имя: {}\n", name));
84 }
85 if let Some(phone) = &payload.vcf_phone {
86 response.push_str(&format!("Телефон: {}\n", phone));
87 has_phone = !phone.is_empty();
88 }
89 }
90
91 if check_hash && has_phone {
93 if payload.verify_hash(&token_bytes) {
94 response.push_str("✅ Номер телефона подтверждён.\n");
95 } else {
96 response.push_str("❌ Номер телефона не подтверждён.\n");
97 }
98 }
99
100 ctx.reply_text(&response).await?;
101 return Ok(());
102 }
103 }
104 Ok(())
105 }
106 });
107
108 println!("Бот запущен. Отправьте команду /start для запроса контактных данных.");
109 dp.start_polling().await;
110 Ok(())
111}