toptl-teloxide 0.1.0

Teloxide plugin for TOP.TL — autopost bot stats, gate handlers behind votes, handle vote webhooks.
Documentation

toptl-teloxide

Crates.io docs.rs Downloads License teloxide TOP.TL

Teloxide plugin for TOP.TL — autopost bot stats, gate handlers behind votes, and handle vote webhooks.

Install

[dependencies]
toptl-teloxide = "0.1"
teloxide = "0.13"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

Built on the toptl SDK.

Quick start

use std::time::Duration;
use teloxide::prelude::*;
use toptl::TopTL;
use toptl_teloxide::{record_update, TopTLPlugin};

#[tokio::main]
async fn main() {
    let bot = Bot::from_env();
    let client = TopTL::new("toptl_xxx");
    let plugin = TopTLPlugin::new(client, "mybot");
    plugin.start(Duration::from_secs(30 * 60));

    let plugin_clone = plugin.clone();
    teloxide::repl(bot, move |msg: Message, bot: Bot| {
        let plugin = plugin_clone.clone();
        async move {
            record_update(&plugin, &msg).await;
            bot.send_message(msg.chat.id, "hi").await?;
            Ok::<_, teloxide::RequestError>(())
        }
    })
    .await;
}

plugin.start(...) spawns a background task that flushes unique user/group/channel counts every interval. record_update(...) ingests one incoming message so the counters stay current.

Vote gating

async fn premium(msg: Message, bot: Bot, plugin: TopTLPlugin) -> ResponseResult<()> {
    if let Some(user) = &msg.from {
        if !plugin.has_voted(user.id.0 as i64).await {
            bot.send_message(msg.chat.id, "Vote first: https://top.tl/mybot").await?;
            return Ok(());
        }
    }
    bot.send_message(msg.chat.id, "Thanks for voting!").await?;
    Ok(())
}

has_voted is fail-open — network or auth errors count as "not voted" and log, never crash your handler.

Manual flush

Useful from a shutdown hook:

plugin.post_now().await?;

License

MIT — see LICENSE.