Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ayrat555/frankenstein
Telegram bot API client for Rust
https://github.com/ayrat555/frankenstein
Last synced: 20 days ago
JSON representation
Telegram bot API client for Rust
- Host: GitHub
- URL: https://github.com/ayrat555/frankenstein
- Owner: ayrat555
- License: wtfpl
- Created: 2021-03-13T13:02:58.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-09-19T10:53:03.000Z (about 2 months ago)
- Last Synced: 2024-10-04T10:28:54.695Z (about 1 month ago)
- Language: Rust
- Homepage:
- Size: 913 KB
- Stars: 259
- Watchers: 4
- Forks: 27
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
- awesome-telegram - Frankenstein
- awesome-telegram - Frankenstein
README
[![Crates.io][s1]][ci] [![docs page][docs-badge]][docs] ![test][ga-test]
# Frankenstein
Telegram bot API client for Rust.
It's a complete wrapper for Telegram bot API, and it's up-to-date with version 7.10 of the API.
Frankenstein's data structures (rust structs and enums) are mapped one-to-one from Telegram bot API objects and method parameters.
## Installation
Run `cargo add frankenstein` or add the following to your `Cargo.toml`.
```toml
[dependencies]
frankenstein = "0.34"
```## Features
### Default features
- `http-client` - a blocking HTTP client (uses `ureq`), it's the only default feature
- `telegram-trait` - a blocking API trait, it's included in the `http-client` feature. It may be useful for people who want to create a custom blocking client (for example, replacing an HTTP client)### Optional features
- `async-http-client` - an async HTTP client, it uses `reqwest`, and it's disabled by default
- `async-telegram-trait` - an async API trait, it's used in the `async-http-client`. It may be useful for people who want to create a custom async clientTo use the async client add the following line to your `Cargo.toml` file:
```toml
frankenstein = { version = "0.34", default-features = false, features = ["async-http-client"] }
```You can also disable all features. In this case the crate will ship only with Telegram types.
```toml
frankenstein = { version = "0.34", default-features = false }
```## Usage
Examples in this section use the blocking client (`frankenstein::Api`), but async examples would look the same (just replace `frankenstein::Api` with `frankenstein::AsyncApi`)
### Data structures
All objects described in the API docs have direct counterparts in the Frankenstein. For example, in the docs there is [the user type](https://core.telegram.org/bots/api#user):
```plaintext
id Integer Unique identifier for this user or bot. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision float type are safe for storing this identifier.
is_bot Boolean True, if this user is a bot
first_name String User's or bot's first name
last_name String Optional. User's or bot's last name
username String Optional. User's or bot's username
language_code String Optional. IETF language tag of the user's language
can_join_groups Boolean Optional. True, if the bot can be invited to groups. Returned only in getMe.
can_read_all_group_messages Boolean Optional. True, if privacy mode is disabled for the bot. Returned only in getMe.
supports_inline_queries Boolean Optional. True, if the bot supports inline queries. Returned only in getMe.
```In Frankenstein, it's described like this:
```rust
pub struct User {
pub id: u64,
pub is_bot: bool,
pub first_name: String,
pub last_name: Option,
pub username: Option,
pub language_code: Option,
pub can_join_groups: Option,
pub can_read_all_group_messages: Option,
pub supports_inline_queries: Option,
}
```Optional fields are described as `Option`.
Every struct can be created with the associated builder. Only required fields are required to set, optional fields are set to `None` when not provided:
```rust
let send_message_params = SendMessageParams::builder()
.chat_id(message.chat.id)
.text("hello")
.reply_to_message_id(message.message_id)
.build();
```For API parameters, the same approach is used. The only difference for parameters is the name of the struct in Frankenstein ends with `Params` postfix.
For example, parameters for `leaveChat` method:
```rust
pub struct LeaveChatParams {
chat_id: ChatId,
}
```### Making requests
To make a request to the Telegram bot API initialize the `Api` struct.
```rust
use frankenstein::Api;
use frankenstein::TelegramApi;...
let token = "My_token";
let api = Api::new(token);
```Then use this API object to make requests to the Bot API:
```rust
let update_params = GetUpdatesParams::builder()
.allowed_updates(vec![AllowedUpdate::Message])
.build();let result = api.get_updates(&update_params);
```Every function returns a `Result` enum with a successful response or failed response.
See a complete example in the `examples` directory.
### Uploading files
Some methods in the API allow uploading files. In the Frankenstein for this `FileUpload` enum is used:
```rust
pub enum FileUpload {
InputFile(InputFile),
String(String),
}pub struct InputFile {
path: std::path::PathBuf
}
```It has two variants:
- `FileUpload::String` is used to pass the ID of the already uploaded file
- `FileUpload::InputFile` is used to upload a new file using multipart upload.### Customizing HTTP clients
Both the async (`reqwest`) and the blocking (`ureq`) HTTP clients can be customized with their builders.
Customizing the blocking client:
```rust
use frankenstein::ureq;
use frankenstein::Api;
use std::time::Duration;let request_agent = ureq::builder().timeout(Duration::from_secs(100)).build();
let api_url = format!("{}{}", BASE_API_URL, TOKEN);Api::builder()
.api_url(api_url)
.request_agent(request_agent)
.build()
```Customizing the async client:
```rust
use frankenstein::reqwest;
use frankenstein::AsyncApi;
use std::time::Duration;let client = reqwest::ClientBuilder::new()
.connect_timeout(Duration::from_secs(100))
.timeout(Duration::from_secs(100))
.build()
.unwrap();
let api_url = format!("{}{}", BASE_API_URL, TOKEN);AsyncApi::builder().api_url(api_url).client(client).build()
```### Documentation
Frankenstein implements all Telegram bot API methods. To see which parameters you should pass, check [docs.rs](https://docs.rs/frankenstein/0.34.0/frankenstein/api_traits/telegram_api/trait.TelegramApi.html#provided-methods)
You can check out real-world bots created using this library:
- [El Monitorro](https://github.com/ayrat555/el_monitorro) - RSS/Atom/JSON feed reader.
- [subvt-telegram-bot](https://github.com/helikon-labs/subvt-backend/tree/main/subvt-telegram-bot) - A Telegram bot for the validators of the [Polkadot](https://polkadot.network/) and [Kusama](https://kusama.network/).
- [wdr-maus-downloader](https://github.com/EdJoPaTo/wdr-maus-downloader) - checks for a new episode of the WDR Maus and downloads it.
- [weather_bot_rust](https://github.com/pxp9/weather_bot_rust) - A Telegram bot that provides weather info around the world.## Replacing the default HTTP client
The library uses `ureq` HTTP client by default, but it can be easily replaced with any HTTP client of your choice.
`ureq` comes with a default feature (`impl`). So the feature should be disabled.
```toml
frankenstein = { version = "0.34", default-features = false, features = ["telegram-trait"] }
```Then implement the `TelegramApi` trait for your HTTP client which requires two functions:
- `request_with_form_data` is used to upload files
- `request` is used for requests without file uploadsYou can check [the default `TelegramApi` trait implementation](https://github.com/ayrat555/frankenstein/blob/aac88c01d06aa945393db7255ef2485a7c764d47/src/api_impl.rs) for `ureq`.
Also, you can take a look at the [implementation for `isahc` HTTP client](https://github.com/ayrat555/frankenstein/blob/master/examples/api_trait_implementation.rs) in the `examples` directory.
Without the default `ureq` implementation, `frankenstein` has only one dependency - `serde`.
## Contributing
1. [Fork it!](https://github.com/ayrat555/frankenstein/fork)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request## Author
Ayrat Badykov (@ayrat555)
[s1]: https://img.shields.io/crates/v/frankenstein.svg
[docs-badge]: https://img.shields.io/badge/docs-website-blue.svg
[ci]: https://crates.io/crates/frankenstein
[docs]: https://docs.rs/frankenstein/
[ga-test]: https://github.com/ayrat555/frankenstein/actions/workflows/rust.yml/badge.svg