Struct teloxide::dispatching::Dispatcher
source · [−]pub struct Dispatcher<R, Err, Key> { /* private fields */ }Expand description
The base for update dispatching.
Updates from different chats are handled concurrently, whereas updates from
the same chats are handled sequentially. If the dispatcher is unable to
determine a chat ID of an incoming update, it will be handled concurrently.
Note that this behaviour can be altered with distribution_function.
See also: “Dispatching or REPLs?”
Implementations
sourceimpl<R, Err> Dispatcher<R, Err, DefaultKey>where
R: Requester + Clone + Send + Sync + 'static,
Err: Send + Sync + 'static,
impl<R, Err> Dispatcher<R, Err, DefaultKey>where
R: Requester + Clone + Send + Sync + 'static,
Err: Send + Sync + 'static,
sourcepub fn builder(
bot: R,
handler: UpdateHandler<Err>
) -> DispatcherBuilder<R, Err, DefaultKey>where
Err: Debug,
pub fn builder(
bot: R,
handler: UpdateHandler<Err>
) -> DispatcherBuilder<R, Err, DefaultKey>where
Err: Debug,
Constructs a new DispatcherBuilder with bot and handler.
Examples found in repository?
47 48 49 50 51 52 53 54 55 56 57 58 59
async fn main() {
pretty_env_logger::init();
log::info!("Starting purchase bot...");
let bot = Bot::from_env();
Dispatcher::builder(bot, schema())
.dependencies(dptree::deps![InMemStorage::<State>::new()])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}More examples
22 23 24 25 26 27 28 29 30 31 32 33 34 35
async fn main() -> Result<(), Box<dyn Error>> {
pretty_env_logger::init();
log::info!("Starting buttons bot...");
let bot = Bot::from_env();
let handler = dptree::entry()
.branch(Update::filter_message().endpoint(message_handler))
.branch(Update::filter_callback_query().endpoint(callback_handler))
.branch(Update::filter_inline_query().endpoint(inline_query_handler));
Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
Ok(())
}36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
async fn main() {
pretty_env_logger::init();
log::info!("Starting dialogue bot...");
let bot = Bot::from_env();
Dispatcher::builder(
bot,
Update::filter_message()
.enter_dialogue::<Message, InMemStorage<State>, State>()
.branch(dptree::case![State::Start].endpoint(start))
.branch(dptree::case![State::ReceiveFullName].endpoint(receive_full_name))
.branch(dptree::case![State::ReceiveAge { full_name }].endpoint(receive_age))
.branch(
dptree::case![State::ReceiveLocation { full_name, age }].endpoint(receive_location),
),
)
.dependencies(dptree::deps![InMemStorage::<State>::new()])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
async fn main() {
pretty_env_logger::init();
log::info!("Starting shared state bot...");
let bot = Bot::from_env();
let messages_total = Arc::new(AtomicU64::new(0));
let handler = Update::filter_message().endpoint(
|bot: Bot, messages_total: Arc<AtomicU64>, msg: Message| async move {
let previous = messages_total.fetch_add(1, Ordering::Relaxed);
bot.send_message(msg.chat.id, format!("I received {previous} messages in total."))
.await?;
respond(())
},
);
Dispatcher::builder(bot, handler)
// Pass the shared state to the handler as a dependency.
.dependencies(dptree::deps![messages_total])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
async fn main() {
pretty_env_logger::init();
log::info!("Starting DB remember bot...");
let bot = Bot::from_env();
let storage: MyStorage = if std::env::var("DB_REMEMBER_REDIS").is_ok() {
RedisStorage::open("redis://127.0.0.1:6379", Bincode).await.unwrap().erase()
} else {
SqliteStorage::open("db.sqlite", Json).await.unwrap().erase()
};
let handler = Update::filter_message()
.enter_dialogue::<Message, ErasedStorage<State>, State>()
.branch(dptree::case![State::Start].endpoint(start))
.branch(
dptree::case![State::GotNumber(n)]
.branch(dptree::entry().filter_command::<Command>().endpoint(got_number))
.branch(dptree::endpoint(invalid_command)),
);
Dispatcher::builder(bot, handler)
.dependencies(dptree::deps![storage])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
async fn main() {
pretty_env_logger::init();
log::info!("Starting inline bot...");
let bot = Bot::from_env();
let handler = Update::filter_inline_query().branch(dptree::endpoint(
|bot: Bot, q: InlineQuery| async move {
// First, create your actual response
let google_search = InlineQueryResultArticle::new(
// Each item needs a unique ID, as well as the response container for the
// items. These can be whatever, as long as they don't
// conflict.
"01".to_string(),
// What the user will actually see
"Google Search",
// What message will be sent when clicked/tapped
InputMessageContent::Text(InputMessageContentText::new(format!(
"https://www.google.com/search?q={}",
q.query,
))),
);
// While constructing them from the struct itself is possible, it is preferred
// to use the builder pattern if you wish to add more
// information to your result. Please refer to the documentation
// for more detailed information about each field. https://docs.rs/teloxide/latest/teloxide/types/struct.InlineQueryResultArticle.html
let ddg_search = InlineQueryResultArticle::new(
"02".to_string(),
"DuckDuckGo Search".to_string(),
InputMessageContent::Text(InputMessageContentText::new(format!(
"https://duckduckgo.com/?q={}",
q.query
))),
)
.description("DuckDuckGo Search")
.thumb_url("https://duckduckgo.com/assets/logo_header.v108.png".parse().unwrap())
.url("https://duckduckgo.com/about".parse().unwrap()); // Note: This is the url that will open if they click the thumbnail
let results = vec![
InlineQueryResult::Article(google_search),
InlineQueryResult::Article(ddg_search),
];
// Send it off! One thing to note -- the ID we use here must be of the query
// we're responding to.
let response = bot.answer_inline_query(&q.id, results).send().await;
if let Err(err) = response {
log::error!("Error in handler: {:?}", err);
}
respond(())
},
));
Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
}sourceimpl<R, Err, Key> Dispatcher<R, Err, Key>where
R: Requester + Clone + Send + Sync + 'static,
Err: Send + Sync + 'static,
Key: Hash + Eq + Clone,
impl<R, Err, Key> Dispatcher<R, Err, Key>where
R: Requester + Clone + Send + Sync + 'static,
Err: Send + Sync + 'static,
Key: Hash + Eq + Clone,
sourcepub async fn dispatch(&mut self)where
R: Requester + Clone,
<R as Requester>::GetUpdates: Send,
pub async fn dispatch(&mut self)where
R: Requester + Clone,
<R as Requester>::GetUpdates: Send,
Starts your bot with the default parameters.
The default parameters are a long polling update listener and log all errors produced by this listener.
Each time a handler is invoked, Dispatcher adds the following
dependencies (in addition to those passed to
DispatcherBuilder::dependencies):
- Your bot passed to
Dispatcher::builder; - An update from Telegram;
crate::types::Me(can be used inHandlerExt::filter_command).
Examples found in repository?
47 48 49 50 51 52 53 54 55 56 57 58 59
async fn main() {
pretty_env_logger::init();
log::info!("Starting purchase bot...");
let bot = Bot::from_env();
Dispatcher::builder(bot, schema())
.dependencies(dptree::deps![InMemStorage::<State>::new()])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}More examples
22 23 24 25 26 27 28 29 30 31 32 33 34 35
async fn main() -> Result<(), Box<dyn Error>> {
pretty_env_logger::init();
log::info!("Starting buttons bot...");
let bot = Bot::from_env();
let handler = dptree::entry()
.branch(Update::filter_message().endpoint(message_handler))
.branch(Update::filter_callback_query().endpoint(callback_handler))
.branch(Update::filter_inline_query().endpoint(inline_query_handler));
Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
Ok(())
}36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
async fn main() {
pretty_env_logger::init();
log::info!("Starting dialogue bot...");
let bot = Bot::from_env();
Dispatcher::builder(
bot,
Update::filter_message()
.enter_dialogue::<Message, InMemStorage<State>, State>()
.branch(dptree::case![State::Start].endpoint(start))
.branch(dptree::case![State::ReceiveFullName].endpoint(receive_full_name))
.branch(dptree::case![State::ReceiveAge { full_name }].endpoint(receive_age))
.branch(
dptree::case![State::ReceiveLocation { full_name, age }].endpoint(receive_location),
),
)
.dependencies(dptree::deps![InMemStorage::<State>::new()])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
async fn main() {
pretty_env_logger::init();
log::info!("Starting shared state bot...");
let bot = Bot::from_env();
let messages_total = Arc::new(AtomicU64::new(0));
let handler = Update::filter_message().endpoint(
|bot: Bot, messages_total: Arc<AtomicU64>, msg: Message| async move {
let previous = messages_total.fetch_add(1, Ordering::Relaxed);
bot.send_message(msg.chat.id, format!("I received {previous} messages in total."))
.await?;
respond(())
},
);
Dispatcher::builder(bot, handler)
// Pass the shared state to the handler as a dependency.
.dependencies(dptree::deps![messages_total])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
async fn main() {
pretty_env_logger::init();
log::info!("Starting DB remember bot...");
let bot = Bot::from_env();
let storage: MyStorage = if std::env::var("DB_REMEMBER_REDIS").is_ok() {
RedisStorage::open("redis://127.0.0.1:6379", Bincode).await.unwrap().erase()
} else {
SqliteStorage::open("db.sqlite", Json).await.unwrap().erase()
};
let handler = Update::filter_message()
.enter_dialogue::<Message, ErasedStorage<State>, State>()
.branch(dptree::case![State::Start].endpoint(start))
.branch(
dptree::case![State::GotNumber(n)]
.branch(dptree::entry().filter_command::<Command>().endpoint(got_number))
.branch(dptree::endpoint(invalid_command)),
);
Dispatcher::builder(bot, handler)
.dependencies(dptree::deps![storage])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
async fn main() {
pretty_env_logger::init();
log::info!("Starting inline bot...");
let bot = Bot::from_env();
let handler = Update::filter_inline_query().branch(dptree::endpoint(
|bot: Bot, q: InlineQuery| async move {
// First, create your actual response
let google_search = InlineQueryResultArticle::new(
// Each item needs a unique ID, as well as the response container for the
// items. These can be whatever, as long as they don't
// conflict.
"01".to_string(),
// What the user will actually see
"Google Search",
// What message will be sent when clicked/tapped
InputMessageContent::Text(InputMessageContentText::new(format!(
"https://www.google.com/search?q={}",
q.query,
))),
);
// While constructing them from the struct itself is possible, it is preferred
// to use the builder pattern if you wish to add more
// information to your result. Please refer to the documentation
// for more detailed information about each field. https://docs.rs/teloxide/latest/teloxide/types/struct.InlineQueryResultArticle.html
let ddg_search = InlineQueryResultArticle::new(
"02".to_string(),
"DuckDuckGo Search".to_string(),
InputMessageContent::Text(InputMessageContentText::new(format!(
"https://duckduckgo.com/?q={}",
q.query
))),
)
.description("DuckDuckGo Search")
.thumb_url("https://duckduckgo.com/assets/logo_header.v108.png".parse().unwrap())
.url("https://duckduckgo.com/about".parse().unwrap()); // Note: This is the url that will open if they click the thumbnail
let results = vec![
InlineQueryResult::Article(google_search),
InlineQueryResult::Article(ddg_search),
];
// Send it off! One thing to note -- the ID we use here must be of the query
// we're responding to.
let response = bot.answer_inline_query(&q.id, results).send().await;
if let Err(err) = response {
log::error!("Error in handler: {:?}", err);
}
respond(())
},
));
Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
}sourcepub async fn dispatch_with_listener<'a, UListener, Eh>(
&'a mut self,
update_listener: UListener,
update_listener_error_handler: Arc<Eh>
)where
UListener: UpdateListener + 'a,
Eh: ErrorHandler<UListener::Err> + 'a,
UListener::Err: Debug,
pub async fn dispatch_with_listener<'a, UListener, Eh>(
&'a mut self,
update_listener: UListener,
update_listener_error_handler: Arc<Eh>
)where
UListener: UpdateListener + 'a,
Eh: ErrorHandler<UListener::Err> + 'a,
UListener::Err: Debug,
Starts your bot with custom update_listener and
update_listener_error_handler.
This method adds the same dependencies as Dispatcher::dispatch.
sourcepub fn setup_ctrlc_handler(&mut self) -> &mut Self
👎Deprecated since 0.10.0: use enable_ctrlc_handler on builder insteadAvailable on crate feature ctrlc_handler only.
pub fn setup_ctrlc_handler(&mut self) -> &mut Self
enable_ctrlc_handler on builder insteadctrlc_handler only.Setups the ^C handler that shutdowns dispatching.
sourcepub fn shutdown_token(&self) -> ShutdownToken
pub fn shutdown_token(&self) -> ShutdownToken
Returns a shutdown token, which can later be used to shutdown dispatching.