mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-08 19:33:53 +01:00
Write documentation for webhooks
This commit is contained in:
parent
e951af7abe
commit
4abafbcacc
3 changed files with 92 additions and 7 deletions
|
@ -1,18 +1,20 @@
|
|||
//! Receiving updates from Telegram.
|
||||
//!
|
||||
//! The key trait here is [`UpdateListener`]. You can get its implementation
|
||||
//! using one these functions:
|
||||
//! from:
|
||||
//!
|
||||
//! - [`polling_default`], which returns a default long polling listener.
|
||||
//! - [`polling`], which returns a long polling listener with your
|
||||
//! - [`polling_default`] function, which returns a default long polling
|
||||
//! listener.
|
||||
//! - [`polling`] function, which returns a long polling listener with your
|
||||
//! configuration.
|
||||
//! - Various functions in the [`webhooks`] module that return webhook listeners
|
||||
//!
|
||||
//! And then you can extract updates from it or pass them directly to a
|
||||
//! [`Dispatcher`].
|
||||
//!
|
||||
//! Telegram supports two ways of [getting updates]: [long polling] and
|
||||
//! [webhooks]. Currently, only the former one is implemented (see [`polling()`]
|
||||
//! and [`polling_default`]). See also [README FAQ about webhooks](https://github.com/teloxide/teloxide/blob/master/README.md#faq).
|
||||
//! [webhooks]. For the former see [`polling`] and [`polling_default`], for the
|
||||
//! latter see the [`webhooks`] module.
|
||||
//!
|
||||
//! [`UpdateListener`]: UpdateListener
|
||||
//! [`polling_default`]: polling_default
|
||||
|
@ -23,6 +25,8 @@
|
|||
//! [long polling]: https://en.wikipedia.org/wiki/Push_technology#Long_polling
|
||||
//! [webhooks]: https://en.wikipedia.org/wiki/Webhook
|
||||
|
||||
/// Implementations of webhook update listeners - an alternative (to
|
||||
/// [`fn@polling`]) way of receiving updates from telegram.
|
||||
#[cfg(any(feature = "webhooks-axum"))]
|
||||
pub mod webhooks;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//!
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use crate::{requests::Requester, types::InputFile};
|
||||
|
@ -62,6 +63,9 @@ pub use self::axum::{axum, axum_no_setup, axum_to_router};
|
|||
#[cfg(feature = "webhooks-axum")]
|
||||
mod axum;
|
||||
|
||||
/// Calls `set_webhook` with arguments from `options`.
|
||||
///
|
||||
/// Note: this takes out `certificate`.
|
||||
async fn setup_webhook<R>(bot: R, options: &mut Options) -> Result<(), R::Err>
|
||||
where
|
||||
R: Requester,
|
||||
|
@ -80,6 +84,16 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns first (`.0`) field from a tuple as a `&mut` reference.
|
||||
///
|
||||
/// This hack is needed because there isn't currently a way to easily force a
|
||||
/// closure to be higher-ranked (`for<'a> &'a mut _ -> &'a mut _`) which causes
|
||||
/// problems when using [`StatefulListener`] to implement update listener.
|
||||
///
|
||||
/// This could be probably removed once [rfc#3216] is implemented.
|
||||
///
|
||||
/// [`StatefulListener`]:
|
||||
/// [rfc#3216]: https://github.com/rust-lang/rfcs/pull/3216
|
||||
fn tuple_first_mut<A, B>(tuple: &mut (A, B)) -> &mut A {
|
||||
&mut tuple.0
|
||||
}
|
||||
|
|
|
@ -11,7 +11,16 @@ use crate::{
|
|||
requests::Requester,
|
||||
};
|
||||
|
||||
/// Webhook implementation based on the [axum] framework.
|
||||
/// Webhook implementation based on the [mod@axum] framework.
|
||||
///
|
||||
/// This function does all the work necessary for webhook to work, it:
|
||||
/// - Calls [`set_webhook`], so telegram starts sending updates our way
|
||||
/// - Spawns [mod@axum] server listening for updates
|
||||
/// - When the update listener is [`stop`]ped, calls [`delete_webhook`]
|
||||
///
|
||||
/// [`set_webhook`]: crate::payloads::SetWebhook
|
||||
/// [`delete_webhook`]: crate::payloads::DeleteWebhook
|
||||
/// [`stop`]: StopToken::stop
|
||||
///
|
||||
/// ## Panics
|
||||
///
|
||||
|
@ -19,9 +28,14 @@ use crate::{
|
|||
///
|
||||
/// [address]: Options.address
|
||||
///
|
||||
/// ## Errors
|
||||
/// ## Fails
|
||||
///
|
||||
/// If `set_webhook()` fails.
|
||||
///
|
||||
/// ## See also
|
||||
///
|
||||
/// [`axum_to_router`] and [`axum_no_setup`] for lower-level versions of this
|
||||
/// function.
|
||||
pub async fn axum<R>(
|
||||
bot: R,
|
||||
options: Options,
|
||||
|
@ -50,6 +64,47 @@ where
|
|||
Ok(update_listener)
|
||||
}
|
||||
|
||||
/// Webhook implementation based on the [mod@axum] framework that can reuse
|
||||
/// existing [mod@axum] server.
|
||||
///
|
||||
/// This function does most of the work necessary for webhook to work, it:
|
||||
/// - Calls [`set_webhook`], so telegram starts sending updates our way
|
||||
/// - When the update listener is [`stop`]ped, calls [`delete_webhook`]
|
||||
///
|
||||
/// The only missing part is running [mod@axum] server with a returned
|
||||
/// [`axum::Router`].
|
||||
///
|
||||
/// This function is intended to be used in cases when you already have an
|
||||
/// [mod@axum] server running and can reuse it for webhooks.
|
||||
///
|
||||
/// **Note**: in order for webhooks to work, you need to use returned
|
||||
/// [`axum::Router`] in an [mod@axum] server that is bound to
|
||||
/// [`options.address`].
|
||||
///
|
||||
/// It may also be desired to use [`with_graceful_shutdown`] with the returned
|
||||
/// future in order to shutdown the server with the [`stop`] of the listener.
|
||||
///
|
||||
/// [`set_webhook`]: crate::payloads::SetWebhook
|
||||
/// [`delete_webhook`]: crate::payloads::DeleteWebhook
|
||||
/// [`stop`]: StopToken::stop
|
||||
/// [`options.address`]: Options.address
|
||||
/// [`with_graceful_shutdown`]: axum::Server::with_graceful_shutdown
|
||||
///
|
||||
/// ## Returns
|
||||
///
|
||||
/// A update listener, stop-future, axum router triplet on success.
|
||||
///
|
||||
/// The "stop-future" is resolved after [`stop`] is called on the stop token of
|
||||
/// the returned update listener.
|
||||
///
|
||||
/// ## Fails
|
||||
///
|
||||
/// If `set_webhook()` fails.
|
||||
///
|
||||
/// ## See also
|
||||
///
|
||||
/// [`fn@axum`] for higher-level and [`axum_no_setup`] for lower-level
|
||||
/// versions of this function.
|
||||
pub async fn axum_to_router<R>(
|
||||
bot: R,
|
||||
mut options: Options,
|
||||
|
@ -85,6 +140,13 @@ where
|
|||
Ok((listener, stop_flag, router))
|
||||
}
|
||||
|
||||
/// Webhook implementation based on the [mod@axum] framework that doesn't
|
||||
/// perform any setup work.
|
||||
///
|
||||
/// ## See also
|
||||
///
|
||||
/// [`fn@axum`] and [`axum_to_router`] for higher-level versions of this
|
||||
/// function.
|
||||
pub fn axum_no_setup(
|
||||
options: Options,
|
||||
) -> (
|
||||
|
@ -110,6 +172,10 @@ pub fn axum_no_setup(
|
|||
let (tx, rx): (Sender, _) = mpsc::unbounded_channel();
|
||||
|
||||
async fn telegram_request(input: String, tx: Extension<Sender>) -> impl IntoResponse {
|
||||
// FIXME: this should probably start returning an error response after `.stop()`
|
||||
// is called to account for cases when update listener is stopped without
|
||||
// stopping the server
|
||||
|
||||
match serde_json::from_str(&input) {
|
||||
Ok(update) => {
|
||||
tx.send(Ok(update)).expect("Cannot send an incoming update from the webhook")
|
||||
|
@ -139,6 +205,7 @@ pub fn axum_no_setup(
|
|||
|
||||
let stream = UnboundedReceiverStream::new(rx);
|
||||
|
||||
// FIXME: this should support `hint_allowed_updates()`
|
||||
let listener = update_listeners::StatefulListener::new(
|
||||
(stream, stop_token),
|
||||
tuple_first_mut,
|
||||
|
|
Loading…
Reference in a new issue