use std::sync::Arc;
use crate::{
framework::{Dispatcher, DispatcherOpts},
types::Update,
Bot, BotError, Poller, UpdateHandler,
};
pub struct Updater {
bot: Bot,
dispatcher: Arc<Dispatcher>,
poll_timeout: i64,
poll_limit: i64,
allowed_updates: Vec<String>,
#[allow(dead_code)]
webhook_port: u16,
#[allow(dead_code)]
webhook_secret: Option<String>,
}
impl Updater {
pub fn with_opts(bot: Bot, opts: DispatcherOpts) -> Self {
Self::from_dispatcher(bot, Dispatcher::new(opts))
}
pub fn new(bot: Bot, dispatcher: Dispatcher) -> Self {
Self::from_dispatcher(bot, dispatcher)
}
fn from_dispatcher(bot: Bot, dispatcher: Dispatcher) -> Self {
Self {
bot,
dispatcher: Arc::new(dispatcher),
poll_timeout: 30,
poll_limit: 100,
allowed_updates: vec![],
webhook_port: 8080,
webhook_secret: None,
}
}
pub fn poll_timeout(mut self, secs: i64) -> Self {
self.poll_timeout = secs;
self
}
pub fn poll_limit(mut self, limit: i64) -> Self {
self.poll_limit = limit;
self
}
pub fn allowed_updates(mut self, updates: Vec<String>) -> Self {
self.allowed_updates = updates;
self
}
pub fn webhook_port(mut self, port: u16) -> Self {
self.webhook_port = port;
self
}
pub fn webhook_secret(mut self, secret: impl Into<String>) -> Self {
self.webhook_secret = Some(secret.into());
self
}
pub fn bot(&self) -> &Bot {
&self.bot
}
pub async fn start_polling(self) -> Result<(), BotError> {
let dp = Arc::clone(&self.dispatcher);
let bot = self.bot.clone();
let handler: UpdateHandler = Box::new(move |bot: Bot, update: Update| {
let dp2 = Arc::clone(&dp);
Box::pin(async move {
dp2.dispatch(bot, update);
})
});
Poller::new(bot, handler)
.timeout(self.poll_timeout)
.limit(self.poll_limit)
.allowed_updates(self.allowed_updates)
.start()
.await
}
#[cfg(feature = "webhook")]
pub async fn start_webhook(self, webhook_url: impl Into<String>) -> Result<(), BotError> {
use crate::WebhookServer;
let dp = Arc::clone(&self.dispatcher);
let bot = self.bot.clone();
let port = self.webhook_port;
let secret = self.webhook_secret.clone();
let handler: UpdateHandler = Box::new(move |bot: Bot, update: Update| {
let dp2 = Arc::clone(&dp);
Box::pin(async move {
dp2.dispatch(bot, update);
})
});
let mut server = WebhookServer::new(bot, handler).port(port);
if let Some(s) = secret {
server = server.secret_token(s);
}
server.start(webhook_url).await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::framework::{
handler::{Handler, HandlerResult},
Context,
};
use async_trait::async_trait;
#[allow(dead_code)]
struct NoopHandler;
#[async_trait]
impl Handler for NoopHandler {
fn name(&self) -> &str {
"noop"
}
fn check_update(&self, _: &Context) -> bool {
false
}
async fn handle_update(&self, _: Bot, _: Context) -> HandlerResult {
Ok(())
}
}
#[test]
fn updater_builds_from_opts() {
let _ = std::mem::size_of::<Updater>();
}
#[test]
fn builder_setters_compile() {
fn check(bot: Bot, dp: Dispatcher) {
let _ = Updater::new(bot, dp)
.poll_timeout(60)
.poll_limit(50)
.allowed_updates(vec!["message".into()])
.webhook_port(8443)
.webhook_secret("abc");
}
let _ = check; }
}