Skip to content

Commit

Permalink
Async client (#38)
Browse files Browse the repository at this point in the history
* start working on async api

* impl wip

* add `api` and `traits` modules to allow several trait impls

* draft reqwest impl

* add Send trait

* add remaining methods to async trait

* add async examples

* implement async multipart upload

* add features

* fix clippy warning

* fix `api_trait_implementation` example

* fix feature name

* disable archs without openssl

* remove arm

* use rustls

* disable default features

* add async upload example and fix multipart uploads

* add a couple of async tests
  • Loading branch information
ayrat555 authored Feb 7, 2022
1 parent 0376b41 commit 4856fe9
Show file tree
Hide file tree
Showing 11 changed files with 2,474 additions and 1,025 deletions.
39 changes: 37 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "frankenstein"
version = "0.9.5"
version = "0.10.0"
authors = ["Ayrat Badykov <[email protected]>"]
description = "Telegram bot API client for Rust"
edition = "2018"
Expand All @@ -18,12 +18,46 @@ required-features = ["http-client"]
name = "reply_to_message_updates"
required-features = ["http-client"]

[[example]]
name = "async_get_me"
required-features = ["async-http-client"]

[[example]]
name = "async_reply_to_message_updates"
required-features = ["async-http-client"]

[[example]]
name = "async_file_upload"
required-features = ["async-http-client"]

[[example]]
name = "api_trait_implementation"
required-features = ["telegram-trait"]

[features]
default = ["http-client"]
http-client = ["ureq", "multipart", "mime_guess", "serde_json"]
http-client = ["ureq", "multipart", "mime_guess", "telegram-trait"]
telegram-trait = ["serde_json"]
async-http-client = ["reqwest", "tokio", "async-telegram-trait"]
async-telegram-trait = ["async-trait", "serde_json"]

[dependencies]

[dependencies.async-trait]
version = "0.1"
optional = true

[dependencies.reqwest]
version = "0.11"
default-features = false
features = ["multipart", "stream", "rustls-tls"]
optional = true

[dependencies.tokio]
version = "1.16"
features = ["fs"]
optional = true

[dependencies.mime_guess]
version = "2"
optional = true
Expand Down Expand Up @@ -53,3 +87,4 @@ optional = true
isahc = "1"
mockito = "0.30"
serde_json = "1"
tokio = { version = "1.16", features = ["full"] }
28 changes: 28 additions & 0 deletions examples/async_file_upload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use frankenstein::api_params::SendPhotoParamsBuilder;
use frankenstein::AsyncApi;
use frankenstein::AsyncTelegramApi;

static TOKEN: &str = "TOKEN";
static CHAT_ID: i64 = 1;

#[tokio::main]
async fn main() {
let api = AsyncApi::new(TOKEN);

let file = std::path::PathBuf::from("./frankenstein_logo.png");

let params = SendPhotoParamsBuilder::default()
.chat_id(CHAT_ID)
.photo(file)
.build()
.unwrap();

match api.send_photo(&params).await {
Ok(response) => {
println!("Photo was uploaded {:?}", response);
}
Err(error) => {
eprintln!("Failed to upload photo: {:?}", error);
}
}
}
23 changes: 23 additions & 0 deletions examples/async_get_me.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use frankenstein::AsyncApi;
use frankenstein::AsyncTelegramApi;

static TOKEN: &str = "API_TOKEN";

#[tokio::main]
async fn main() {
let api = AsyncApi::new(TOKEN);

match api.get_me().await {
Ok(response) => {
let user = response.result;
println!(
"Hello, I'm @{}, https://t.me/{}",
user.first_name,
user.username.expect("The bot must have a username.")
);
}
Err(error) => {
eprintln!("Failed to get me: {:?}", error);
}
}
}
58 changes: 58 additions & 0 deletions examples/async_reply_to_message_updates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use frankenstein::AsyncApi;
use frankenstein::AsyncTelegramApi;
use frankenstein::GetUpdatesParamsBuilder;
use frankenstein::Message;
use frankenstein::SendMessageParamsBuilder;

static TOKEN: &str = "API_TOKEN";

#[tokio::main]
async fn main() {
let api = AsyncApi::new(TOKEN);

let mut update_params_builder = GetUpdatesParamsBuilder::default();
update_params_builder.allowed_updates(vec!["message".to_string()]);

let mut update_params = update_params_builder.build().unwrap();

loop {
let result = api.get_updates(&update_params).await;

println!("result: {:?}", result);

match result {
Ok(response) => {
for update in response.result {
if let Some(message) = update.message {
let api_clone = api.clone();

tokio::spawn(async move {
process_message(message, api_clone).await;
});

update_params = update_params_builder
.offset(update.update_id + 1)
.build()
.unwrap();
}
}
}
Err(error) => {
println!("Failed to get updates: {:?}", error);
}
}
}
}

async fn process_message(message: Message, api: AsyncApi) {
let send_message_params = SendMessageParamsBuilder::default()
.chat_id(message.chat.id)
.text("hello")
.reply_to_message_id(message.message_id)
.build()
.unwrap();

if let Err(err) = api.send_message(&send_message_params).await {
println!("Failed to send message: {:?}", err);
}
}
Loading

0 comments on commit 4856fe9

Please sign in to comment.