Skip to content

v0.3

Compare
Choose a tag to compare
@snejugal snejugal released this 18 Mar 04:25
· 736 commits to master since this release

We're happy to announce tbot v0.3! Here's an overview of what we've prepared
for this release.

In v0.3, tbot has moved to std::future and now supports async/.await!
For example, here's an echo bot implemented using async/.await:

use tbot::prelude::*;

async fn main() {
    let mut bot = tbot::from_env!("BOT_TOKEN").event_loop();

    bot.text(|context| {
        async move {
            let echo = &context.text.value;
            let call_result = context.send_message(echo).call().await;

            if let Err(err) = call_result {
                dbg!(err);
            }
        }
    });

    bot.polling().start().await.unwrap();
}

Also, you must appreciate the getMe example:

async fn main() -> Result<(), tbot::errors::MethodCall> {
    let bot = tbot::from_env!("BOT_TOKEN");

    let me = bot.get_me().call().await?;
    dbg!(me);

    Ok(())
}

tbot v0.3 introduces contexts::fields, a module that contains traits for
specific contexts fields. It may sound complicated, but what it actually means
is that you can now write handlers generic over contexts. Here's an example
of a handler that you can use for both just-sent photos and edited ones:

use std::sync::Arc;
use tbot::{contexts::fields::Photo, connectors::Connector};

async fn handle_photo<Ctx, Cnn: Connector>(context: Arc<Ctx>)
where
    Ctx: Photo<Cnn>,
    Cnn: Connector,
{
    let photo = context.photo();
    // ..
}

// ..

bot.photo(handle_photo);
bot.edited_photo(handle_photo);

Though tbot has had webhook support since the first version, it could only
listen over HTTP, while Telegram sent updates over HTTPS only. Because of that,
you would have to use nginx to use webhooks with tbot. Now tbot can natively
listen to updates over HTTPS! If you had this:

bot.webhook(URL, PORT).start();

you can turn it into this:

use tbot::event_loop::webhook::https::Identity;

let identity = Identity::from_pkcs12(
    include_bytes!("path/to/identity.p12"),
    env!("IDENTITY_PASSWORD"),
).unwrap();
bot.webhook(URL, PORT)
    .certificate(include_str!("path/to/public/key/cert.pem"))
    .https(identity)
    .start()
    .await
    .unwrap();

Still, nginx is useful if you want to host several bots on one domain/IP
address or to distribute load between servers, and tbot continues to support
webhook over HTTP.

Another important change in this release is that handlers cannot be mutating
anymore, meaning that you no longer can write this:

let mut id = 0;
bot.inline(move |_| {
    id += 1;
    // ..
});

Instead, you should use a Mutex (or similar) if you need to have some global
state, which scales better with time:

use tokio::sync::Mutex;
use std::sync::Arc;

let id = Arc::new(Mutex::new(0));
bot.inline(move |_| {
    let id = Arc::clone(&id);
    async move {
        id.lock().await += 1;
    }
});
  • tbot::bot! was renamed to tbot::from_env! to better reflect what it does
    (!107);
  • Most types are annotated with #[non_exhaustive] (leading to MSRV 1.40)
    (!133);
  • Input types became #[must_use], as well as methods returning any type
    (for they're all pure) (!134, !137, !138);
  • types::parameters::Updates was renamed to types::parameters::UpdateKind
    (!141);
  • A missing method ChatMethods::pin_chat_message was added (!111);
  • A trait Connector was introduced to simplify writing code generic over
    connectors (!118);
  • Method docs were updated to describe what each method does, so you no longer
    need to refer to Bots API docs (!115);
  • is_* methods were added for enums where they were accidentially missing
    (!140);
  • The Token type is no longer public: it was only used once in public code
    where this additional type safety is not actually needed. It is still used
    internally to allow debugging methods without revealing your token (!124).

We hope you enjoy this huge update!