linkleaner/src/main.rs

129 lines
3.9 KiB
Rust

#![feature(let_chains)]
mod commands;
mod deamp;
mod fixer;
#[cfg(feature = "ddinstagram")]
mod instagram;
mod logging;
mod medium;
mod message;
mod twitter;
mod utils;
mod youtube;
use crate::commands::Command;
use crate::logging::TeloxideLogger;
use dotenvy::dotenv;
use fixer::FixerState;
use once_cell::sync::Lazy;
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
use teloxide::{
dispatching::{dialogue::GetChatId, HandlerExt, UpdateFilterExt},
dptree,
prelude::Dispatcher,
types::{ChatId, Message, Update},
update_listeners::Polling,
Bot,
};
use utils::has_matching_urls;
pub(crate) static FIXER_STATE: Lazy<Mutex<HashMap<ChatId, FixerState>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
const REPLACE_SKIP_TOKEN: &str = "#skip";
async fn run() {
if let Err(e) = logging::init() {
eprintln!("{e}");
return;
};
dotenv().ok();
let bot = Bot::from_env();
let handler = Update::filter_message()
.branch(
dptree::entry()
.filter_command::<Command>()
.endpoint(commands::handler),
)
.branch(
dptree::filter(|msg: Message| {
let should_match = has_matching_urls(&msg, &twitter::DOMAINS)
&& !msg.text().unwrap_or_default().contains(REPLACE_SKIP_TOKEN);
if should_match
&& let Ok(ref mut map) = FIXER_STATE.try_lock()
&& let Some(chat_id) = msg.chat_id()
{
return map.entry(chat_id).or_insert(FixerState::default()).twitter;
}
false
})
.endpoint(twitter::handler),
);
#[cfg(feature = "ddinstagram")]
let handler = handler.branch(
dptree::filter(|msg: Message| {
let should_match = has_matching_urls(&msg, &instagram::DOMAINS)
&& !msg.text().unwrap_or_default().contains(REPLACE_SKIP_TOKEN);
if should_match
&& let Ok(ref mut map) = FIXER_STATE.try_lock()
&& let Some(chat_id) = msg.chat_id()
{
return map
.entry(chat_id)
.or_insert(FixerState::default())
.instagram;
}
false
})
.endpoint(instagram::handler),
);
let handler = handler.branch(
dptree::filter(|msg: Message| {
let should_match = has_matching_urls(&msg, &youtube::DOMAINS)
&& !msg.text().unwrap_or_default().contains(REPLACE_SKIP_TOKEN);
if should_match
&& let Ok(ref mut map) = FIXER_STATE.try_lock()
&& let Some(chat_id) = msg.chat_id()
{
return map.entry(chat_id).or_insert(FixerState::default()).youtube;
}
false
})
.endpoint(youtube::handler),
);
let handler = handler.branch(
dptree::filter(|msg: Message| {
let should_match = has_matching_urls(&msg, &medium::DOMAINS);
let should_match =
should_match && !msg.text().unwrap_or_default().contains(REPLACE_SKIP_TOKEN);
if should_match
&& let Ok(ref mut map) = FIXER_STATE.try_lock()
&& let Some(chat_id) = msg.chat_id()
{
return map.entry(chat_id).or_insert(FixerState::default()).medium;
}
false
})
.endpoint(medium::handler),
);
let handler = handler.branch(dptree::filter(deamp::is_amp).endpoint(deamp::handler));
let error_handler = Arc::new(TeloxideLogger::default());
let listener = Polling::builder(bot.clone()).drop_pending_updates().build();
Dispatcher::builder(bot, handler)
.enable_ctrlc_handler()
.build()
.dispatch_with_listener(listener, error_handler)
.await;
}
#[tokio::main]
async fn main() {
run().await;
}