use async_std::future::pending; use futures::{channel::oneshot::Sender, future::BoxFuture, lock::Mutex, Sink, StreamExt}; use std::{collections::HashMap, sync::Arc}; use telegram_bot::{ self, requests, Api, CallbackQuery, ChatRef, InlineKeyboardButton, InlineKeyboardMarkup, SendMessage, Update, UpdateKind, }; use uuid::Uuid; use super::Selector; pub struct TelegramSelector { client: Arc, chat_ref: Arc>, pending: Arc>>>, } impl TelegramSelector { pub fn new(api: Arc, chat_ref: Arc>) -> Self { let pending: Arc>>> = Arc::new(Mutex::new(HashMap::new())); let stream = api.clone(); let pending_clone = pending.clone(); smol::spawn(async move { let stream = stream.stream(); while let Some(Ok(Update { kind: UpdateKind::CallbackQuery(CallbackQuery { data: Some(query), .. }), .. })) = stream.next().await { let uuid_bytes = query.as_bytes().get(0..32); let bool_byte = query.as_bytes().get(32); if let (Some(uuid), Some(keep)) = (uuid_bytes, bool_byte) { let uuid = Uuid::parse_str(&String::from_utf8_lossy(uuid)); if let Ok(uuid) = uuid { if let Some(sender) = pending_clone.lock().await.get(&uuid) { sender.send(match *keep as char { 't' => true, _ => false, }); } } } } }); Self { client: api, chat_ref: chat_ref, pending: pending, } } } impl Selector for TelegramSelector { type Error = telegram_bot::Error; type Response = BoxFuture<'static, Result>; fn review(&self, message: String) -> Self::Response { let client = self.client.clone(); let chat_ref = self.chat_ref.clone(); let pending = self.pending.clone(); Box::pin(async move { let chat_ref = chat_ref.lock().await.clone(); let message = SendMessage::new(chat_ref, message).reply_markup( InlineKeyboardMarkup::new().add_row(vec![InlineKeyboardButton::callback("Keep")]), ); }) } // /setmain }