Implement webhooks

This commit is contained in:
Temirkhan Myrzamadi 2020-03-30 18:41:20 +06:00
parent e0ab813554
commit 6e486f0d78
3 changed files with 49 additions and 10 deletions

View file

@ -47,6 +47,8 @@ serde_with_macros = "1.0.1"
teloxide-macros = "0.2.1"
warp = "0.2.2"
[dev-dependencies]
smart-default = "0.6.0"
rand = "0.7.3"

View file

@ -101,14 +101,24 @@
//! [webhook]: https://en.wikipedia.org/wiki/Webhook
use futures::{stream, Stream, StreamExt};
use tokio::sync::mpsc;
use warp::Filter;
use crate::{
bot::Bot,
prelude::ResponseResult,
requests::Request,
types::{AllowedUpdate, Update},
types::{AllowedUpdate, InputFile, Update},
RequestError,
};
use std::{convert::TryInto, sync::Arc, time::Duration};
use reqwest::Url;
use std::{
convert::{Infallible, TryInto},
net::SocketAddr,
sync::Arc,
time::Duration,
};
/// A generic update listener.
pub trait UpdateListener<E>: Stream<Item = Result<Update, E>> {
@ -198,7 +208,34 @@ pub fn polling(
.flatten()
}
// TODO implement webhook (this actually require webserver and probably we
// should add cargo feature that adds webhook)
//pub fn webhook<'a>(bot: &'a cfg: WebhookConfig) -> Updater<impl
// Stream<Item=Result<Update, ???>> + 'a> {}
pub async fn webhook(
bot: Arc<Bot>,
addr: SocketAddr,
url: Url,
certificate: Option<InputFile>,
max_connections: Option<i32>,
allowed_updates: Option<Vec<AllowedUpdate>>,
) -> ResponseResult<impl UpdateListener<Infallible>> {
let mut webhook = bot.set_webhook(url.to_string());
webhook.certificate = certificate;
webhook.max_connections = max_connections;
webhook.allowed_updates = allowed_updates;
webhook.send().await?;
let (tx, rx) = mpsc::unbounded_channel();
let server = warp::post().and(warp::path(url)).and(warp::body::json()).map(
move |update: Update| {
tx.send(Ok(update.clone()))
.expect("Cannot send an update from webhook");
""
},
);
tokio::spawn(async move {
// TODO: Tls
warp::serve(server).run(addr).await;
});
Ok(rx)
}

View file

@ -29,10 +29,10 @@ use std::sync::Arc;
pub struct SetWebhook {
#[serde(skip_serializing)]
bot: Arc<Bot>,
url: String,
certificate: Option<InputFile>,
max_connections: Option<i32>,
allowed_updates: Option<Vec<AllowedUpdate>>,
pub(crate) url: String,
pub(crate) certificate: Option<InputFile>,
pub(crate) max_connections: Option<i32>,
pub(crate) allowed_updates: Option<Vec<AllowedUpdate>>,
}
#[async_trait::async_trait]