tg-rs/carapax

Handle updates in Rocket web framework

Closed this issue · 7 comments

I am not using handle_updates function, and I receive update using webhook like this (it is rocker framework) :

#[post("/bot/telegram/test-dev", format = "application/json", data = "<update>")]
pub fn telegram_webhook(update: Json<tgbot::types::Update>, db_conn: RustyDbConn) -> String {
    "".into()
}

So the question is, how can I send one reply or more? And not only reply, sometimes bot need send notifications.. I am trying code:

let method = SendMessage::new(chat_id, "Test msg:");
tokio::run(api.clone().execute(method).then(|x| {
    Ok::<(), ()>(())
}));

and it works. But code after tokio::run is unreachable.
Looks like long polling is turining on? I am not sure..

So, the question is how can I send messages not using tgbot's handlers? Forward thank you!

Hi! Unfortunately I have no idea why it is unreachable. @mexus can you help?

Also I guess it's better to send update to a thread where you can spawn a future. Same for notifications. So you don't need to create a tokio runtime on every request which is a bit expensive.

Hi! Unfortunately I have no idea why it is unreachable. @mexus can you help?

I have simplified an example:

extern crate futures;
extern crate tgbot;
extern crate tokio;

use futures::Future;
use tgbot::{
    Api,
    Config, methods::SendMessage,
};

pub fn get_telegram_api() -> Api {
    let token = "_________YOUR_TELEGRAM_TOKEN_________".to_string();
    let config = Config::new(token);
    Api::new(config).expect("Failed to create API")
}

fn main() {
    let api = get_telegram_api();

    let method = SendMessage::new(1, "Test");
    let f = api.clone().execute(method).then(|x| {
        println!("{:?}", x);
        Ok::<(), ()>(())
    });
    tokio::run(f);

    println!("This code is unreachable");
}

Read it like it is the case when bot want send a notification (not a reply)
As I understand, tokio::run blocks the rest of thread. But unfortunately api::spawn or tokio::spawn instead of tokio::run not works. And my_future:wait() not working also

P. S. this example works, but program doesn't shut down after sending a message, either println unreachable

I've added an example for notifications:
https://github.com/tg-rs/tg-rs/blob/cd33892ee3419ed6bfbdbdcefac2103af045f349/tgbot/examples/notify.rs

In Rocket you can do something like this: tx.send(Notification::Update(update))?;

Try block_on_all: https://docs.rs/tokio/0.1.22/tokio/runtime/current_thread/fn.block_on_all.html

Yes, not sure about block_on_all, but block_on works for me!))

use tokio::runtime::current_thread::Runtime;
let mut rt = Runtime::new().unwrap();
rt.block_on(future);
println!("String will be printed!!");

I've added an example for notifications:
https://github.com/tg-rs/tg-rs/blob/cd33892ee3419ed6bfbdbdcefac2103af045f349/tgbot/examples/notify.rs

In Rocket you can do something like this: tx.send(Notification::Update(update))?;

This example also looks nice!) with channel, really good one.
The only thing it require some work to implement it like fairings or like request guards to have copy of tx in route. but any way it is already much possible. And example suits great, works, and have correct logic!)