• Stars
    star
    258
  • Rank 158,189 (Top 4 %)
  • Language
    Rust
  • License
    Do What The F*ck ...
  • Created over 3 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Telegram bot API client for Rust

frankenstein

Crates.io docs page 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 6.7 of the API.

Frankenstein data structures (rust structs and enums) are mapped one-to-one from Telegram bot API objects and method params.

Installation

Add this to your Cargo.toml

[dependencies]
frankenstein = "0.26"

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 client

To use the async client add the following line to your Cargo.toml file:

frankenstein = { version = "0.26", default-features = false, features = ["async-http-client"] }

You can also disable all features:

frankenstein = { version = "0.26", default-features = false }

In this case the crate will ship only with telegram types

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:

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:

pub struct User {
    pub id: u64,
    pub is_bot: bool,
    pub first_name: String,
    pub last_name: Option<String>,
    pub username: Option<String>,
    pub language_code: Option<String>,
    pub can_join_groups: Option<bool>,
    pub can_read_all_group_messages: Option<bool>,
    pub supports_inline_queries: Option<bool>,
}

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:

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:

pub struct LeaveChatParams {
    chat_id: ChatId,
}

Making requests

To make a request to the telegram bot api:

  1. Initialize the Api struct:
use frankenstein::Api;
use frankenstein::TelegramApi;

...

let token = "My_token";
let api = Api::new(token);
  1. Use this api object to make requests to the Bot API:
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:

pub enum FileUpload {
    InputFile(InputFile),
    String(String),
}

pub struct InputFile {
    path: std::path::PathBuf
}

It has two variants:

  • FileUpload::String is used to pass 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:

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:

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

You can check out real-world bots created using this library:

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:

  1. ureq comes with a default feature (impl). So the feature should be disabled:
frankenstein = { version = "0.26", default-features = false, features = ["telegram-trait"] }
  1. Implement TelegramApi trait which requires two functions:
  • request_with_form_data is used to upload files
  • request is used for requests without file uploads

You can check the default TelegramApi trait implementation for ureq.

Also, you can take a look at the implementation for isahc http client in the examples directory.

Without the default ureq implementation, frankenstein has only one dependency - serde.

Contributing

  1. Fork it!
  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)

More Repositories

1

fang

Background processing for Rust
Rust
608
star
2

el_monitorro

πŸ‚ El Monitorro is a high-performance feed reader as a Telegram bot. It supports RSS, Atom and JSON feeds
Rust
198
star
3

mix.el

Emacs Minor Mode for Mix, a build tool that ships with Elixir
Emacs Lisp
34
star
4

hornet

Hornet is a simple library for stress testing
Elixir
33
star
5

ton

TON (The Open Network) SDK
Elixir
27
star
6

cryptopunk

Hierarchical deterministic wallet for Elixir
Elixir
24
star
7

clope

Elixir implementation of CLOPE: A Fast and Effective Clustering Algorithm for Transactional Data
Elixir
22
star
8

treasure_hunter

The project for hacking your crypto wallet
Elixir
17
star
9

cargo-mode

Emacs minor mode which allows to dynamically select cargo command
Emacs Lisp
17
star
10

dot-emacs

My Emacs configuration
Emacs Lisp
15
star
11

ex_secp256k1

Rust Nif that wraps a couple functions from the libsecp256k1 rust library
Elixir
14
star
12

company-elixir

company-mode completion backend for Elixir.
Emacs Lisp
12
star
13

rock

Elixir implementation of ROCK: A Robust Clustering Algorithm for Categorical Attributes
Elixir
11
star
14

cronenberg

Simple cron command entry parser
Rust
11
star
15

braindump

WIP braindump
Emacs Lisp
10
star
16

eth_bloom

Ethereum's bloom filter implementation in elixir
Elixir
6
star
17

ex_riak_cs

Riak CS API wrapper for Elixir
Elixir
5
star
18

cortex-dark

Dark theme for Braindump (Hugo)
SCSS
5
star
19

ex_pbkdf2

Password-Based Key Derivation Function v2 (PBKDF2) for Elixir by a Rust-based NIF
Elixir
4
star
20

foogold

A tool for trying your luck with random bitcoin mnemonics
Rust
4
star
21

cafezinho

Rust NIF for Ed25519 curve functions.
Elixir
2
star
22

geth_reorg_sim

Dockerfile
2
star
23

ayrat555.github.io

Personal blog
HTML
2
star
24

mnemoniac

Implementation of BIP-39 which describes generation of mnemonic codes or mnemonic sentences
Elixir
2
star
25

ex_keccak

Elixir
1
star
26

ex_bech32

Nif for Bech32 format encoding and decoding (used for native segregated witness output addresses in btc).
Elixir
1
star
27

evil_crc32c

"Evil" version of the crc32c algorithm
Elixir
1
star
28

tiny_evm

Tiny EVM - test assignment for the Mana project (https://github.com/poanetwork/mana) candidates
Elixir
1
star
29

ex_base58

Rust NIF for Base58 encoding and decoding with support of Bitcoin, Ripple, Monero and Flickr alphabets.
Elixir
1
star