izzilis/src/selection/telegram.rs

74 lines
2.5 KiB
Rust

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<Api>,
chat_ref: Arc<Mutex<ChatRef>>,
pending: Arc<Mutex<HashMap<Uuid, Sender<bool>>>>,
}
impl TelegramSelector {
pub fn new(api: Arc<Api>, chat_ref: Arc<Mutex<ChatRef>>) -> Self {
let pending: Arc<Mutex<HashMap<Uuid, Sender<bool>>>> = 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<bool, Self::Error>>;
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
}