1use crate::{
4 contexts, errors,
5 state::StatefulEventLoop,
6 types::{
7 self, callback,
8 message::{
9 self,
10 text::{Entity, EntityKind, Text},
11 Message,
12 },
13 update,
14 },
15 Bot,
16};
17use std::{collections::HashMap, future::Future, sync::Arc};
18use tracing::{error, instrument, trace, warn};
19
20#[macro_use]
21mod handlers_macros;
22
23mod polling;
24pub mod webhook;
25
26pub use {polling::Polling, webhook::Webhook};
27
28type Handlers<T> = Vec<Box<T>>;
29type Map<T> = HashMap<String, Handlers<T>>;
30
31type Handler<T> = dyn Fn(Arc<T>) + Send + Sync;
33
34type AnimationHandler = Handler<contexts::Animation>;
35type AudioHandler = Handler<contexts::Audio>;
36type ChosenInlineHandler = Handler<contexts::ChosenInline>;
37type CommandHandler = Handler<contexts::Command<contexts::Text>>;
38type ConnectedWebsiteHandler = Handler<contexts::ConnectedWebsite>;
39type ContactHandler = Handler<contexts::Contact>;
40type CreatedGroupHandler = Handler<contexts::CreatedGroup>;
41type DataCallbackHandler = Handler<contexts::DataCallback>;
42type DeletedChatPhotoHandler = Handler<contexts::DeletedChatPhoto>;
43type DiceHandler = Handler<contexts::Dice>;
44type DocumentHandler = Handler<contexts::Document>;
45type EditedAnimationHandler = Handler<contexts::EditedAnimation>;
46type EditedAudioHandler = Handler<contexts::EditedAudio>;
47type EditedCommandHandler = Handler<contexts::Command<contexts::EditedText>>;
48type EditedDocumentHandler = Handler<contexts::EditedDocument>;
49type EditedLocationHandler = Handler<contexts::EditedLocation>;
50type EditedPhotoHandler = Handler<contexts::EditedPhoto>;
51type EditedTextHandler = Handler<contexts::EditedText>;
52type EditedVideoHandler = Handler<contexts::EditedVideo>;
53type GameCallbackHandler = Handler<contexts::GameCallback>;
54type GameHandler = Handler<contexts::Game>;
55type InlineHandler = Handler<contexts::Inline>;
56type InvoiceHandler = Handler<contexts::Invoice>;
57type LeftMemberHandler = Handler<contexts::LeftMember>;
58type LocationHandler = Handler<contexts::Location>;
59type MigrationHandler = Handler<contexts::Migration>;
60type NewChatPhotoHandler = Handler<contexts::NewChatPhoto>;
61type NewChatTitleHandler = Handler<contexts::NewChatTitle>;
62type NewMembersHandler = Handler<contexts::NewMembers>;
63type PassportHandler = Handler<contexts::Passport>;
64type PaymentHandler = Handler<contexts::Payment>;
65type PhotoHandler = Handler<contexts::Photo>;
66type PinnedMessageHandler = Handler<contexts::PinnedMessage>;
67type PollHandler = Handler<contexts::Poll>;
68type PollAnswerHandler = Handler<contexts::PollAnswer>;
69type PreCheckoutHandler = Handler<contexts::PreCheckout>;
70type ShippingHandler = Handler<contexts::Shipping>;
71type StickerHandler = Handler<contexts::Sticker>;
72type TextHandler = Handler<contexts::Text>;
73type UnhandledHandler = Handler<contexts::Unhandled>;
74type UpdatedPollHandler = Handler<contexts::UpdatedPoll>;
75type UpdateHandler = Handler<contexts::Update>;
76type VenueHandler = Handler<contexts::Venue>;
77type VideoHandler = Handler<contexts::Video>;
78type VideoNoteHandler = Handler<contexts::VideoNote>;
79type VoiceHandler = Handler<contexts::Voice>;
80
81#[must_use]
101pub struct EventLoop {
102 bot: Bot,
103 username: Option<String>,
104
105 command_handlers: Map<CommandHandler>,
106 edited_command_handlers: Map<EditedCommandHandler>,
107 after_update_handlers: Handlers<UpdateHandler>,
108 animation_handlers: Handlers<AnimationHandler>,
109 audio_handlers: Handlers<AudioHandler>,
110 before_update_handlers: Handlers<UpdateHandler>,
111 chosen_inline_handlers: Handlers<ChosenInlineHandler>,
112 contact_handlers: Handlers<ContactHandler>,
113 connected_website_handlers: Handlers<ConnectedWebsiteHandler>,
114 created_group_handlers: Handlers<CreatedGroupHandler>,
115 data_callback_handlers: Handlers<DataCallbackHandler>,
116 deleted_chat_photo_handlers: Handlers<DeletedChatPhotoHandler>,
117 dice_handlers: Handlers<DiceHandler>,
118 document_handlers: Handlers<DocumentHandler>,
119 edited_animation_handlers: Handlers<EditedAnimationHandler>,
120 edited_audio_handlers: Handlers<EditedAudioHandler>,
121 edited_document_handlers: Handlers<EditedDocumentHandler>,
122 edited_location_handlers: Handlers<EditedLocationHandler>,
123 edited_photo_handlers: Handlers<EditedPhotoHandler>,
124 edited_text_handlers: Handlers<EditedTextHandler>,
125 edited_video_handlers: Handlers<EditedVideoHandler>,
126 game_callback_handlers: Handlers<GameCallbackHandler>,
127 game_handlers: Handlers<GameHandler>,
128 inline_handlers: Handlers<InlineHandler>,
129 invoice_handlers: Handlers<InvoiceHandler>,
130 left_member_handlers: Handlers<LeftMemberHandler>,
131 location_handlers: Handlers<LocationHandler>,
132 migration_handlers: Handlers<MigrationHandler>,
133 new_chat_photo_handlers: Handlers<NewChatPhotoHandler>,
134 new_chat_title_handlers: Handlers<NewChatTitleHandler>,
135 new_members_handlers: Handlers<NewMembersHandler>,
136 passport_handlers: Handlers<PassportHandler>,
137 payment_handlers: Handlers<PaymentHandler>,
138 photo_handlers: Handlers<PhotoHandler>,
139 pinned_message_handlers: Handlers<PinnedMessageHandler>,
140 poll_handlers: Handlers<PollHandler>,
141 poll_answer_handlers: Handlers<PollAnswerHandler>,
142 pre_checkout_handlers: Handlers<PreCheckoutHandler>,
143 shipping_handlers: Handlers<ShippingHandler>,
144 sticker_handlers: Handlers<StickerHandler>,
145 text_handlers: Handlers<TextHandler>,
146 unhandled_handlers: Handlers<UnhandledHandler>,
147 updated_poll_handlers: Handlers<UpdatedPollHandler>,
148 venue_handlers: Handlers<VenueHandler>,
149 video_handlers: Handlers<VideoHandler>,
150 video_note_handlers: Handlers<VideoNoteHandler>,
151 voice_handlers: Handlers<VoiceHandler>,
152}
153
154impl EventLoop {
155 pub(crate) fn new(bot: Bot) -> Self {
156 Self {
157 bot,
158 username: None,
159 command_handlers: HashMap::new(),
160 edited_command_handlers: HashMap::new(),
161 after_update_handlers: Vec::new(),
162 animation_handlers: Vec::new(),
163 audio_handlers: Vec::new(),
164 before_update_handlers: Vec::new(),
165 chosen_inline_handlers: Vec::new(),
166 contact_handlers: Vec::new(),
167 connected_website_handlers: Vec::new(),
168 created_group_handlers: Vec::new(),
169 data_callback_handlers: Vec::new(),
170 deleted_chat_photo_handlers: Vec::new(),
171 dice_handlers: Vec::new(),
172 document_handlers: Vec::new(),
173 edited_animation_handlers: Vec::new(),
174 edited_audio_handlers: Vec::new(),
175 edited_document_handlers: Vec::new(),
176 edited_location_handlers: Vec::new(),
177 edited_photo_handlers: Vec::new(),
178 edited_text_handlers: Vec::new(),
179 edited_video_handlers: Vec::new(),
180 game_callback_handlers: Vec::new(),
181 game_handlers: Vec::new(),
182 inline_handlers: Vec::new(),
183 invoice_handlers: Vec::new(),
184 left_member_handlers: Vec::new(),
185 location_handlers: Vec::new(),
186 migration_handlers: Vec::new(),
187 new_chat_photo_handlers: Vec::new(),
188 new_chat_title_handlers: Vec::new(),
189 new_members_handlers: Vec::new(),
190 passport_handlers: Vec::new(),
191 payment_handlers: Vec::new(),
192 photo_handlers: Vec::new(),
193 pinned_message_handlers: Vec::new(),
194 poll_handlers: Vec::new(),
195 poll_answer_handlers: Vec::new(),
196 pre_checkout_handlers: Vec::new(),
197 shipping_handlers: Vec::new(),
198 sticker_handlers: Vec::new(),
199 text_handlers: Vec::new(),
200 unhandled_handlers: Vec::new(),
201 updated_poll_handlers: Vec::new(),
202 venue_handlers: Vec::new(),
203 video_handlers: Vec::new(),
204 video_note_handlers: Vec::new(),
205 voice_handlers: Vec::new(),
206 }
207 }
208
209 pub fn into_stateful<S>(self, state: S) -> StatefulEventLoop<S>
212 where
213 S: Send + Sync + 'static,
214 {
215 StatefulEventLoop::new(self, state)
216 }
217
218 pub fn username(&mut self, username: String) {
223 self.username = Some(username);
224 }
225
226 pub fn polling(self) -> Polling {
228 Polling::new(self)
229 }
230
231 pub fn webhook(self, url: &str, port: u16) -> Webhook<'_> {
237 Webhook::new(self, url, port)
238 }
239
240 pub fn command<H, F>(&mut self, command: &'static str, handler: H)
249 where
250 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> F)
251 + Send
252 + Sync
253 + 'static,
254 F: Future<Output = ()> + Send + 'static,
255 {
256 self.command_handlers
257 .entry(command.to_string())
258 .or_insert_with(Vec::new)
259 .push(Box::new(move |context| {
260 tokio::spawn(handler(context));
261 }));
262 }
263
264 pub fn command_if<H, HF, P, PF>(
274 &mut self,
275 command: &'static str,
276 predicate: P,
277 handler: H,
278 ) where
279 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> HF)
280 + Send
281 + Sync
282 + 'static,
283 HF: Future<Output = ()> + Send + 'static,
284 P: (Fn(Arc<contexts::Command<contexts::Text>>) -> PF)
285 + Send
286 + Sync
287 + 'static,
288 PF: Future<Output = bool> + Send + 'static,
289 {
290 let predicate = Arc::new(predicate);
291 let handler = Arc::new(handler);
292 self.command(command, move |context| {
293 let predicate = Arc::clone(&predicate);
294 let handler = Arc::clone(&handler);
295 async move {
296 if predicate(Arc::clone(&context)).await {
297 handler(context).await
298 }
299 }
300 });
301 }
302
303 pub fn commands<Cm, H, F>(&mut self, commands: Cm, handler: H)
312 where
313 Cm: IntoIterator<Item = &'static str>,
314 F: Future<Output = ()> + Send + 'static,
315 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> F)
316 + Send
317 + Sync
318 + 'static,
319 {
320 let handler = Arc::new(handler);
321
322 for command in commands {
323 let handler = Arc::clone(&handler);
324 self.command_handlers
325 .entry(command.to_string())
326 .or_insert_with(Vec::new)
327 .push(Box::new(move |context| {
328 tokio::spawn(handler(context));
329 }));
330 }
331 }
332
333 pub fn commands_if<Cm, H, HF, P, PF>(
343 &mut self,
344 commands: Cm,
345 predicate: P,
346 handler: H,
347 ) where
348 Cm: IntoIterator<Item = &'static str>,
349 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> HF)
350 + Send
351 + Sync
352 + 'static,
353 HF: Future<Output = ()> + Send + 'static,
354 P: (Fn(Arc<contexts::Command<contexts::Text>>) -> PF)
355 + Send
356 + Sync
357 + 'static,
358 PF: Future<Output = bool> + Send + 'static,
359 {
360 let predicate = Arc::new(predicate);
361 let handler = Arc::new(handler);
362 self.commands(commands, move |context| {
363 let predicate = Arc::clone(&predicate);
364 let handler = Arc::clone(&handler);
365 async move {
366 if predicate(Arc::clone(&context)).await {
367 handler(context).await
368 }
369 }
370 });
371 }
372
373 fn will_handle_command(&self, command: &str) -> bool {
374 self.command_handlers.contains_key(command)
375 }
376
377 fn run_command_handlers(
378 &self,
379 command: &str,
380 context: &Arc<contexts::Command<contexts::Text>>,
381 ) {
382 if let Some(handlers) = self.command_handlers.get(command) {
383 for handler in handlers {
384 handler(context.clone());
385 }
386 }
387 }
388
389 pub fn start<H, F>(&mut self, handler: H)
391 where
392 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> F)
393 + Send
394 + Sync
395 + 'static,
396 F: Future<Output = ()> + Send + 'static,
397 {
398 self.command("start", handler);
399 }
400
401 pub fn start_if<H, HF, P, PF>(&mut self, predicate: P, handler: H)
404 where
405 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> HF)
406 + Send
407 + Sync
408 + 'static,
409 HF: Future<Output = ()> + Send + 'static,
410 P: (Fn(Arc<contexts::Command<contexts::Text>>) -> PF)
411 + Send
412 + Sync
413 + 'static,
414 PF: Future<Output = bool> + Send + 'static,
415 {
416 let predicate = Arc::new(predicate);
417 let handler = Arc::new(handler);
418 self.start(move |context| {
419 let predicate = Arc::clone(&predicate);
420 let handler = Arc::clone(&handler);
421 async move {
422 if predicate(Arc::clone(&context)).await {
423 handler(context).await
424 }
425 }
426 });
427 }
428
429 pub fn settings<H, F>(&mut self, handler: H)
431 where
432 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> F)
433 + Send
434 + Sync
435 + 'static,
436 F: Future<Output = ()> + Send + 'static,
437 {
438 self.command("settings", handler);
439 }
440
441 pub fn settings_if<H, HF, P, PF>(&mut self, predicate: P, handler: H)
444 where
445 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> HF)
446 + Send
447 + Sync
448 + 'static,
449 HF: Future<Output = ()> + Send + 'static,
450 P: (Fn(Arc<contexts::Command<contexts::Text>>) -> PF)
451 + Send
452 + Sync
453 + 'static,
454 PF: Future<Output = bool> + Send + 'static,
455 {
456 let predicate = Arc::new(predicate);
457 let handler = Arc::new(handler);
458 self.settings(move |context| {
459 let predicate = Arc::clone(&predicate);
460 let handler = Arc::clone(&handler);
461 async move {
462 if predicate(Arc::clone(&context)).await {
463 handler(context).await
464 }
465 }
466 });
467 }
468
469 pub fn help<H, F>(&mut self, handler: H)
471 where
472 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> F)
473 + Send
474 + Sync
475 + 'static,
476 F: Future<Output = ()> + Send + 'static,
477 {
478 self.command("help", handler);
479 }
480
481 pub fn help_if<H, HF, P, PF>(&mut self, predicate: P, handler: H)
484 where
485 H: (Fn(Arc<contexts::Command<contexts::Text>>) -> HF)
486 + Send
487 + Sync
488 + 'static,
489 HF: Future<Output = ()> + Send + 'static,
490 P: (Fn(Arc<contexts::Command<contexts::Text>>) -> PF)
491 + Send
492 + Sync
493 + 'static,
494 PF: Future<Output = bool> + Send + 'static,
495 {
496 let predicate = Arc::new(predicate);
497 let handler = Arc::new(handler);
498 self.help(move |context| {
499 let predicate = Arc::clone(&predicate);
500 let handler = Arc::clone(&handler);
501 async move {
502 if predicate(Arc::clone(&context)).await {
503 handler(context).await
504 }
505 }
506 });
507 }
508
509 pub fn edited_command<H, F>(&mut self, command: &'static str, handler: H)
511 where
512 H: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> F)
513 + Send
514 + Sync
515 + 'static,
516 F: Future<Output = ()> + Send + 'static,
517 {
518 self.edited_command_handlers
519 .entry(command.to_string())
520 .or_insert_with(Vec::new)
521 .push(Box::new(move |context| {
522 tokio::spawn(handler(context));
523 }));
524 }
525
526 pub fn edited_command_if<H, HF, P, PF>(
529 &mut self,
530 command: &'static str,
531 predicate: P,
532 handler: H,
533 ) where
534 H: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> HF)
535 + Send
536 + Sync
537 + 'static,
538 HF: Future<Output = ()> + Send + 'static,
539 P: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> PF)
540 + Send
541 + Sync
542 + 'static,
543 PF: Future<Output = bool> + Send + 'static,
544 {
545 let predicate = Arc::new(predicate);
546 let handler = Arc::new(handler);
547 self.edited_command(command, move |context| {
548 let predicate = Arc::clone(&predicate);
549 let handler = Arc::clone(&handler);
550 async move {
551 if predicate(Arc::clone(&context)).await {
552 handler(context).await
553 }
554 }
555 });
556 }
557
558 pub fn edited_commands<Cm, H, F>(&mut self, commands: Cm, handler: H)
560 where
561 Cm: IntoIterator<Item = &'static str>,
562 F: Future<Output = ()> + Send + 'static,
563 H: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> F)
564 + Send
565 + Sync
566 + 'static,
567 {
568 let handler = Arc::new(handler);
569
570 for command in commands {
571 let handler = Arc::clone(&handler);
572 self.edited_command_handlers
573 .entry(command.to_string())
574 .or_insert_with(Vec::new)
575 .push(Box::new(move |context| {
576 tokio::spawn(handler(context));
577 }));
578 }
579 }
580
581 pub fn edited_commands_if<Cm, H, HF, P, PF>(
584 &mut self,
585 commands: Cm,
586 predicate: P,
587 handler: H,
588 ) where
589 Cm: IntoIterator<Item = &'static str>,
590 H: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> HF)
591 + Send
592 + Sync
593 + 'static,
594 HF: Future<Output = ()> + Send + 'static,
595 P: (Fn(Arc<contexts::Command<contexts::EditedText>>) -> PF)
596 + Send
597 + Sync
598 + 'static,
599 PF: Future<Output = bool> + Send + 'static,
600 {
601 let predicate = Arc::new(predicate);
602 let handler = Arc::new(handler);
603 self.edited_commands(commands, move |context| {
604 let predicate = Arc::clone(&predicate);
605 let handler = Arc::clone(&handler);
606 async move {
607 if predicate(Arc::clone(&context)).await {
608 handler(context).await
609 }
610 }
611 });
612 }
613
614 fn will_handle_edited_command(&self, command: &str) -> bool {
615 self.edited_command_handlers.contains_key(command)
616 }
617
618 fn run_edited_command_handlers(
619 &self,
620 command: &str,
621 context: &Arc<contexts::Command<contexts::EditedText>>,
622 ) {
623 if let Some(handlers) = self.edited_command_handlers.get(command) {
624 for handler in handlers {
625 handler(context.clone());
626 }
627 }
628 }
629
630 handler! {
631 contexts::Update,
632 after_update,
634 after_update_if,
637 }
638
639 handler! {
640 contexts::Animation,
641 animation,
643 animation_if,
646 }
647
648 handler! {
649 contexts::Audio,
650 audio,
652 audio_if,
655 }
656
657 handler! {
658 contexts::Update,
659 before_update,
661 before_update_if,
664 }
665
666 handler! {
667 contexts::ChosenInline,
668 chosen_inline,
670 chosen_inline_if,
673 }
674
675 handler! {
676 contexts::Contact,
677 contact,
679 contact_if,
682 }
683
684 handler! {
685 contexts::ConnectedWebsite,
686 connected_website,
688 connected_website_if,
691 }
692
693 handler! {
694 contexts::CreatedGroup,
695 created_group,
697 created_group_if,
700 }
701
702 handler! {
703 contexts::DataCallback,
704 data_callback,
706 data_callback_if,
709 }
710
711 handler! {
712 contexts::DeletedChatPhoto,
713 deleted_chat_photo,
715 deleted_chat_photo_if,
718 }
719
720 handler! {
721 contexts::Dice,
722 dice,
724 dice_if,
727 }
728
729 handler! {
730 contexts::Document,
731 document,
733 document_if,
736 }
737
738 handler! {
739 contexts::EditedAnimation,
740 edited_animation,
742 edited_animation_if,
745 }
746
747 handler! {
748 contexts::EditedAudio,
749 edited_audio,
751 edited_audio_if,
754 }
755
756 handler! {
757 contexts::EditedDocument,
758 edited_document,
760 edited_document_if,
763 }
764
765 handler! {
766 contexts::EditedLocation,
767 edited_location,
769 edited_location_if,
772 }
773
774 handler! {
775 contexts::EditedPhoto,
776 edited_photo,
778 edited_photo_if,
781 }
782
783 handler! {
784 contexts::EditedText,
785 edited_text,
787 edited_text_if,
790 }
791
792 handler! {
793 contexts::EditedVideo,
794 edited_video,
796 edited_video_if,
799 }
800
801 handler! {
802 contexts::GameCallback,
803 game_callback,
805 game_callback_if,
808 }
809
810 handler! {
811 contexts::Game,
812 game,
814 game_if,
817 }
818
819 handler! {
820 contexts::Inline,
821 inline,
823 inline_if,
826 }
827
828 handler! {
829 contexts::Invoice,
830 invoice,
832 invoice_if,
835 }
836
837 handler! {
838 contexts::LeftMember,
839 left_member,
841 left_member_if,
844 }
845
846 handler! {
847 contexts::Location,
848 location,
850 location_if,
853 }
854
855 handler! {
856 contexts::Migration,
857 migration,
859 migration_if,
862 }
863
864 handler! {
865 contexts::NewChatPhoto,
866 new_chat_photo,
868 new_chat_photo_if,
871 }
872
873 handler! {
874 contexts::NewChatTitle,
875 new_chat_title,
877 new_chat_title_if,
880 }
881
882 handler! {
883 contexts::NewMembers,
884 new_members,
886 new_members_if,
889 }
890
891 handler! {
892 contexts::Passport,
893 passport,
895 passport_if,
898 }
899
900 handler! {
901 contexts::Payment,
902 payment,
904 payment_if,
907 }
908
909 handler! {
910 contexts::Photo,
911 photo,
913 photo_if,
916 }
917
918 handler! {
919 contexts::PinnedMessage,
920 pinned_message,
922 pinned_message_if,
925 }
926
927 handler! {
928 contexts::Poll,
929 poll,
931 poll_if,
934 }
935
936 handler! {
937 contexts::PreCheckout,
938 pre_checkout,
940 pre_checkout_if,
943 }
944
945 handler! {
946 contexts::Shipping,
947 shipping,
949 shipping_if,
952 }
953
954 handler! {
955 contexts::Sticker,
956 sticker,
958 sticker_if,
961 }
962
963 handler! {
964 contexts::Text,
965 text,
967 text_if,
970 }
971
972 pub fn unhandled<H, F>(&mut self, handler: H)
974 where
975 H: (Fn(Arc<contexts::Unhandled>) -> F) + Send + Sync + 'static,
976 F: Future<Output = ()> + Send + 'static,
977 {
978 self.unhandled_handlers.push(Box::new(move |context| {
979 tokio::spawn(handler(context));
980 }))
981 }
982
983 pub fn unhandled_if<H, HF, P, PF>(&mut self, predicate: P, handler: H)
986 where
987 H: (Fn(Arc<contexts::Unhandled>) -> HF) + Send + Sync + 'static,
988 HF: Future<Output = ()> + Send + 'static,
989 P: (Fn(Arc<contexts::Unhandled>) -> PF) + Send + Sync + 'static,
990 PF: Future<Output = bool> + Send + 'static,
991 {
992 let predicate = Arc::new(predicate);
993 let handler = Arc::new(handler);
994 self.unhandled(move |context| {
995 let predicate = Arc::clone(&predicate);
996 let handler = Arc::clone(&handler);
997 async move {
998 if predicate(Arc::clone(&context)).await {
999 handler(context).await
1000 }
1001 }
1002 });
1003 }
1004
1005 fn will_handle_unhandled(&self) -> bool {
1006 !self.unhandled_handlers.is_empty()
1007 }
1008
1009 fn run_unhandled_handlers(&self, bot: Arc<Bot>, update: update::Kind) {
1010 let context = Arc::new(contexts::Unhandled::new(bot, update));
1011
1012 for handler in &self.unhandled_handlers {
1013 handler(context.clone());
1014 }
1015 }
1016
1017 handler! {
1018 contexts::UpdatedPoll,
1019 updated_poll,
1021 updated_poll_if,
1024 }
1025
1026 handler! {
1027 contexts::PollAnswer,
1028 poll_answer,
1030 poll_answer_if,
1033 }
1034
1035 handler! {
1036 contexts::Venue,
1037 venue,
1039 venue_if,
1042 }
1043
1044 handler! {
1045 contexts::Video,
1046 video,
1048 video_if,
1051 }
1052
1053 handler! {
1054 contexts::VideoNote,
1055 video_note,
1057 video_note_if,
1060 }
1061
1062 handler! {
1063 contexts::Voice,
1064 voice,
1066 voice_if,
1069 }
1070
1071 #[instrument(skip(self, bot, update))]
1072 fn handle_update(&self, bot: Arc<Bot>, update: types::Update) {
1073 trace!(?update);
1074
1075 let update_context =
1076 Arc::new(contexts::Update::new(Arc::clone(&bot), update.id));
1077
1078 self.run_before_update_handlers(update_context.clone());
1079
1080 match update.kind {
1081 update::Kind::CallbackQuery(query) => match query.kind {
1082 callback::Kind::Data(data)
1083 if self.will_handle_data_callback() =>
1084 {
1085 let context = contexts::DataCallback::new(
1086 bot,
1087 query.id,
1088 query.from,
1089 query.origin,
1090 query.chat_instance,
1091 data,
1092 );
1093 self.run_data_callback_handlers(Arc::new(context));
1094 }
1095 callback::Kind::Game(game)
1096 if self.will_handle_game_callback() =>
1097 {
1098 let context = contexts::GameCallback::new(
1099 bot,
1100 query.id,
1101 query.from,
1102 query.origin,
1103 query.chat_instance,
1104 game,
1105 );
1106 self.run_game_callback_handlers(Arc::new(context));
1107 }
1108 _ if self.will_handle_unhandled() => {
1109 let update = update::Kind::CallbackQuery(query.clone());
1110 self.run_unhandled_handlers(bot, update);
1111 }
1112 callback::Kind::Data(..) | callback::Kind::Game(..) => (),
1113 },
1114 update::Kind::ChosenInlineResult(result)
1115 if self.will_handle_chosen_inline() =>
1116 {
1117 let context = contexts::ChosenInline::new(bot, result);
1118 self.run_chosen_inline_handlers(Arc::new(context));
1119 }
1120 update::Kind::EditedMessage(message)
1121 | update::Kind::EditedChannelPost(message) => {
1122 self.handle_message_edit_update(bot, message);
1123 }
1124 update::Kind::InlineQuery(query) if self.will_handle_inline() => {
1125 let context = contexts::Inline::new(bot, query);
1126 self.run_inline_handlers(Arc::new(context));
1127 }
1128 update::Kind::Message(message)
1129 | update::Kind::ChannelPost(message) => {
1130 self.handle_message_update(bot, message);
1131 }
1132 update::Kind::PreCheckoutQuery(query)
1133 if self.will_handle_pre_checkout() =>
1134 {
1135 let context = contexts::PreCheckout::new(bot, query);
1136 self.run_pre_checkout_handlers(Arc::new(context));
1137 }
1138 update::Kind::Poll(poll) if self.will_handle_updated_poll() => {
1139 let context = contexts::UpdatedPoll::new(bot, poll);
1140 self.run_updated_poll_handlers(Arc::new(context));
1141 }
1142 update::Kind::PollAnswer(answer)
1143 if self.will_handle_poll_answer() =>
1144 {
1145 let context = contexts::PollAnswer::new(bot, answer);
1146 self.run_poll_answer_handlers(Arc::new(context));
1147 }
1148 update::Kind::ShippingQuery(query)
1149 if self.will_handle_shipping() =>
1150 {
1151 let context = contexts::Shipping::new(bot, query);
1152 self.run_shipping_handlers(Arc::new(context));
1153 }
1154 update if self.will_handle_unhandled() => {
1155 self.run_unhandled_handlers(bot, update);
1156 }
1157 update::Kind::ChosenInlineResult(..)
1158 | update::Kind::InlineQuery(..)
1159 | update::Kind::Poll(..)
1160 | update::Kind::PollAnswer(..)
1161 | update::Kind::PreCheckoutQuery(..)
1162 | update::Kind::ShippingQuery(..)
1163 | update::Kind::Unknown => (),
1164 }
1165
1166 self.run_after_update_handlers(update_context);
1167 }
1168
1169 #[allow(clippy::cognitive_complexity)]
1170 #[allow(clippy::too_many_lines)] fn handle_message_update(&self, bot: Arc<Bot>, message: types::Message) {
1172 let (data, kind) = message.split();
1173
1174 match kind {
1175 message::Kind::Animation(animation, caption)
1176 if self.will_handle_animation() =>
1177 {
1178 let context =
1179 contexts::Animation::new(bot, data, *animation, caption);
1180 self.run_animation_handlers(Arc::new(context));
1181 }
1182 message::Kind::Audio(audio, caption)
1183 if self.will_handle_audio() =>
1184 {
1185 let context = contexts::Audio::new(bot, data, *audio, caption);
1186 self.run_audio_handlers(Arc::new(context));
1187 }
1188 message::Kind::ChatPhotoDeleted
1189 if self.will_handle_deleted_chat_photo() =>
1190 {
1191 let context = contexts::DeletedChatPhoto::new(bot, data);
1192 self.run_deleted_chat_photo_handlers(Arc::new(context));
1193 }
1194 message::Kind::ConnectedWebsite(website)
1195 if self.will_handle_connected_website() =>
1196 {
1197 let context =
1198 contexts::ConnectedWebsite::new(bot, data, website);
1199 self.run_connected_website_handlers(Arc::new(context));
1200 }
1201 message::Kind::Contact(contact) if self.will_handle_contact() => {
1202 let context = contexts::Contact::new(bot, data, contact);
1203 self.run_contact_handlers(Arc::new(context));
1204 }
1205 message::Kind::Dice(dice) if self.will_handle_dice() => {
1206 let context = contexts::Dice::new(bot, data, dice);
1207 self.run_dice_handlers(Arc::new(context));
1208 }
1209 message::Kind::Document(document, caption)
1210 if self.will_handle_document() =>
1211 {
1212 let context =
1213 contexts::Document::new(bot, data, *document, caption);
1214 self.run_document_handlers(Arc::new(context));
1215 }
1216 message::Kind::Game(game) if self.will_handle_game() => {
1217 let context = contexts::Game::new(bot, data, *game);
1218 self.run_game_handlers(Arc::new(context));
1219 }
1220 message::Kind::GroupCreated if self.will_handle_created_group() => {
1221 let context = contexts::CreatedGroup::new(bot, data);
1222 self.run_created_group_handlers(Arc::new(context));
1223 }
1224 message::Kind::Invoice(invoice) if self.will_handle_invoice() => {
1225 let context = contexts::Invoice::new(bot, data, invoice);
1226 self.run_invoice_handlers(Arc::new(context));
1227 }
1228 message::Kind::LeftChatMember(member)
1229 if self.will_handle_left_member() =>
1230 {
1231 let context = contexts::LeftMember::new(bot, data, member);
1232 self.run_left_member_handlers(Arc::new(context));
1233 }
1234 message::Kind::Location(location)
1235 if self.will_handle_location() =>
1236 {
1237 let context = contexts::Location::new(bot, data, location);
1238 self.run_location_handlers(Arc::new(context));
1239 }
1240 message::Kind::MigrateFrom(old_id)
1241 if self.will_handle_migration() =>
1242 {
1243 let context = contexts::Migration::new(bot, data, old_id);
1244 self.run_migration_handlers(Arc::new(context));
1245 }
1246 message::Kind::MigrateTo(..) => (), message::Kind::NewChatMembers(members)
1248 if self.will_handle_new_members() =>
1249 {
1250 let context = contexts::NewMembers::new(bot, data, members);
1251 self.run_new_members_handlers(Arc::new(context));
1252 }
1253 message::Kind::NewChatPhoto(photo)
1254 if self.will_handle_new_chat_photo() =>
1255 {
1256 let context = contexts::NewChatPhoto::new(bot, data, photo);
1257 self.run_new_chat_photo_handlers(Arc::new(context));
1258 }
1259 message::Kind::NewChatTitle(title)
1260 if self.will_handle_new_chat_title() =>
1261 {
1262 let context = contexts::NewChatTitle::new(bot, data, title);
1263 self.run_new_chat_title_handlers(Arc::new(context));
1264 }
1265 message::Kind::PassportData(passport_data)
1266 if self.will_handle_passport() =>
1267 {
1268 let context = contexts::Passport::new(bot, data, passport_data);
1269 self.run_passport_handlers(Arc::new(context));
1270 }
1271 message::Kind::Photo(photo, caption, media_group_id)
1272 if self.will_handle_photo() =>
1273 {
1274 let context = contexts::Photo::new(
1275 bot,
1276 data,
1277 photo,
1278 caption,
1279 media_group_id,
1280 );
1281 self.run_photo_handlers(Arc::new(context));
1282 }
1283 message::Kind::Pinned(message)
1284 if self.will_handle_pinned_message() =>
1285 {
1286 let context = contexts::PinnedMessage::new(bot, data, *message);
1287 self.run_pinned_message_handlers(Arc::new(context));
1288 }
1289 message::Kind::Poll(poll) if self.will_handle_poll() => {
1290 let context = contexts::Poll::new(bot, data, poll);
1291 self.run_poll_handlers(Arc::new(context));
1292 }
1293 message::Kind::Sticker(sticker) if self.will_handle_sticker() => {
1294 let context = contexts::Sticker::new(bot, data, *sticker);
1295 self.run_sticker_handlers(Arc::new(context));
1296 }
1297 message::Kind::SuccessfulPayment(payment)
1298 if self.will_handle_payment() =>
1299 {
1300 let context = contexts::Payment::new(bot, data, *payment);
1301 self.run_payment_handlers(Arc::new(context));
1302 }
1303 message::Kind::Text(text) if is_command(&text) => {
1304 let (command, username) = parse_command(&text);
1305
1306 if !self.is_for_this_bot(username) {
1307 return;
1308 }
1309
1310 if self.will_handle_command(&command) {
1311 let text = trim_command(text);
1312 let context = contexts::Command::new(
1313 command.clone(),
1314 contexts::Text::new(bot, data, text),
1315 );
1316 self.run_command_handlers(&command, &Arc::new(context));
1317 } else if self.will_handle_unhandled() {
1318 let kind = message::Kind::Text(text);
1319 let message = Message::new(data, kind);
1320 let update = update::Kind::Message(message);
1321 self.run_unhandled_handlers(bot, update);
1322 }
1323 }
1324 message::Kind::Text(text) if self.will_handle_text() => {
1325 let context = contexts::Text::new(bot, data, text);
1326 self.run_text_handlers(Arc::new(context));
1327 }
1328 message::Kind::Venue(venue) if self.will_handle_venue() => {
1329 let context = contexts::Venue::new(bot, data, venue);
1330 self.run_venue_handlers(Arc::new(context));
1331 }
1332 message::Kind::Video(video, caption, media_group_id)
1333 if self.will_handle_video() =>
1334 {
1335 let context = contexts::Video::new(
1336 bot,
1337 data,
1338 *video,
1339 caption,
1340 media_group_id,
1341 );
1342 self.run_video_handlers(Arc::new(context));
1343 }
1344 message::Kind::VideoNote(video_note)
1345 if self.will_handle_video_note() =>
1346 {
1347 let context = contexts::VideoNote::new(bot, data, video_note);
1348 self.run_video_note_handlers(Arc::new(context));
1349 }
1350 message::Kind::Voice(voice, caption)
1351 if self.will_handle_voice() =>
1352 {
1353 let context = contexts::Voice::new(bot, data, voice, caption);
1354 self.run_voice_handlers(Arc::new(context));
1355 }
1356 message::Kind::SupergroupCreated
1357 | message::Kind::ChannelCreated => {
1358 warn!("Update not expected; skipping it")
1359 }
1360 kind if self.will_handle_unhandled() => {
1361 let message = Message::new(data, kind);
1362 let update = update::Kind::Message(message);
1363 self.run_unhandled_handlers(bot, update);
1364 }
1365 message::Kind::Animation(..)
1366 | message::Kind::Audio(..)
1367 | message::Kind::ChatPhotoDeleted
1368 | message::Kind::ConnectedWebsite(..)
1369 | message::Kind::Contact(..)
1370 | message::Kind::Dice(..)
1371 | message::Kind::Document(..)
1372 | message::Kind::Game(..)
1373 | message::Kind::GroupCreated
1374 | message::Kind::Invoice(..)
1375 | message::Kind::LeftChatMember(..)
1376 | message::Kind::Location(..)
1377 | message::Kind::MigrateFrom(..)
1378 | message::Kind::NewChatMembers(..)
1379 | message::Kind::NewChatPhoto(..)
1380 | message::Kind::NewChatTitle(..)
1381 | message::Kind::PassportData(..)
1382 | message::Kind::Photo(..)
1383 | message::Kind::Pinned(..)
1384 | message::Kind::Poll(..)
1385 | message::Kind::Sticker(..)
1386 | message::Kind::SuccessfulPayment(..)
1387 | message::Kind::Text(..)
1388 | message::Kind::Venue(..)
1389 | message::Kind::Video(..)
1390 | message::Kind::VideoNote(..)
1391 | message::Kind::Voice(..)
1392 | message::Kind::Unknown => (),
1393 }
1394 }
1395
1396 #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] fn handle_message_edit_update(
1398 &self,
1399 bot: Arc<Bot>,
1400 message: types::Message,
1401 ) {
1402 let (data, kind) = message.split();
1403 let edit_date = if let Some(edit_date) = data.edit_date {
1404 edit_date
1405 } else {
1406 error!("No `edit_date` on an edited message; skipping it");
1407 return;
1408 };
1409
1410 match kind {
1411 message::Kind::Animation(animation, caption)
1412 if self.will_handle_edited_animation() =>
1413 {
1414 let context = contexts::EditedAnimation::new(
1415 bot, data, edit_date, *animation, caption,
1416 );
1417 self.run_edited_animation_handlers(Arc::new(context));
1418 }
1419 message::Kind::Audio(audio, caption)
1420 if self.will_handle_edited_audio() =>
1421 {
1422 let context = contexts::EditedAudio::new(
1423 bot, data, edit_date, *audio, caption,
1424 );
1425 self.run_edited_audio_handlers(Arc::new(context));
1426 }
1427 message::Kind::Document(document, caption)
1428 if self.will_handle_edited_document() =>
1429 {
1430 let context = contexts::EditedDocument::new(
1431 bot, data, edit_date, *document, caption,
1432 );
1433 self.run_edited_document_handlers(Arc::new(context));
1434 }
1435 message::Kind::Location(location)
1436 if self.will_handle_edited_location() =>
1437 {
1438 let context = contexts::EditedLocation::new(
1439 bot, data, edit_date, location,
1440 );
1441 self.run_edited_location_handlers(Arc::new(context));
1442 }
1443 message::Kind::Photo(photo, caption, media_group_id)
1444 if self.will_handle_edited_photo() =>
1445 {
1446 let context = contexts::EditedPhoto::new(
1447 bot,
1448 data,
1449 edit_date,
1450 photo,
1451 caption,
1452 media_group_id,
1453 );
1454 self.run_edited_photo_handlers(Arc::new(context));
1455 }
1456 message::Kind::Text(text) if is_command(&text) => {
1457 let (command, username) = parse_command(&text);
1458 if !self.is_for_this_bot(username) {
1459 return;
1460 }
1461
1462 if self.will_handle_edited_command(&command) {
1463 let text = trim_command(text);
1464 let context = contexts::Command::new(
1465 command.clone(),
1466 contexts::EditedText::new(bot, data, edit_date, text),
1467 );
1468 self.run_edited_command_handlers(
1469 &command,
1470 &Arc::new(context),
1471 );
1472 } else if self.will_handle_unhandled() {
1473 let kind = message::Kind::Text(text);
1474 let message = Message::new(data, kind);
1475 let update = update::Kind::EditedMessage(message);
1476 self.run_unhandled_handlers(bot, update);
1477 }
1478 }
1479 message::Kind::Text(text) if self.will_handle_edited_text() => {
1480 let context =
1481 contexts::EditedText::new(bot, data, edit_date, text);
1482 self.run_edited_text_handlers(Arc::new(context));
1483 }
1484 message::Kind::Video(video, caption, media_group_id)
1485 if self.will_handle_edited_video() =>
1486 {
1487 let context = contexts::EditedVideo::new(
1488 bot,
1489 data,
1490 edit_date,
1491 *video,
1492 caption,
1493 media_group_id,
1494 );
1495 self.run_edited_video_handlers(Arc::new(context));
1496 }
1497
1498 message::Kind::Contact(..)
1499 | message::Kind::Dice(..)
1500 | message::Kind::Game(..)
1501 | message::Kind::Invoice(..)
1502 | message::Kind::Poll(..)
1503 | message::Kind::Sticker(..)
1504 | message::Kind::Venue(..)
1505 | message::Kind::VideoNote(..)
1506 | message::Kind::Voice(..)
1507 | message::Kind::ChannelCreated
1508 | message::Kind::ChatPhotoDeleted
1509 | message::Kind::ConnectedWebsite(..)
1510 | message::Kind::GroupCreated
1511 | message::Kind::LeftChatMember(..)
1512 | message::Kind::MigrateFrom(..)
1513 | message::Kind::MigrateTo(..)
1514 | message::Kind::NewChatMembers(..)
1515 | message::Kind::NewChatPhoto(..)
1516 | message::Kind::NewChatTitle(..)
1517 | message::Kind::PassportData(..)
1518 | message::Kind::Pinned(..)
1519 | message::Kind::SuccessfulPayment(..)
1520 | message::Kind::SupergroupCreated => warn!(
1521 "Unexpected message kind received as an edited message; \
1522 skipping it"
1523 ),
1524
1525 kind if self.will_handle_unhandled() => {
1526 let message = Message::new(data, kind);
1527 let update = update::Kind::EditedMessage(message);
1528 self.run_unhandled_handlers(bot, update)
1529 }
1530 message::Kind::Animation(..)
1531 | message::Kind::Audio(..)
1532 | message::Kind::Document(..)
1533 | message::Kind::Location(..)
1534 | message::Kind::Photo(..)
1535 | message::Kind::Text(..)
1536 | message::Kind::Video(..)
1537 | message::Kind::Unknown => (),
1538 }
1539 }
1540
1541 fn is_for_this_bot(&self, username: Option<&str>) -> bool {
1542 if let Some(username) = username {
1543 self.username.as_ref().map(|x| x == username) == Some(true)
1544 } else {
1545 true
1546 }
1547 }
1548
1549 pub async fn fetch_username(&mut self) -> Result<(), errors::MethodCall> {
1554 let me = self.bot.get_me().call().await?;
1555
1556 let username = me
1557 .user
1558 .username
1559 .expect("[tbot] Expected the bot to have a username");
1560 self.username(username);
1561
1562 Ok(())
1563 }
1564}
1565
1566fn is_command(text: &Text) -> bool {
1567 text.entities.get(0).map(|entity| {
1568 entity.kind == EntityKind::BotCommand && entity.offset == 0
1569 }) == Some(true)
1570}
1571
1572fn parse_command(text: &Text) -> (String, Option<&str>) {
1573 let mut iter =
1574 text.value.split_whitespace().next().unwrap()[1..].split('@');
1577
1578 let command = iter.next().unwrap();
1580 let username = iter.next();
1581
1582 (command.to_string(), username)
1583}
1584
1585fn trim_command(text: Text) -> Text {
1586 let mut entities = text.entities.into_iter();
1587 let command_entity = entities.next().unwrap();
1590 let old_length = text.value.chars().count();
1591
1592 let value: String = text
1593 .value
1594 .chars()
1595 .skip(command_entity.length)
1596 .skip_while(|x| x.is_whitespace())
1597 .collect();
1598 let new_length = value.chars().count();
1599
1600 let entities = entities
1601 .map(|entity| Entity {
1602 kind: entity.kind,
1603 length: entity.length,
1604 offset: entity.offset - (old_length - new_length),
1605 })
1606 .collect();
1607
1608 Text { value, entities }
1609}