1mod cmd;
2pub mod config;
3mod db;
4mod handler;
5mod mastodon;
6mod util;
7
8use std::sync::Arc;
9
10use cmd::Command;
11use spdlog::prelude::*;
12use teloxide::{
13 prelude::*,
14 types::{Me, Update},
15 utils::command::BotCommands,
16};
17
18use crate::util::handle;
19
20pub struct InstanceState {
21 pub db: db::Pool,
22}
23
24impl InstanceState {
25 async fn new(db_url: impl AsRef<str>) -> anyhow::Result<Arc<Self>> {
26 Ok(Arc::new(Self {
27 db: db::Pool::connect(db_url).await?,
28 }))
29 }
30}
31
32pub async fn run(bot_token: impl Into<String>, db_url: impl AsRef<str>) -> anyhow::Result<()> {
33 let bot = Bot::new(bot_token);
34 let inst_state = InstanceState::new(db_url).await?;
35
36 bot.set_my_commands(Command::bot_commands()).await?;
37
38 let handler =
39 dptree::entry()
40 .branch(
41 Update::filter_message()
42 .inspect_async(
43 |state: Arc<InstanceState>, bot: Bot, me: Me, msg: Message| async move {
44 let req = handle::Request::new_message(state, bot, me, msg);
45 _ = handler::handle(req).await;
46 },
47 )
48 .branch(dptree::entry().filter_command::<Command>().endpoint(
49 |state: Arc<InstanceState>,
50 bot: Bot,
51 me: Me,
52 msg: Message,
53 cmd: Command| async move {
54 let req = handle::Request::new_command(state, bot, me, msg, cmd);
55 handler::handle(req).await
56 },
57 )),
58 )
59 .branch(Update::filter_edited_message().inspect_async(
60 |state: Arc<InstanceState>, bot: Bot, me: Me, msg: Message| async move {
61 let req = handle::Request::edited_message(state, bot, me, msg);
62 _ = handler::handle(req).await;
63 },
64 ));
65
66 Dispatcher::builder(bot, handler)
67 .dependencies(dptree::deps![inst_state])
68 .default_handler(|upd| async move {
69 debug!("unhandled update: {upd:?}");
70 })
71 .error_handler(Arc::new(
72 |err| async move { error!("dispatcher error: {err}") },
73 ))
74 .enable_ctrlc_handler()
75 .build()
76 .dispatch()
77 .await;
78
79 Ok(())
80}