My code:
use telebot::Bot;
use dotenv::dotenv;
use std::env;
use serde::Deserialize;
use reqwest::Error;
// import all available functions
use telebot::functions::*;
use futures::stream::Stream;
#[derive(Deserialize, Debug)]
struct ApiResponse {
translated_text: String,
}
async fn translate(text: &str, api_translate_url: &str, api_translate_key: &str) -> Result<ApiResponse, Error> {
let client = reqwest::Client::new();
let response = client.post(api_translate_url)
.header("Authorization", format!("Bearer {}", api_translate_key))
.form(&[("text", text)])
.send()
.await?
.json::<ApiResponse>()
.await?;
Ok(response)
}
#[tokio::main]
async fn main() {
dotenv().ok();
env_logger::init();
let token_bot = env::var("TELEGRAM_BOT_KEY").expect("TELEGRAM_BOT_KEY not found");
let api_translate_url = env::var("API_TRANSLATE_URL").expect("API_TRANSLATE_URL not found");
let api_translate_key = env::var("API_TRANSLATE_KEY").expect("API_TRANSLATE_KEY not found");
// Create the bot
let mut bot = Bot::new(&token_bot).update_interval(200);
// Register a reply command which answers a message
let stream = bot.new_cmd("/reply")
.for_each(move |(bot, msg)| {
let text = msg.text.clone().unwrap_or_else(|| "<empty>".into());
let api_translate_url = api_translate_url.clone();
let api_translate_key = api_translate_key.clone();
async move {
bot.message(msg.chat.id, text.clone()).send().await.unwrap();
match translate(&text, &api_translate_url, &api_translate_key).await {
Ok(response) => println!("{:#?}", response),
Err(err) => eprintln!("Translation error: {:?}", err),
}
}
});
bot.run_with(stream);
}
I'm puzzling over the problem, I don't understand in the end what needs to be fixed so that the asynchronous code would work, before that I wrote synchronous, it worked
Error listing:
Compiling telegram_bot v0.1.0 (D:\workspace\rust\telegram_bot)
error[E0277]: `impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_` is not a future
--> src/main.rs:51:63
|
51 | bot.message(msg.chat.id, text.clone()).send().await.unwrap();
| -^^^^^
| ||
| |`impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_` is not a future
| help: remove the `.await`
|
= help: the trait `std::future::Future` is not implemented for `impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_`, which is required by `impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_: std::future::IntoFuture`
= note: impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_ must be a future or must implement `IntoFuture` to be awaited
= note: required for `impl futures::Future<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error> + '_` to implement `std::future::IntoFuture`
error[E0277]: the trait bound `{async block@src/main.rs:50:13: 56:14}: futures::IntoFuture` is not satisfied
--> src/main.rs:45:10
|
45 | .for_each(move |(bot, msg)| {
| ^^^^^^^^ the trait `futures::Future` is not implemented for `{async block@src/main.rs:50:13: 56:14}`, which is required by `{async block@src/main.rs:50:13: 56:14}: futures::IntoFuture`
|
= help: the following other types implement trait `futures::IntoFuture`:
(A, B)
(A, B, C)
(A, B, C, D)
(A, B, C, D, E)
Result<T, E>
hyper::service::service::ServiceFn<F, R>
hyper::service::service::ServiceFnOk<F, R>
tokio::executor::Spawn
= note: required for `{async block@src/main.rs:50:13: 56:14}` to implement `futures::IntoFuture`
note: required by a bound in `futures::Stream::for_each`
--> C:\Users\Digkill\.cargo\registry\src\index.crates.io-6f17d22bba15001f\futures-0.1.31\src\stream\mod.rs:764:18
|
762 | fn for_each<F, U>(self, f: F) -> ForEach<Self, F, U>
| -------- required by a bound in this associated function
763 | where F: FnMut(Self::Item) -> U,
764 | U: IntoFuture<Item=(), Error = Self::Error>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Stream::for_each`
error[E0277]: the trait bound `{async block@src/main.rs:50:13: 56:14}: futures::Future` is not satisfied
--> src/main.rs:59:18
|
59 | bot.run_with(stream);
| -------- ^^^^^^ the trait `futures::Future` is not implemented for `{async block@src/main.rs:50:13: 56:14}`, which is required by `ForEach<impl Stream<Item = (RequestHandle, telebot::objects::Message), Error = failure::error::Error>, {closure@src/main.rs:45:19: 45:36}, {async block@src/main.rs:50:13: 56:14}>: std::marker::Send`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `futures::Future`:
&'a mut F
AssertUnwindSafe<F>
BiLockAcquire<T>
Box<F>
Concat2<S>
Either<A, B>
Failed<T, E>
Flush<S>
and 87 others
= note: required for `{async block@src/main.rs:50:13: 56:14}` to implement `futures::IntoFuture`
note: required because it appears within the type `ForEach<impl Stream<Item = (RequestHandle, Message), Error = Error>, ..., ...>`
--> C:\Users\Digkill\.cargo\registry\src\index.crates.io-6f17d22bba15001f\futures-0.1.31\src\stream\for_each.rs:10:12
|
10 | pub struct ForEach<S, F, U> where U: IntoFuture {
| ^^^^^^^
note: required by a bound in `Bot::run_with`
--> C:\Users\Digkill\.cargo\registry\src\index.crates.io-6f17d22bba15001f\telebot-0.3.1\src\bot.rs:398:36
|
395 | pub fn run_with<I>(self, other: I)
| -------- required by a bound in this associated function
...
398 | <I as IntoFuture>::Future: Send + 'static,
| ^^^^ required by this bound in `Bot::run_with`
= note: the full name for the type has been written to 'D:\workspace\rust\telegram_bot\target\debug\deps\telegram_bot.long-type-11458010299628303036.txt'
= note: consider using `--verbose` to print the full type name to the console
For more information about this error, try `rustc --explain E0277`.
error: could not compile `telegram_bot` (bin "telegram_bot") due to 3 previous errors
PS D:\workspace\rust\telegram_bot>
Cargo.toml:
[package]
name = "telegram_bot"
version = "0.1.0"
edition = "2021"
[dependencies]
dotenv = "0.15"
telebot = "0.3.1"
futures = "0.1.31"
env_logger = "0.11.3"
reqwest = { version = "0.12.5", features = ["json"] }
serde = { version = "1.0.204", features = ["derive"] }
tokio = { version = "1.38.1", features = ["full"] }