telegram_bot2/
lib.rs

1#![allow(dead_code)]
2#![warn(missing_docs)]
3
4//!# Telegram bot
5//!
6//! This crate provides an easy to use framework to build telegram bots. It is still in developpement, you may report bugs or request features on the project [repo](https://www.gitlab.com/Thechi2000/telegram-bot2).
7//!
8//! ## Workflow
9//!
10//! The idea behind this framework is similar to [rocket](https://www.rocket.rs) webservers. There is a main function that builds a bot using the [`BotBuilder`](crate::BotBuilder). Updates are fetched via long polling, then passed to handlers.
11//!
12//! ## Building the bot
13//! The recommended way to build the bot is to create a function annotated with [`#[bot]`](macro@crate::bot), returning a [`BotBuilder`](crate::BotBuilder).\
14//! For more information, see [`BotBuilder`](crate::BotBuilder) and [`#[bot]`](macro@crate::bot)
15//! ```rust
16//! #[bot]
17//! async fn bot() -> _ {
18//!     BotBuilder::new()
19//!         .interval(Duration::from_secs(0))
20//!         .timeout(5)
21//!         .handler(handlers![handler])
22//!         .commands(commands![soup])
23//! }
24//! ```
25//!
26//! Note: The function does not need an explicit return type, as it is handled by the `#[bot]` macro
27//!
28//! ## Handlers
29//! Handlers are async functions returning a `Result<(), E> where E: Debug` (returning an Err will result in the program termination). They may take as many parameters as needed, but they all need to implement the [`FromUpdate`](crate::FromUpdate) trait (a bunch of implementations is already provided). Specific handlers may take additional parameters
30//!
31//! ### Generic handler
32//! A generic handler is annotated with the  [`#[handler]`](crate::handler) attribute, and has no specific parameters.
33//!
34//! The parameters of the functions are parsed using the [`FromUpdate`](crate::FromUpdate) trait. If the parsing of any arguments fails, the next handler is tried, until one is successfully parsed.
35//!
36//! The macro takes the following parameters:
37//! - `rank`(usize): Defaults to 0. The priority of this handler, 0 being the highest (i.e. the first handler the be executed)
38//! - `restrict` (list of [`UpdateType`](crate::models::UpdateType)): Defaults to all. The updates that may be passed to the handler
39//!
40//! ```
41//! #[handler(rank = 1)]
42//! async fn handler(message: &Message, bot: &Bot) -> Result<(), ()> {
43//!     bot.send_message(SendMessageBuilder::new(ChatId::from(message.chat.id), message.text.clone().unwrap()).build()).await.unwrap();
44//!     Ok(())
45//! }
46//! ```
47//!
48//! ### Command handler
49//! A command handler is annotated with the  [`#[command]`](crate::command) macro. It take as parameters the dynamic arguments of the command (see the syntax), and any type implementing [`FromUpdate`](crate::FromUpdate)
50//!
51//! The function's arguments are either extracted from the call (according to the syntax), or parsed with [`FromUpdate`](crate::FromUpdate)
52//!
53//! The macro takes the following parameters:
54//! - (String): Mandatory. the syntax of the command, as follows: `"/command_name [static|<dynamic>]*"`. Static parameters are constants, while dynamic parameters are parsed from the command and given to the handler with [`FromStr`](std::str::FromStr)
55//!
56//! ```
57//! #[command("/soup get <id>")]
58//! async fn soup(bot: &Bot, chat: ChatId, id: i64) -> Result<(), ()> {
59//!     bot.send_message(SendMessageBuilder::new(chat, format!("Soup {} requested", id)).build()).await.unwrap();
60//!     Ok(())
61//! }
62//! ```
63//!
64//! In this example, the id parameter is parsed from the message, and has to be an i64. A valid call would be `"/soup get 10"`, while `"/soup get hi"` would not be parsed successfully
65//!
66//! ## Daemons
67//! You can setup daemons that are periodically called in background and can access the BotState. Daemon function are annotated with [`#[daemon]`](crate::daemon) and require an `interval` parameter, which specifies the time between two calls (in seconds).
68//!
69//! The interval time is the time between calls, it does not starts at the end of the last call. For example, if the interval is set to 60s and the daemon takes 5s to complete, the next call will proceeds 55s after the first one ends. The same daemon cannot be started if it is already running (i.e. a 5s daemon with interval of 1s will start as soon as it ends). The timer is precise at a millisecond order.
70//!
71//! The parameters of the function are parsed by the [`FromDaemon`](crate::FromDaemon) trait, at each call
72//!
73//! The macro takes the following parameters:
74//! - `interval` (usize): Mandatory. The time (in seconds) between two calls
75//!
76//! ```
77//! #[daemon(interval = 5)]
78//! async fn hello(state: &BotState<Mutex<usize>>) {
79//!     let mut lock = state.lock().unwrap();
80//!     *lock += 1;
81//!     println!("Increasing counter to {}", lock);
82//! }
83//! ```
84
85extern crate telegram_bot2_macros;
86pub use telegram_bot2_macros::{bot, handler, handlers};
87#[cfg(feature = "commands")]
88pub use telegram_bot2_macros::{command, commands};
89#[cfg(feature = "daemons")]
90pub use telegram_bot2_macros::{daemon, daemons};
91
92pub(crate) use telegram_bot2_macros::{Builder, FileHolder};
93
94mod bot;
95mod bot_builder;
96mod builder;
97mod error;
98mod from_daemon;
99mod from_update;
100mod state;
101
102/// This module is reserved for macros. You should not use any of its members
103#[allow(missing_docs)]
104pub mod __private;
105
106/// Data models of Telegram's API
107pub mod models;
108
109/// Logging crate
110pub use log;
111
112pub use bot::*;
113pub use bot_builder::*;
114pub use builder::*;
115pub use error::*;
116#[cfg(feature = "daemons")]
117pub use from_daemon::*;
118pub use from_update::*;
119pub use state::*;