core/
lib.rs

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}