mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
Merge branch 'dev' into const-must-use
This commit is contained in:
commit
bb6dd81f6a
15 changed files with 215 additions and 124 deletions
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
@ -157,6 +157,13 @@ jobs:
|
|||
command: check
|
||||
args: --examples --features full
|
||||
|
||||
# TODO: prolly move it to a separate step?
|
||||
- name: Check with no default features
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --no-default-features
|
||||
|
||||
clippy:
|
||||
name: Run linter
|
||||
runs-on: ubuntu-latest
|
||||
|
|
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## unreleased
|
||||
|
||||
## Removed
|
||||
### Changed
|
||||
|
||||
- Updated `axum` to v0.6.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- `rocksdb-storage` feature and associated items (See [PR #761](https://github.com/teloxide/teloxide/pull/761) for reasoning) [**BC**]
|
||||
|
||||
|
@ -16,7 +20,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- The following functions were made `#[must_use]`:
|
||||
- `DispatcherBuilder::{enable_ctrlc_handler, distribution_function}`
|
||||
|
||||
## 0.11.1 - 2022-10-31
|
||||
## 0.11.3 - 2022-11-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add another missing feature gate for `dispatching::repls` import ([issue #770](https://github.com/teloxide/teloxide/issues/770))
|
||||
|
||||
## 0.11.2 - 2022-11-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add missing feature gate for `dispatching::repls` import ([issue #770](https://github.com/teloxide/teloxide/issues/770))
|
||||
|
||||
## 0.11.1 - 2022-10-31 [yanked]
|
||||
|
||||
This release was yanked because it accidentally [breaks backwards compatibility](https://github.com/teloxide/teloxide/issues/770).
|
||||
|
||||
### Added
|
||||
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -1,2 +1,13 @@
|
|||
[workspace]
|
||||
members = ["crates/*"]
|
||||
|
||||
|
||||
# The settings below will be applied to all crates in the workspace
|
||||
[workspace.package]
|
||||
# MSRV (minimal supported Rust version).
|
||||
rust-version = "1.64"
|
||||
edition = "2021"
|
||||
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/teloxide/teloxide"
|
||||
repository = "https://github.com/teloxide/teloxide"
|
||||
|
|
|
@ -9,7 +9,7 @@ Note that the list of required changes is not fully exhaustive and it may lack s
|
|||
If you are using rocksdb storage, you'll need to either write `Storage` impl yourself, or use a third party crate.
|
||||
<!-- FIXME: add a link once there *is* a third party crate -->
|
||||
|
||||
## 0.11 -> 0.11.1
|
||||
## 0.11 -> 0.11.3
|
||||
|
||||
### teloxide
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
> [v0.11 -> v0.11.1 migration guide >>](MIGRATION_GUIDE.md#011---0111)
|
||||
> [v0.11 -> v0.11.3 migration guide >>](MIGRATION_GUIDE.md#011---0113)
|
||||
|
||||
<div align="center">
|
||||
<img src="./media/teloxide-logo.png" width="250"/>
|
||||
|
|
|
@ -1,64 +1,20 @@
|
|||
[package]
|
||||
name = "teloxide-core"
|
||||
description = "Core part of the `teloxide` library - telegram bot API client"
|
||||
version = "0.8.0"
|
||||
edition = "2021"
|
||||
description = "Core part of the `teloxide` library - telegram bot API client"
|
||||
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
license = "MIT"
|
||||
repository = "https://github.com/teloxide/teloxide-core/"
|
||||
homepage = "https://github.com/teloxide/teloxide-core/"
|
||||
documentation = "https://docs.rs/teloxide-core/"
|
||||
readme = "README.md"
|
||||
|
||||
keywords = ["telegram", "bot", "tba"]
|
||||
keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api", "bot", "TBA"]
|
||||
categories = ["api-bindings", "asynchronous"]
|
||||
|
||||
exclude = [
|
||||
".github/*",
|
||||
"netlify.toml",
|
||||
]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.5"
|
||||
tokio = { version = "1.12.0", features = ["fs"] }
|
||||
tokio-util = { version = "0.7.0", features = ["codec"] }
|
||||
pin-project = "1.0.12"
|
||||
bytes = "1.0.0"
|
||||
reqwest = { version = "0.11.10", features = ["json", "stream", "multipart"], default-features = false }
|
||||
url = { version = "2", features = ["serde"] }
|
||||
log = "0.4"
|
||||
|
||||
serde = { version = "1.0.114", features = ["derive"] }
|
||||
serde_json = "1.0.55"
|
||||
serde_with_macros = "1.5.2"
|
||||
uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files
|
||||
|
||||
derive_more = "0.99.9"
|
||||
mime = "0.3.16"
|
||||
thiserror = "1.0.20"
|
||||
once_cell = "1.5.0"
|
||||
takecell = "0.1"
|
||||
take_mut = "0.2"
|
||||
rc-box = "1.1.1"
|
||||
never = "0.1.0"
|
||||
chrono = { version = "0.4.19", default-features = false }
|
||||
either = "1.6.1"
|
||||
bitflags = { version = "1.2" }
|
||||
|
||||
vecrem = { version = "0.1", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_env_logger = "0.4"
|
||||
tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] }
|
||||
cool_asserts = "2.0.3"
|
||||
|
||||
xshell = "0.2"
|
||||
ron = "0.7"
|
||||
indexmap = { version = "1.9", features = ["serde-1"] }
|
||||
aho-corasick = "0.7"
|
||||
itertools = "0.10"
|
||||
|
||||
[features]
|
||||
default = ["native-tls"]
|
||||
|
@ -90,6 +46,49 @@ auto_send = []
|
|||
# All features except nightly and tls-related
|
||||
full = ["throttle", "trace_adaptor", "erased", "cache_me", "auto_send"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.5"
|
||||
tokio = { version = "1.12.0", features = ["fs"] }
|
||||
tokio-util = { version = "0.7.0", features = ["codec"] }
|
||||
pin-project = "1.0.12"
|
||||
bytes = "1.0.0"
|
||||
reqwest = { version = "0.11.10", features = ["json", "stream", "multipart"], default-features = false }
|
||||
url = { version = "2", features = ["serde"] }
|
||||
log = "0.4"
|
||||
|
||||
serde = { version = "1.0.114", features = ["derive"] }
|
||||
serde_json = "1.0.55"
|
||||
serde_with_macros = "1.5.2"
|
||||
uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files
|
||||
|
||||
derive_more = "0.99.9"
|
||||
mime = "0.3.16"
|
||||
thiserror = "1.0.20"
|
||||
once_cell = "1.5.0"
|
||||
takecell = "0.1"
|
||||
take_mut = "0.2"
|
||||
rc-box = "1.1.1"
|
||||
never = "0.1.0"
|
||||
chrono = { version = "0.4.19", default-features = false }
|
||||
either = "1.6.1"
|
||||
bitflags = { version = "1.2" }
|
||||
|
||||
vecrem = { version = "0.1", optional = true }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_env_logger = "0.4"
|
||||
tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] }
|
||||
cool_asserts = "2.0.3"
|
||||
|
||||
xshell = "0.2"
|
||||
ron = "0.7"
|
||||
indexmap = { version = "1.9", features = ["serde-1"] }
|
||||
aho-corasick = "0.7"
|
||||
itertools = "0.10"
|
||||
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["full", "nightly", "tokio/macros", "tokio/rt-multi-thread"]
|
||||
rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"]
|
||||
|
@ -97,6 +96,7 @@ rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"]
|
|||
# https://github.com/rust-lang/rust/issues/88791
|
||||
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
|
||||
|
||||
|
||||
[[example]]
|
||||
name = "self_info"
|
||||
required-features = ["tokio/macros", "tokio/rt-multi-thread"]
|
||||
|
|
|
@ -90,8 +90,8 @@ use crate::{
|
|||
///
|
||||
/// Because of this it's oftentimes more convinient to have a type alias:
|
||||
///
|
||||
/// ```rust
|
||||
/// # async {
|
||||
/// ```rust,no_run
|
||||
/// # #[cfg(feature = "throttle")] {
|
||||
/// # use teloxide_core::{adaptors::{DefaultParseMode, Throttle}, requests::RequesterExt, types::ParseMode};
|
||||
/// type Bot = DefaultParseMode<Throttle<teloxide_core::Bot>>;
|
||||
///
|
||||
|
|
|
@ -2,14 +2,22 @@
|
|||
name = "teloxide-macros"
|
||||
version = "0.7.0"
|
||||
description = "The teloxide's procedural macros"
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
documentation = "https://docs.rs/teloxide-core/"
|
||||
# FIXME: add a simple readme for teloxide-macros
|
||||
#readme = "README.md"
|
||||
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.7"
|
||||
proc-macro2 = "1.0.19"
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
[package]
|
||||
name = "teloxide"
|
||||
version = "0.11.1"
|
||||
edition = "2021"
|
||||
version = "0.11.3"
|
||||
description = "An elegant Telegram bots framework for Rust"
|
||||
repository = "https://github.com/teloxide/teloxide"
|
||||
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
documentation = "https://docs.rs/teloxide/"
|
||||
readme = "../../README.md"
|
||||
keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api"]
|
||||
|
||||
keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api", "bot", "TBA"]
|
||||
categories = ["web-programming", "api-bindings", "asynchronous"]
|
||||
license = "MIT"
|
||||
exclude = ["media", "README.md"]
|
||||
|
||||
|
||||
[features]
|
||||
default = ["native-tls", "ctrlc_handler", "teloxide-core/default", "auto-send"]
|
||||
|
@ -56,6 +61,7 @@ full = [
|
|||
"erased",
|
||||
]
|
||||
|
||||
|
||||
[dependencies]
|
||||
teloxide-core = { version = "0.8.0", default-features = false }
|
||||
teloxide-macros = { version = "0.7.0", optional = true }
|
||||
|
@ -94,11 +100,12 @@ sqlx = { version = "0.6", optional = true, default-features = false, features =
|
|||
redis = { version = "0.21", features = ["tokio-comp"], optional = true }
|
||||
serde_cbor = { version = "0.11", optional = true }
|
||||
bincode = { version = "1.3", optional = true }
|
||||
axum = { version = "0.5.13", optional = true }
|
||||
axum = { version = "0.6.0", optional = true }
|
||||
tower = { version = "0.4.12", optional = true }
|
||||
tower-http = { version = "0.3.4", features = ["trace"], optional = true }
|
||||
rand = { version = "0.8.5", optional = true }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.3"
|
||||
pretty_env_logger = "0.4.0"
|
||||
|
@ -109,6 +116,7 @@ reqwest = "0.11.11"
|
|||
chrono = "0.4"
|
||||
tokio-stream = "0.1"
|
||||
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
# FIXME: Add back "-Znormalize-docs" when https://github.com/rust-lang/rust/issues/93703 is fixed
|
||||
|
@ -116,6 +124,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||
rustc-args = ["--cfg", "dep_docsrs"]
|
||||
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
|
||||
|
||||
|
||||
[[test]]
|
||||
name = "redis"
|
||||
path = "tests/redis.rs"
|
||||
|
@ -126,42 +135,51 @@ name = "sqlite"
|
|||
path = "tests/sqlite.rs"
|
||||
required-features = ["sqlite-storage", "cbor-serializer", "bincode-serializer"]
|
||||
|
||||
|
||||
[[example]]
|
||||
name = "dialogue"
|
||||
required-features = ["macros"]
|
||||
name = "admin"
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "buttons"
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "command"
|
||||
required-features = ["macros"]
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "db_remember"
|
||||
required-features = ["sqlite-storage", "redis-storage", "bincode-serializer", "macros"]
|
||||
|
||||
[[example]]
|
||||
name = "inline"
|
||||
required-features = ["macros"]
|
||||
|
||||
[[example]]
|
||||
name = "buttons"
|
||||
required-features = ["macros"]
|
||||
|
||||
[[example]]
|
||||
name = "admin"
|
||||
required-features = ["macros"]
|
||||
name = "dialogue"
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "dispatching_features"
|
||||
required-features = ["macros"]
|
||||
|
||||
[[example]]
|
||||
name = "ngrok_ping_pong"
|
||||
required-features = ["webhooks-axum"]
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "heroku_ping_pong"
|
||||
required-features = ["webhooks-axum"]
|
||||
required-features = ["webhooks-axum", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "inline"
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "ngrok_ping_pong"
|
||||
required-features = ["webhooks-axum", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "purchase"
|
||||
required-features = ["macros"]
|
||||
required-features = ["macros", "ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "shared_state"
|
||||
required-features = ["ctrlc_handler"]
|
||||
|
||||
[[example]]
|
||||
name = "throw_dice"
|
||||
required-features = ["ctrlc_handler"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! An update dispatching model based on [`dptree`].
|
||||
//!
|
||||
//! In teloxide, update dispatching is declarative: it takes the form of a
|
||||
//! In `teloxide`, update dispatching is declarative: it takes the form of a
|
||||
//! [chain of responsibility] pattern enriched with a number of combinator
|
||||
//! functions, which together form an instance of the [`dptree::Handler`] type.
|
||||
//!
|
||||
|
@ -23,6 +23,7 @@
|
|||
//! `/start` or `/help`:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # #[cfg(feature = "macros")] {
|
||||
//! # use teloxide::utils::command::BotCommands;
|
||||
//! #[derive(BotCommands, Clone)]
|
||||
//! #[command(rename_rule = "lowercase", description = "These commands are supported:")]
|
||||
|
@ -34,6 +35,7 @@
|
|||
//! #[command(description = "cancel the purchase procedure.")]
|
||||
//! Cancel,
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Now the key question: how to elegantly dispatch on different combinations of
|
||||
|
@ -43,6 +45,7 @@
|
|||
//! solution is to use [`dptree`]:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # #[cfg(feature = "macros")] {
|
||||
//! # // That's a lot of context needed to compile this, oof
|
||||
//! # use teloxide::dispatching::{UpdateHandler, UpdateFilterExt, dialogue, dialogue::InMemStorage};
|
||||
//! # use teloxide::utils::command::BotCommands;
|
||||
|
@ -81,6 +84,7 @@
|
|||
//! .branch(message_handler)
|
||||
//! .branch(callback_query_handler)
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! The overall logic should be clear. Throughout the above example, we use
|
||||
|
@ -149,6 +153,7 @@
|
|||
//! Inside `main`, we plug the schema into [`Dispatcher`] like this:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # #[cfg(feature = "ctrlc_handler")] {
|
||||
//! # use teloxide::Bot;
|
||||
//! # use teloxide::requests::RequesterExt;
|
||||
//! # use teloxide::dispatching::{Dispatcher, dialogue::InMemStorage};
|
||||
|
@ -165,6 +170,7 @@
|
|||
//! .dispatch()
|
||||
//! .await;
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! In a call to [`DispatcherBuilder::dependencies`], we specify a list of
|
||||
|
|
|
@ -146,6 +146,9 @@ where
|
|||
ctrlc_handler,
|
||||
} = self;
|
||||
|
||||
// If the `ctrlc_handler` feature is not enabled, don't emit a warning.
|
||||
let _ = ctrlc_handler;
|
||||
|
||||
let dp = Dispatcher {
|
||||
bot,
|
||||
dependencies,
|
||||
|
|
|
@ -77,14 +77,15 @@ impl EventKind for Kind {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[cfg(feature = "macros")]
|
||||
use crate::{
|
||||
self as teloxide, // fixup for the `BotCommands` macro
|
||||
dispatching::{HandlerExt, UpdateFilterExt},
|
||||
types::{AllowedUpdate::*, Update},
|
||||
utils::command::BotCommands,
|
||||
};
|
||||
|
||||
use crate as teloxide; // fixup for the `BotCommands` macro
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
#[derive(BotCommands, Clone)]
|
||||
#[command(rename_rule = "lowercase")]
|
||||
enum Cmd {
|
||||
|
@ -93,6 +94,7 @@ mod tests {
|
|||
|
||||
// <https://github.com/teloxide/teloxide/discussions/648>
|
||||
#[test]
|
||||
#[cfg(feature = "macros")]
|
||||
fn discussion_648() {
|
||||
let h =
|
||||
dptree::entry().branch(Update::filter_my_chat_member().endpoint(|| async {})).branch(
|
||||
|
@ -108,4 +110,11 @@ mod tests {
|
|||
|
||||
assert_eq!(v, [Message, MyChatMember])
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "this test requires `macros` feature"]
|
||||
#[cfg(not(feature = "macros"))]
|
||||
fn discussion_648() {
|
||||
panic!("this test requires `macros` feature")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
use std::{convert::Infallible, future::Future, pin::Pin};
|
||||
|
||||
use axum::{
|
||||
extract::{FromRequest, RequestParts},
|
||||
http::status::StatusCode,
|
||||
extract::{FromRequestParts, State},
|
||||
http::{request::Parts, status::StatusCode},
|
||||
};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
dispatching::update_listeners::{webhooks::Options, UpdateListener},
|
||||
requests::Requester,
|
||||
stop::StopFlag,
|
||||
types::Update,
|
||||
};
|
||||
|
||||
/// Webhook implementation based on the [mod@axum] framework.
|
||||
|
@ -156,25 +158,17 @@ pub fn axum_no_setup(
|
|||
use crate::{
|
||||
dispatching::update_listeners::{self, webhooks::tuple_first_mut},
|
||||
stop::{mk_stop_token, StopToken},
|
||||
types::Update,
|
||||
};
|
||||
use axum::{extract::Extension, response::IntoResponse, routing::post};
|
||||
use tokio::sync::mpsc;
|
||||
use axum::{response::IntoResponse, routing::post};
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
type Sender = mpsc::UnboundedSender<Result<Update, std::convert::Infallible>>;
|
||||
type CSender = ClosableSender<Result<Update, std::convert::Infallible>>;
|
||||
|
||||
let (tx, rx): (Sender, _) = mpsc::unbounded_channel();
|
||||
let (tx, rx): (UpdateSender, _) = mpsc::unbounded_channel();
|
||||
|
||||
async fn telegram_request(
|
||||
input: String,
|
||||
State(WebhookState { secret, flag, mut tx }): State<WebhookState>,
|
||||
secret_header: XTelegramBotApiSecretToken,
|
||||
secret: Extension<Option<String>>,
|
||||
tx: Extension<CSender>,
|
||||
flag: Extension<StopFlag>,
|
||||
input: String,
|
||||
) -> impl IntoResponse {
|
||||
// FIXME: use constant time comparison here
|
||||
if secret_header.0.as_deref() != secret.as_deref().map(str::as_bytes) {
|
||||
|
@ -186,7 +180,7 @@ pub fn axum_no_setup(
|
|||
// Do not process updates after `.stop()` is called even if the server is still
|
||||
// running (useful for when you need to stop the bot but can't stop the server).
|
||||
_ if flag.is_stopped() => {
|
||||
{ tx.0 }.close();
|
||||
tx.close();
|
||||
return StatusCode::SERVICE_UNAVAILABLE;
|
||||
}
|
||||
Some(tx) => tx,
|
||||
|
@ -212,14 +206,14 @@ pub fn axum_no_setup(
|
|||
|
||||
let (stop_token, stop_flag) = mk_stop_token();
|
||||
|
||||
let app = axum::Router::new().route(options.url.path(), post(telegram_request)).layer(
|
||||
ServiceBuilder::new()
|
||||
let app = axum::Router::new()
|
||||
.route(options.url.path(), post(telegram_request))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(Extension(ClosableSender::new(tx)))
|
||||
.layer(Extension(stop_flag.clone()))
|
||||
.layer(Extension(options.secret_token))
|
||||
.into_inner(),
|
||||
);
|
||||
.with_state(WebhookState {
|
||||
tx: ClosableSender::new(tx),
|
||||
flag: stop_flag.clone(),
|
||||
secret: options.secret_token,
|
||||
});
|
||||
|
||||
let stream = UnboundedReceiverStream::new(rx);
|
||||
|
||||
|
@ -233,9 +227,19 @@ pub fn axum_no_setup(
|
|||
(listener, stop_flag, app)
|
||||
}
|
||||
|
||||
type UpdateSender = mpsc::UnboundedSender<Result<Update, std::convert::Infallible>>;
|
||||
type UpdateCSender = ClosableSender<Result<Update, std::convert::Infallible>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct WebhookState {
|
||||
tx: UpdateCSender,
|
||||
flag: StopFlag,
|
||||
secret: Option<String>,
|
||||
}
|
||||
|
||||
/// A terrible workaround to drop axum extension
|
||||
struct ClosableSender<T> {
|
||||
origin: std::sync::Arc<std::sync::RwLock<Option<tokio::sync::mpsc::UnboundedSender<T>>>>,
|
||||
origin: std::sync::Arc<std::sync::RwLock<Option<mpsc::UnboundedSender<T>>>>,
|
||||
}
|
||||
|
||||
impl<T> Clone for ClosableSender<T> {
|
||||
|
@ -245,11 +249,11 @@ impl<T> Clone for ClosableSender<T> {
|
|||
}
|
||||
|
||||
impl<T> ClosableSender<T> {
|
||||
fn new(sender: tokio::sync::mpsc::UnboundedSender<T>) -> Self {
|
||||
fn new(sender: mpsc::UnboundedSender<T>) -> Self {
|
||||
Self { origin: std::sync::Arc::new(std::sync::RwLock::new(Some(sender))) }
|
||||
}
|
||||
|
||||
fn get(&self) -> Option<tokio::sync::mpsc::UnboundedSender<T>> {
|
||||
fn get(&self) -> Option<mpsc::UnboundedSender<T>> {
|
||||
self.origin.read().unwrap().clone()
|
||||
}
|
||||
|
||||
|
@ -260,20 +264,22 @@ impl<T> ClosableSender<T> {
|
|||
|
||||
struct XTelegramBotApiSecretToken(Option<Vec<u8>>);
|
||||
|
||||
impl<B> FromRequest<B> for XTelegramBotApiSecretToken {
|
||||
impl<S> FromRequestParts<S> for XTelegramBotApiSecretToken {
|
||||
type Rejection = StatusCode;
|
||||
|
||||
fn from_request<'l0, 'at>(
|
||||
req: &'l0 mut RequestParts<B>,
|
||||
fn from_request_parts<'l0, 'l1, 'at>(
|
||||
req: &'l0 mut Parts,
|
||||
_state: &'l1 S,
|
||||
) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'at>>
|
||||
where
|
||||
'l0: 'at,
|
||||
'l1: 'at,
|
||||
Self: 'at,
|
||||
{
|
||||
use crate::dispatching::update_listeners::webhooks::check_secret;
|
||||
|
||||
let res = req
|
||||
.headers_mut()
|
||||
.headers
|
||||
.remove("x-telegram-bot-api-secret-token")
|
||||
.map(|header| {
|
||||
check_secret(header.as_bytes())
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
//!
|
||||
//! [[`examples/throw_dice.rs`](https://github.com/teloxide/teloxide/blob/master/examples/throw_dice.rs)]
|
||||
//! ```no_run
|
||||
//! # #[cfg(feature = "ctrlc_handler")]
|
||||
//! use teloxide::prelude::*;
|
||||
//!
|
||||
//! # #[cfg(feature = "ctrlc_handler")]
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! pretty_env_logger::init();
|
||||
|
@ -20,7 +22,7 @@
|
|||
//! Ok(())
|
||||
//! })
|
||||
//! .await;
|
||||
//! # }
|
||||
//! # } #[cfg(not(feature = "ctrlc_handler"))] fn main(){}
|
||||
//! ```
|
||||
//!
|
||||
//! <div align="center">
|
||||
|
@ -60,6 +62,7 @@
|
|||
#[cfg(feature = "ctrlc_handler")]
|
||||
pub use dispatching::repls::{repl, repl_with_listener};
|
||||
|
||||
#[cfg(feature = "ctrlc_handler")]
|
||||
#[allow(deprecated)]
|
||||
pub use dispatching::repls::{commands_repl, commands_repl_with_listener};
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@ pub use crate::error_handlers::{LoggingErrorHandler, OnError};
|
|||
pub use crate::respond;
|
||||
|
||||
pub use crate::dispatching::{
|
||||
dialogue::Dialogue, repls::CommandReplExt as _, Dispatcher, HandlerExt as _,
|
||||
MessageFilterExt as _, UpdateFilterExt as _,
|
||||
dialogue::Dialogue, Dispatcher, HandlerExt as _, MessageFilterExt as _, UpdateFilterExt as _,
|
||||
};
|
||||
|
||||
#[cfg(feature = "ctrlc_handler")]
|
||||
pub use crate::dispatching::repls::CommandReplExt as _;
|
||||
|
||||
pub use teloxide_core::{
|
||||
requests::ResponseResult,
|
||||
types::{
|
||||
|
|
Loading…
Reference in a new issue