tgbot-mastodon-sync 0.2.2

A Telegram bot synchronizes Telegram messages to Mastodon
Documentation
mod cmd;
pub mod config;
mod db;
mod handler;
mod mastodon;
mod util;

use std::sync::Arc;

use cmd::Command;
use spdlog::prelude::*;
use teloxide::{
    prelude::*,
    types::{Me, Update},
    utils::command::BotCommands,
};

use crate::util::handle;

pub struct InstanceState {
    pub db: db::Pool,
}

impl InstanceState {
    async fn new(db_url: impl AsRef<str>) -> anyhow::Result<Arc<Self>> {
        Ok(Arc::new(Self {
            db: db::Pool::connect(db_url).await?,
        }))
    }
}

pub async fn run(bot_token: impl Into<String>, db_url: impl AsRef<str>) -> anyhow::Result<()> {
    let bot = Bot::new(bot_token);
    let inst_state = InstanceState::new(db_url).await?;

    bot.set_my_commands(Command::bot_commands()).await?;

    let handler =
        dptree::entry()
            .branch(
                Update::filter_message()
                    .inspect_async(
                        |state: Arc<InstanceState>, bot: Bot, me: Me, msg: Message| async move {
                            let req = handle::Request::new_message(state, bot, me, msg);
                            _ = handler::handle(req).await;
                        },
                    )
                    .branch(dptree::entry().filter_command::<Command>().endpoint(
                        |state: Arc<InstanceState>,
                         bot: Bot,
                         me: Me,
                         msg: Message,
                         cmd: Command| async move {
                            let req = handle::Request::new_command(state, bot, me, msg, cmd);
                            handler::handle(req).await
                        },
                    )),
            )
            .branch(Update::filter_edited_message().inspect_async(
                |state: Arc<InstanceState>, bot: Bot, me: Me, msg: Message| async move {
                    let req = handle::Request::edited_message(state, bot, me, msg);
                    _ = handler::handle(req).await;
                },
            ));

    Dispatcher::builder(bot, handler)
        .dependencies(dptree::deps![inst_state])
        .default_handler(|upd| async move {
            debug!("unhandled update: {upd:?}");
        })
        .error_handler(Arc::new(
            |err| async move { error!("dispatcher error: {err}") },
        ))
        .enable_ctrlc_handler()
        .build()
        .dispatch()
        .await;

    Ok(())
}