def test_pass_job_or_update_queue(self, dp): handler = TypeHandler(dict, self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update({'a': 1, 'b': 2}) assert self.test_flag dp.remove_handler(handler) handler = TypeHandler(dict, self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False dp.process_update({'a': 1, 'b': 2}) assert self.test_flag dp.remove_handler(handler) handler = TypeHandler(dict, self.callback_queue_2, pass_job_queue=True, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False dp.process_update({'a': 1, 'b': 2}) assert self.test_flag
def test_basic(self, dp): handler = TypeHandler(dict, self.callback_basic) dp.add_handler(handler) assert handler.check_update({'a': 1, 'b': 2}) assert not handler.check_update('not a dict') dp.process_update({'a': 1, 'b': 2}) assert self.test_flag
def test_slot_behaviour(self, mro_slots, recwarn): inst = TypeHandler(dict, self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" inst.custom, inst.callback = 'should give warning', self.callback_basic assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list
async def test_basic(self, app): handler = TypeHandler(dict, self.callback) app.add_handler(handler) assert handler.check_update({"a": 1, "b": 2}) assert not handler.check_update("not a dict") async with app: await app.process_update({"a": 1, "b": 2}) assert self.test_flag
def test_slot_behaviour(self, mro_slots): inst = TypeHandler(dict, self.callback) for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set( mro_slots(inst))), "duplicate slot"
def main(): # noinspection SpellCheckingInspection updater = Updater(os.environ.get("LILYPONDBOT_TOKEN"), use_context=True) dispatcher: Dispatcher = updater.dispatcher dispatcher.add_handler(TypeHandler(Update, anti_flood), group=-1) dispatcher.add_handler(MessageHandler(Filters.text, update_monitor), group=0) dispatcher.add_handler(InlineQueryHandler(update_monitor), group=0) for cmd in (start, help_, ping, version): dispatcher.add_handler(CommandHandler(cmd.__name__.rstrip('_'), cmd, ~Filters.update.edited_message), group=1) dispatcher.add_handler(MessageHandler( ~Filters.command & Filters.chat_type.private & Filters.text, send_compile_results), group=1) dispatcher.add_handler(InlineQueryHandler(send_compile_results), group=1) dispatcher.add_error_handler(log_error) pathlib.Path(constants.USER_FILES_DIR).mkdir(parents=True, exist_ok=True) pathlib.Path(constants.ERROR_FILES_DIR).mkdir(parents=True, exist_ok=True) updater.job_queue.run_repeating(monitor.cleanup, 30 * 60, 0) updater.start_polling(clean=True) print(f"Bot started! @{updater.bot.username}") updater.idle()
def main(): updater = Updater(CONFIG.BOTTOKEN) dispatcher = updater.dispatcher dispatcher.add_handler(TypeHandler(type=Update, callback=Misc.block_access), group=0) dispatcher.add_handler(CommandHandler("start", Misc.start_command), group=1) dispatcher.add_handler(CommandHandler("restart", Restart.command), group=1) dispatcher.add_handler(CommandHandler("get", Misc.get_all), group=1) dispatcher.add_handler(CommandHandler("help", Misc.help_command), group=1) dispatcher.add_handler(CommandHandler("stats", Stats.command), group=1) dispatcher.add_handler(CommandHandler("detail_stats", Stats.detail_command), group=1) dispatcher.add_handler(CallbackQueryHandler(Stats.command, pattern="refresh"), group=1) if CONFIG.PORT_NUM != 0: updater.start_webhook(listen="127.0.0.1", port=CONFIG.PORT_NUM, url_path=CONFIG.BOTTOKEN) updater.bot.set_webhook( url=f"https://{CONFIG.IP_ADDR}:443/{CONFIG.BOTTOKEN}", certificate=open("cert.pem", "rb"), ) else: updater.start_polling() updater.idle()
def init(): config = get_json(CONFIG) sql.init(**config['db']) token = get_token(config) upd = Updater(token=token, use_context=True) disp = upd.dispatcher logger.info('Updater created') disp.add_handler(CommandHandler('start', start)) disp.add_handler( ConversationHandler( entry_points=[CommandHandler('register', register_start)], states={ REGISTER_NAME: [ MessageHandler(Filters.text & ~Filters.command, register_name) ] }, fallbacks=[CommandHandler('cancel', cancel)])) disp.add_handler( ConversationHandler( entry_points=[CommandHandler('forget', forget_start)], states={ FORGET_NAME: [MessageHandler(Filters.text & ~Filters.command, forget_name)] }, fallbacks=[CommandHandler('cancel', cancel)])) disp.add_handler(CommandHandler('names', names)) disp.add_handler(TypeHandler(PostNotify, foobar)) logger.info('Handlers set up') return upd
def __init__(self, hass, bot, config): """Create Updater and Dispatcher before calling super().""" self.bot = bot self.updater = Updater(bot=bot, workers=4) self.dispatcher = self.updater.dispatcher self.dispatcher.add_handler(TypeHandler(Update, self.handle_update)) self.dispatcher.add_error_handler(process_error) super().__init__(hass, config)
def main() -> None: """Run the bot.""" context_types = ContextTypes(context=CustomContext, chat_data=ChatData) application = Application.builder().token("TOKEN").context_types(context_types).build() # run track_users in its own group to not interfere with the user handlers application.add_handler(TypeHandler(Update, track_users), group=-1) application.add_handler(CommandHandler("start", start)) application.add_handler(CallbackQueryHandler(count_click)) application.add_handler(CommandHandler("print_users", print_users)) application.run_polling()
def __init__(self, hass, bot, config): """Create Dispatcher before calling super().""" self.bot = bot self.trusted_networks = config[CONF_TRUSTED_NETWORKS] # Dumb dispatcher that just gets our updates to our handler callback (self.handle_update) self.dispatcher = Dispatcher(bot, None) self.dispatcher.add_handler(TypeHandler(Update, self.handle_update)) super().__init__(hass, config) self.base_url = config.get(CONF_URL) or get_url( hass, require_ssl=True, allow_internal=False) self.webhook_url = f"{self.base_url}{TELEGRAM_WEBHOOK_URL}"
def main() -> None: """Run the bot.""" context_types = ContextTypes(context=CustomContext, chat_data=ChatData) updater = Updater("TOKEN", context_types=context_types) dispatcher = updater.dispatcher # run track_users in its own group to not interfere with the user handlers dispatcher.add_handler(TypeHandler(Update, track_users), group=-1) dispatcher.add_handler(CommandHandler("start", start)) dispatcher.add_handler(CallbackQueryHandler(count_click)) dispatcher.add_handler(CommandHandler("print_users", print_users)) updater.start_polling() updater.idle()
def test_persistence_dispatcher_arbitrary_update_types(self, dp, base_persistence, caplog): # Updates used with TypeHandler doesn't necessarily have the proper attributes for # persistence, makes sure it works anyways dp.persistence = base_persistence class MyUpdate(object): pass dp.add_handler(TypeHandler(MyUpdate, lambda *_: None)) with caplog.at_level(logging.ERROR): dp.process_update(MyUpdate()) assert 'An uncaught error was raised while processing the update' not in caplog.text
def main(): updater = Updater(telegram_bot["token"], use_context=True) dispatcher = updater.dispatcher ScheduleMenu(dispatcher) notification_dispatch_handler = TypeHandler(UserNotification, notify_user, updater) dispatcher.add_handler(notification_dispatch_handler) start_handler = CommandHandler("start", start) dispatcher.add_handler(start_handler) notify_command_handler = CommandHandler("notify", restaurant_notifications, pass_user_data=True) dispatcher.add_handler(notify_command_handler) # dispatcher.add_handler( # CallbackQueryHandler(notifications_handler, pass_user_data=True) # ) notify_time_handler = MessageHandler( Filters.regex(r"^\d{1,2}\s*[\.:\s+,]\s*\d{1,2}$"), notify_time) dispatcher.add_handler(notify_time_handler) materik_handler = MessageHandler(Filters.regex("^(материк)$"), menu_materik) vangog_handler = MessageHandler(Filters.regex("^(вангог)$"), menu_vangog) pizzaroni_handler = MessageHandler(Filters.regex("^(пиццарони)$"), menu_pizzaroni) dispatcher.add_handler(materik_handler) dispatcher.add_handler(vangog_handler) dispatcher.add_handler(pizzaroni_handler) dispatcher.add_handler( CallbackQueryHandler(Materik.menu_handler, pass_user_data=True)) dispatcher.add_error_handler(error_callback) unknown_handler = MessageHandler(Filters.command, unknown) dispatcher.add_handler(unknown_handler) updater.start_polling() updater.idle()
def main(): updater = Updater(CONFIG.BOTTOKEN) dispatcher = updater.dispatcher dispatcher.add_handler(TypeHandler(type=Update, callback=block_access), group=0) dispatcher.add_handler(CommandHandler('start', start), group=1) dispatcher.add_handler(CommandHandler('restart', restart), group=1) dispatcher.add_handler(CommandHandler('get', get_all), group=1) dispatcher.add_handler(CommandHandler('help', help), group=1) if CONFIG.PORT_NUM != 0: updater.start_webhook(listen='127.0.0.1', port=CONFIG.PORT_NUM, url_path=CONFIG.BOTTOKEN) updater.bot.set_webhook( url=f"https://{CONFIG.IP_ADDR}:443/{CONFIG.BOTTOKEN}", certificate=open('cert.pem', 'rb')) else: updater.start_polling() updater.idle()
dp = updater.dispatcher # See persistence note above CallbackContext.github_data = property( lambda self: persistence.github_data) # Save data every five (5) min dp.job_queue.run_repeating(lambda *_: persistence.flush(), 5 * 60) # Telegram updates dp.add_handler(CommandHandler('start', start_handler)) dp.add_handler(CommandHandler('help', help_handler)) dp.add_handler(CommandHandler('privacy', privacy_handler)) dp.add_handler(CommandHandler('login', login_handler)) settings.add_handlers(dp) # For commenting on issues/PR/reviews dp.add_handler( MessageHandler(Filters.reply & reply_data_link_filter, reply_handler)) # Non-telegram updates github_handler = GithubHandler(dp) dp.add_handler(TypeHandler(GithubUpdate, github_handler.handle_update)) dp.add_handler( TypeHandler(GithubAuthUpdate, github_handler.handle_auth_update)) dp.add_error_handler(error_handler) updater.start()
def test_strict(self): handler = TypeHandler(dict, self.callback_basic, strict=True) o = OrderedDict({'a': 1, 'b': 2}) assert handler.check_update({'a': 1, 'b': 2}) assert not handler.check_update(o)
def test_strict(self): handler = TypeHandler(dict, self.callback, strict=True) o = OrderedDict({"a": 1, "b": 2}) assert handler.check_update({"a": 1, "b": 2}) assert not handler.check_update(o)
def register_dispatcher( updater: Updater, admins: Union[int, List[int]], chats: Union[int, List[int]], default_settings: Dict, gsheets_file: str, gsheets_email: str, ) -> None: dispatcher = updater.dispatcher dispatcher.add_handler(TypeHandler(Update, access.check), group=-2) dispatcher.add_handler(PollAnswerHandler(poll.collect_answer), group=-1) # dispatcher.add_handler(InlineQueryHandler(inline.surveys)) dispatcher.add_handler(CommandHandler("add_admin", commands.add_admin)) dispatcher.add_handler(CommandHandler("add_chat", commands.add_chat)) dispatcher.add_handler(CommandHandler("help", commands.help)) dispatcher.add_handler( CommandHandler("restart", partial(commands.restart, updater=updater))) dispatcher.add_handler( CommandHandler("remove_admin", commands.remove_admin)) dispatcher.add_handler(CommandHandler("remove_chat", commands.remove_chat)) dispatcher.add_handler( CommandHandler("reset_ongoing", commands.reset_ongoing)) dispatcher.add_handler(CommandHandler("rotate_log", commands.rotate_log)) dispatcher.add_handler( CommandHandler("show_chat_id", commands.show_chat_id)) dispatcher.add_handler( CommandHandler("show_current_survey", commands.show_current_survey)) dispatcher.add_handler(CommandHandler("show_id", commands.show_id)) edit_conv = ConversationHandler( entry_points=[ CallbackQueryHandler( partial(edit.pick_part, source="compose"), pattern="^{}$".format(cc.EDIT_SURVEY_COMPOSE_CB), ), CallbackQueryHandler( partial(edit.pick_part, source="manage"), pattern="^{}$".format(cc.EDIT_SURVEY_MANAGE_CB), ), ], states={ cc.PICK_PART_STATE: [ CallbackQueryHandler(edit.title, pattern="^{}$".format(cc.EDIT_TITLE_CB)), CallbackQueryHandler(edit.desc, pattern="^{}$".format(cc.EDIT_DESC_CB)), CallbackQueryHandler(edit.pick_question, pattern="^{}$".format( cc.EDIT_QUESTIONS_CB)), CallbackQueryHandler(edit.save_confirm, pattern="^{}$".format( cc.SAVE_AND_EXIT_CB)), CallbackQueryHandler(edit.discard_confirm, pattern="^{}$".format( cc.DISCARD_AND_EXIT_CB)), ], cc.EDIT_TITLE_STATE: [ CallbackQueryHandler( partial(compose.get_title, mode="edit"), pattern="^{}$".format(cc.NEW_TITLE_CB), ), CallbackQueryHandler(edit.pick_part, pattern="^{}$".format( cc.KEEP_CURRENT_TITLE_CB)), ], cc.GET_TITLE_STATE: [MessageHandler(filters.Filters.text, compose.save_title)], cc.SAVE_TITLE_STATE: [ CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.SAVE_TITLE_CB)), CallbackQueryHandler(compose.get_title, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.EDIT_DESC_STATE: [ CallbackQueryHandler(compose.get_desc, pattern="^{}$".format(cc.NEW_DESC_CB)), CallbackQueryHandler(edit.pick_part, pattern="^{}$".format( cc.KEEP_CURRENT_DESC_CB)), ], cc.GET_DESC_STATE: [MessageHandler(filters.Filters.text, compose.save_desc)], cc.SAVE_DESC_STATE: [ CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.SAVE_DESC_CB)), CallbackQueryHandler(compose.get_desc, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.PICK_QUESTION_STATE: [ CallbackQueryHandler(edit.question, pattern="^\d+$"), CallbackQueryHandler( edit.pick_question, pattern="^(prev page|next page|PAGENUM)$"), CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.RETURN_CB)), ], cc.PICK_QUESTION_PART_STATE: [ CallbackQueryHandler(edit.question_text, pattern="^{}$".format( cc.EDIT_QUESTION_TEXT_CB)), CallbackQueryHandler(edit.multi, pattern="^{}$".format(cc.EDIT_MULTI_CB)), CallbackQueryHandler(edit.answers, pattern="^{}$".format( cc.EDIT_ANSWERS_CB)), CallbackQueryHandler( edit.remove_question_confirm, pattern="^{}$".format(cc.REMOVE_QUESTION_CB), ), CallbackQueryHandler(edit.pick_question, pattern="^{}$".format(cc.RETURN_CB)), ], cc.EDIT_QUESTION_TEXT_STATE: [ CallbackQueryHandler( partial(compose.get_question, mode="edit"), pattern="^{}$".format(cc.NEW_QUESTION_TEXT_CB), ), CallbackQueryHandler( edit.question, pattern="^{}$".format(cc.KEEP_CURRENT_QUESTION_TEXT_CB), ), CallbackQueryHandler( edit.remove_question_confirm, pattern="^{}$".format(cc.REMOVE_QUESTION_CB), ), ], cc.GET_QUESTION_STATE: [ MessageHandler(filters.Filters.text, partial(compose.save_question, mode="edit")) ], cc.SAVE_QUESTION_STATE: [ CallbackQueryHandler( partial(edit.save_result, result="question"), pattern="^{}$".format(cc.SAVE_QUESTION_CB), ), CallbackQueryHandler( partial(compose.get_question, mode="edit"), pattern="^{}$".format(cc.ENTER_AGAIN_CB), ), ], cc.EDIT_MULTI_STATE: [ CallbackQueryHandler( partial(compose.get_multi, mode="edit"), pattern="^{}$".format(cc.NEW_MULTI_CB), ), CallbackQueryHandler(edit.question, pattern="^{}$".format( cc.KEEP_CURRENT_MULTI_CB)), ], cc.GET_MULTIANS_STATE: [ CallbackQueryHandler( partial(compose.save_multi, multi=True, mode="edit"), pattern="^{}$".format(cc.YES_CB), ), CallbackQueryHandler( partial(compose.save_multi, multi=False, mode="edit"), pattern="^{}$".format(cc.NO_CB), ), ], cc.SAVE_MULTIANS_STATE: [ CallbackQueryHandler( partial(edit.save_result, result="multi"), pattern="^{}$".format(cc.YES_CB), ), CallbackQueryHandler(compose.get_multi, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.EDIT_ANSWERS_STATE: [ CallbackQueryHandler(edit.pick_answer, pattern="^{}$".format( cc.EDIT_EXISTING_ANSWER_CB)), CallbackQueryHandler( partial(compose.get_answer, mode="edit"), pattern="^{}$".format(cc.ADD_NEW_ANSWER_CB), ), CallbackQueryHandler(edit.question, pattern="^{}$".format(cc.RETURN_CB)), ], cc.PICK_ANSWER_STATE: [ MessageHandler(filters.Filters.text, edit.answer), CallbackQueryHandler(edit.question, pattern="^{}$".format(cc.RETURN_CB)), ], cc.EDIT_ANSWER_STATE: [ CallbackQueryHandler( partial(compose.get_answer, mode="edit"), pattern="^{}$".format(cc.EDIT_ANSWER_CB), ), CallbackQueryHandler( edit.remove_answer_confirm, pattern="^{}$".format(cc.REMOVE_ANSWER_CB), ), ], cc.GET_ANSWER_STATE: [ MessageHandler(filters.Filters.text, partial(compose.save_answer, mode="edit")) ], cc.SAVE_ANSWER_STATE: [ CallbackQueryHandler( partial(edit.save_result, result="answers"), pattern="^{}$".format(cc.SAVE_ANSWER_CB), ), CallbackQueryHandler( partial(compose.get_question, mode="edit"), pattern="^{}$".format(cc.ENTER_AGAIN_CB), ), ], cc.REMOVE_ANSWER_CONFIRM_STATE: [ CallbackQueryHandler(edit.remove_answer, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(edit.pick_answer, pattern="^{}$".format(cc.NO_CB)), ], cc.REMOVE_QUESTION_CONFIRM_STATE: [ CallbackQueryHandler(edit.remove_question, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(edit.question, pattern="^{}$".format(cc.NO_CB)), ], cc.EDIT_AFTER_SAVE_STATE: [ CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.TO_PARTS_CB)), CallbackQueryHandler(edit.pick_question, pattern="^{}$".format( cc.TO_QUESTIONS_CB)), ], cc.SAVE_CONFIRM_STATE: [ CallbackQueryHandler(edit.save_changes, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.NO_CB)), ], cc.DISCARD_CONFIRM_STATE: [ CallbackQueryHandler(edit.discard_changes, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(edit.pick_part, pattern="^{}$".format(cc.NO_CB)), ], }, fallbacks=[ CallbackQueryHandler(root.confirm_return_to_main, pattern="^{}$".format(cc.RETURN_TO_MAIN_CB)), ], map_to_parent={ cc.END_COMPOSE: cc.REVIEW_STATE, cc.END_MANAGE: cc.MANAGE_SURVEYS_STATE, cc.MAIN_MENU_STATE: cc.MAIN_MENU_STATE }, ) compose_conv = ConversationHandler( entry_points=[ CallbackQueryHandler(compose.get_title, pattern="^{}$".format(cc.CREATE_SURVEY_CB)) ], states={ cc.GET_TITLE_STATE: [ MessageHandler(filters.Filters.text, compose.save_title), CallbackQueryHandler(compose.return_to_step, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(compose.get_title, pattern="^{}$".format(cc.NO_CB)), ], cc.SAVE_TITLE_STATE: [ CallbackQueryHandler(compose.get_desc, pattern="^{}$".format(cc.SAVE_TITLE_CB)), CallbackQueryHandler(compose.get_title, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.GET_DESC_STATE: [MessageHandler(filters.Filters.text, compose.save_desc)], cc.SAVE_DESC_STATE: [ CallbackQueryHandler(compose.get_question, pattern="^{}$".format(cc.SAVE_DESC_CB)), CallbackQueryHandler(compose.get_desc, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.GET_QUESTION_STATE: [MessageHandler(filters.Filters.text, compose.save_question)], cc.SAVE_QUESTION_STATE: [ CallbackQueryHandler(compose.get_multi, pattern="^{}$".format( cc.SAVE_QUESTION_CB)), CallbackQueryHandler( partial(compose.get_question, returning=True), pattern="^{}$".format(cc.ENTER_AGAIN_CB), ), ], cc.GET_MULTIANS_STATE: [ CallbackQueryHandler( partial(compose.save_multi, multi=True), pattern="^{}$".format(cc.YES_CB), ), CallbackQueryHandler( partial(compose.save_multi, multi=False), pattern="^{}$".format(cc.NO_CB), ), ], cc.SAVE_MULTIANS_STATE: [ CallbackQueryHandler(compose.get_answer, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(compose.get_multi, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.GET_ANSWER_STATE: [MessageHandler(filters.Filters.text, compose.save_answer)], cc.SAVE_ANSWER_STATE: [ CallbackQueryHandler(compose.checkpoint, pattern="^{}$".format(cc.SAVE_ANSWER_CB)), CallbackQueryHandler( partial(compose.get_answer, returning=True), pattern="^{}$".format(cc.ENTER_AGAIN_CB), ), ], cc.CHECKPOINT_STATE: [ CallbackQueryHandler(compose.get_answer, pattern="^{}$".format(cc.NEXT_ANSWER_CB)), CallbackQueryHandler(compose.get_question, pattern="^{}$".format( cc.NEXT_QUESTION_CB)), CallbackQueryHandler(compose.review, pattern="^{}$".format( cc.FINISH_CREATING_CB)), ], cc.REVIEW_STATE: [ CallbackQueryHandler(compose.finish, pattern="^{}$".format( cc.CREATION_COMPLETE_CB)), edit_conv, ], cc.START_OVER_STATE: [ CallbackQueryHandler(compose.get_title, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler( partial(compose.review, returning=True), pattern="^{}$".format(cc.NO_CB), ), ], }, fallbacks=[CommandHandler("start", root.start)], map_to_parent={ cc.END: cc.START_STATE, cc.START_STATE: cc.START_STATE, cc.MAIN_MENU_STATE: cc.MAIN_MENU_STATE, }, ) manage_conv = ConversationHandler( entry_points=[ CallbackQueryHandler(manage.start, pattern="^{}$".format(cc.MANAGE_SURVEYS_CB)) ], states={ cc.MANAGE_SURVEYS_STATE: [ compose_conv, CallbackQueryHandler(manage.pick, pattern="^{}$".format( cc.CHOOSE_SURVEY_CB)), ], cc.MANAGE_PICK_SURVEY_STATE: [ CallbackQueryHandler(manage.survey, pattern="^\d+$"), CallbackQueryHandler( manage.pick, pattern="^(prev page|next page|PAGENUM)$"), compose_conv, ], cc.MANAGE_SURVEY_STATE: [ edit_conv, CallbackQueryHandler( manage.confirm_delete, pattern="^{}$".format(cc.MANAGE_DELETE_SURVEY_CB), ), CallbackQueryHandler(manage.print_survey, pattern="^{}$".format( cc.PRINT_SURVEY_CB)), ], cc.MANAGE_DELETE_CONFIRM_STATE: [ CallbackQueryHandler(manage.delete, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(manage.survey, pattern="^{}$".format(cc.NO_CB)), ], cc.MANAGE_AFTER_DELETE_STATE: [ CallbackQueryHandler(manage.pick, pattern="^{}$".format( cc.CHOOSE_SURVEY_CB)) ], cc.MAIN_MENU_STATE: [ CallbackQueryHandler(root.start, pattern="^{}$".format(cc.YES_CB)), CallbackQueryHandler(manage.start, pattern="^{}$".format(cc.NO_CB)), ], }, fallbacks=[ CallbackQueryHandler(root.confirm_return_to_main, pattern="^{}$".format(cc.RETURN_TO_MAIN_CB)) ], map_to_parent={ cc.START_STATE: cc.START_STATE, cc.MAIN_MENU_STATE: cc.MAIN_MENU_STATE, }, ) settings_conv = ConversationHandler( entry_points=[ CallbackQueryHandler(settings.pick, pattern="^{}$".format(cc.SETTINGS_CB)) ], states={ cc.PICK_SETTING_STATE: [ CallbackQueryHandler(settings.lang, pattern="^{}$".format( cc.SETTINGS_LANG_CB)), CallbackQueryHandler(settings.page_len, pattern="^{}$".format( cc.SETTINGS_PAGE_LEN_CB)), CallbackQueryHandler(settings.row_len, pattern="^{}$".format( cc.SETTINGS_ROW_LEN_CB)), ], cc.SETTINGS_PAGE_LEN_STATE: [ CallbackQueryHandler( partial(settings.change_setting, setting="page_len"), pattern="^\d+$", ), CallbackQueryHandler(settings.pick, pattern="^{}$".format(cc.RETURN_CB)), ], cc.SETTINGS_ROW_LEN_STATE: [ CallbackQueryHandler(partial(settings.change_setting, setting="row_len"), pattern="^\d+$"), CallbackQueryHandler(settings.pick, pattern="^{}$".format(cc.RETURN_CB)), ], }, fallbacks=[], map_to_parent={ cc.SETTINGS_LANG_STATE: cc.LANG_STATE, cc.MAIN_MENU_STATE: cc.MAIN_MENU_STATE, }, ) poll_conv = ConversationHandler( entry_points=[ CallbackQueryHandler(poll.pick_survey, pattern="^{}$".format(cc.START_SURVEY_CB)) ], states={ cc.POLL_PICK_STATE: [ CallbackQueryHandler(poll.preview, pattern="^\d+$"), CallbackQueryHandler( poll.pick_survey, pattern="^(prev page|next page|PAGENUM)$"), compose_conv, ], cc.POLL_PREVIEW_STATE: [ CallbackQueryHandler(poll.pick_chat, pattern="^{}$".format(cc.PICK_CHAT_CB)), CallbackQueryHandler(poll.pick_survey, pattern="^{}$".format( cc.CHOOSE_SURVEY_CB)), ], cc.PICK_CHAT_STATE: [ CallbackQueryHandler(poll.set_cap, pattern="^\d+$"), CallbackQueryHandler( poll.pick_chat, pattern="^(prev page|next page|PAGENUM)$"), ], cc.SET_CAP_STATE: [ CallbackQueryHandler(poll.confirm, pattern="^{}$".format( cc.USE_RECOMMENDED_CB)), CallbackQueryHandler(poll.get_cap, pattern="^{}$".format(cc.SET_OWN_CAP_CB)), ], cc.GET_CAP_STATE: [MessageHandler(filters.Filters.text, poll.validate_cap)], cc.VALIDATE_CAP_STATE: [ CallbackQueryHandler(poll.confirm, pattern="^{}$".format( cc.USE_RECOMMENDED_CB)), CallbackQueryHandler(poll.confirm, pattern="^{}$".format(cc.USE_CUSTOM_CB)), CallbackQueryHandler(poll.get_cap, pattern="^{}$".format(cc.ENTER_AGAIN_CB)), ], cc.POLL_CONFIRM_STATE: [ CallbackQueryHandler(poll.launch, pattern="^{}$".format( cc.START_SURVEY_CB)), CallbackQueryHandler(poll.pick_survey, pattern="^{}$".format( cc.CHANGE_SURVEY_CB)), CallbackQueryHandler(poll.pick_chat, pattern="^{}$".format(cc.CHANGE_CHAT_CB)), CallbackQueryHandler(poll.set_cap, pattern="^{}$".format(cc.CHANGE_CAP_CB)), ], }, fallbacks=[ CallbackQueryHandler(root.confirm_return_to_main, pattern="^{}$".format(cc.RETURN_TO_MAIN_CB)) ], map_to_parent={ cc.START_STATE: cc.START_STATE, cc.MAIN_MENU_STATE: cc.MAIN_MENU_STATE, }, ) main_conv = ConversationHandler( entry_points=[CommandHandler("start", root.start)], states={ cc.LANG_STATE: [ CallbackQueryHandler( partial(commands.set_lang, lang="ru"), pattern="^{}$".format(cc.RU_CB), ), CallbackQueryHandler( partial(commands.set_lang, lang="en"), pattern="^{}$".format(cc.EN_CB), ), ], cc.START_STATE: [poll_conv, manage_conv, settings_conv], cc.MAIN_MENU_STATE: [ CallbackQueryHandler(root.start, pattern="^{}$".format(cc.YES_CB)) ], }, fallbacks=[ CallbackQueryHandler(root.to_prev_step, pattern="^{}$".format(cc.RETURN_CB)), CallbackQueryHandler(root.confirm_return_to_main, pattern="^{}$".format(cc.RETURN_TO_MAIN_CB)), CommandHandler("start", root.start), ], ) dispatcher.add_handler(main_conv) bot_data = dispatcher.bot_data if not bot_data.get(consts.SURVEYS_KEY): bot_data[consts.SURVEYS_KEY] = [] if not bot_data.get(consts.ADMINS_KEY): bot_data[consts.ADMINS_KEY] = admins if not bot_data.get(consts.SHEETS_KEY): bot_data[consts.SHEETS_KEY] = { "file": gsheets_file, "email": gsheets_email } if not bot_data.get(consts.CHATS_KEY): bot_data[consts.CHATS_KEY] = chats if (not bot_data.get(consts.DEFAULTS_KEY) or bot_data[consts.DEFAULTS_KEY] != default_settings): bot_data[consts.DEFAULTS_KEY] = default_settings
**reiherbergActions, **en_reiherbergActions, **generalActions }, prechecks=prechecks), **read_state_yml("states/reiherberg.yml", actions={**reiherbergActions}, prechecks=prechecks), **read_state_yml("states/en_reiherberg.yml", actions={**en_reiherbergActions}, prechecks=prechecks), ConversationHandler.TIMEOUT: [ MessageHandler(Filters.regex(r'^(.)+'), reiherbergActions["timeout"]) ], }, fallbacks=[TypeHandler(Update, generalActions["log_update"])]) dp.add_handler(conv_handler) dp.add_error_handler(error_handler) print("webhook_url: ", os.environ.get("APP_URL") + TOKEN) print("PORT", PORT) updater.start_webhook(listen="0.0.0.0", port=PORT, url_path=TOKEN, webhook_url=os.environ.get("APP_URL") + TOKEN) updater.idle()
response += f'<i>{shop.mana}💧</i> by <b>{shop.ownerCastle}{shop.ownerName}</b>' response += '\n\n' responses.append(response) for response in responses: msg.reply_text(response, parse_mode='HTML') if __name__ == '__main__': ud = Updater(config.TOKEN, workers=12) dp = ud.dispatcher jq = ud.job_queue jq.run_repeating(shops_updater, interval=config.UPDATE_INTERVAL, first=0) dp.add_handler(TypeHandler(Update, dbhandler), group=-1) dp.add_handler(CommandHandler('start', start)) dp.add_handler(CommandHandler('help', help)) dp.add_handler(CommandHandler(['list', 'shops'], list_shops)) dp.add_handler(InlineQueryHandler(inline_shop_search)) if config.APP_ENV.startswith('PROD'): ud.start_webhook(listen='0.0.0.0', port=config.WEBHOOK_PORT, url_path=config.TOKEN) ud.bot.set_webhook( url='https://{}/{}'.format(config.WEBHOOK_URL, config.TOKEN)) else:
def setup( # pylint: disable=R0913,R0914,R0915 dispatcher: Dispatcher, admin: Union[int, str], oc_url: str, oc_username: str, oc_password: str, oc_path: str, ad_url: str, ad_url_active: str, ad_username: str, ad_password: str, yourls_url: str, yourls_signature: str, ) -> None: """ * Adds handlers. Convenience method to avoid doing that all in the main script. * Sets the bot commands and makes sure ``dispatcher.bot_data`` is set up correctly. * Registers a :class:`telegram.ext.TypeHandler` that makes sure that conversations are not interrupted * Sets up statistics Args: dispatcher: The :class:`telegram.ext.Dispatcher`. admin: The admins chat id. oc_url: URL of the OwnCloud Instance. oc_username: Username for the OwnCloud Instance. oc_password: Password of the OwnCloud Instance. oc_path: Remote path on the OwnCloud Instance. ad_url: URL of the AkaDressen file. ad_url_active: URL of the AkaDressen file containing only the active members. ad_username: Username for the AkaDressen. ad_password: Password for the AkaDressen. yourls_url: URL of the YOURLS instance. yourls_signature: Signature for the YOURLS instance. """ def check_conversation_status(update: Update, context: CallbackContext) -> None: """ Checks if the user is currently in a conversation. If they are and the corresponding conversation does *not* handle the incoming update, the user will get a corresponding message and the update will be discarded. Args: update: The update. context: The context as provided by the :class:`telegram.ext.Dispatcher`. """ if not update.effective_user: return conversation = context.user_data.get(CONVERSATION_KEY, None) if not conversation: return conversation_check = not bool( conversations[conversation].check_update(update)) # Make sure that the callback queries for vcard requests are not processed if update.callback_query: contact_request_check = bool( re.match(inline.REQUEST_CONTACT_PATTERN, update.callback_query.data)) highscore_check = 'highscore' in update.callback_query.data else: contact_request_check = False highscore_check = False if conversation_check or contact_request_check or highscore_check: text = interrupt_replies[conversation] if update.callback_query: update.callback_query.answer(text=text, show_alert=True) elif update.effective_message: update.effective_message.reply_text(text) raise DispatcherHandlerStop() def clear_conversation_status(update: Update, context: CallbackContext) -> None: """ Clears the conversation status of a user in case of an error. Just to be sure. Args: update: The update. context: The context as provided by the :class:`telegram.ext.Dispatcher`. """ if update.effective_user: context.user_data.pop(CONVERSATION_KEY) # ------------------------------------------------------------------------------------------- # # Set up statistics set_dispatcher(dispatcher) # Count total number of updates register_stats(SimpleStats('stats', lambda u: bool(u.effective_user)), admin_id=int(admin)) # Count number of started games register_stats( SimpleStats( 'game_stats', lambda u: bool(u.message) and Filters.text('/spiel_starten')(u)), admin_id=int(admin), ) # Count number of requested contacts register_stats( admin_id=int(admin), stats=SimpleStats( 'contact_stats', lambda u: bool(u.callback_query and 'contact_request' in u. callback_query.data), ), ) # Handlers # Prepare conversations game_handler = game.GAME_HANDLER editing_conversation = editing.build_editing_handler(int(admin)) canceling_conversation = cancel_membership.CANCEL_MEMBERSHIP_HANDLER banning_conversation = ban.build_banning_handler(int(admin)) conversations: Dict[str, ConversationHandler] = { game.CONVERSATION_VALUE: game_handler, editing.CONVERSATION_VALUE: editing_conversation, cancel_membership.CONVERSATION_VALUE: canceling_conversation, ban.CONVERSATION_VALUE: banning_conversation, } interrupt_replies: Dict[str, str] = { game.CONVERSATION_VALUE: game.CONVERSATION_INTERRUPT_TEXT, editing.CONVERSATION_VALUE: editing.CONVERSATION_INTERRUPT_TEXT, cancel_membership.CONVERSATION_VALUE: cancel_membership.CONVERSATION_INTERRUPT_TEXT, ban.CONVERSATION_VALUE: ban.CONVERSATION_INTERRUPT_TEXT, } # Registration status dispatcher.add_handler(TypeHandler(Update, registration.check_registration_status), group=-2) # Conversation Interruption behaviour dispatcher.add_handler(TypeHandler(Update, check_conversation_status), group=-1) # Game Conversation # Must be first so that the fallback can catch unrelated messages dispatcher.add_handler(game_handler) # Registration process # We need the filter here in order to not catch /start with deep linking parameter used for # inline help dispatcher.add_handler( CommandHandler('start', registration.start, filters=Filters.text('/start'))) dispatcher.add_handler( CallbackQueryHandler(registration.request_registration, pattern=REGISTRATION_PATTERN, run_async=True)) dispatcher.add_handler(registration.ACCEPT_REGISTRATION_HANDLER) dispatcher.add_handler(registration.DENY_REGISTRATION_HANDLER) # Edit user data dispatcher.add_handler(editing_conversation) # Cancel membership dispatcher.add_handler(canceling_conversation) # Banning members dispatcher.add_handler(banning_conversation) # Simple commands dispatcher.add_handler( CommandHandler(['hilfe', 'help'], commands.help_message)) dispatcher.add_handler(CommandHandler('daten_anzeigen', commands.show_data)) dispatcher.add_handler( CommandHandler('kontakt_abrufen', commands.start_inline)) dispatcher.add_handler( CommandHandler('start', commands.start_inline, filters=Filters.text(f'/start {INLINE_HELP}'))) # Inline Mode dispatcher.add_handler(InlineQueryHandler(inline.search_users)) dispatcher.add_handler(inline.SEND_VCARD_HANDLER) # Highscores dispatcher.add_handler( CommandHandler('highscore', highscore.show_highscore)) dispatcher.add_handler(highscore.HIGHSCORE_HANDLER) # Set commands dispatcher.bot.set_my_commands(BOT_COMMANDS) # Admin stuff dispatcher.add_handler( CommandHandler('rebuild', bot.admin.rebuild_orchestra, filters=Filters.user(int(admin)))) # Error Handler dispatcher.add_error_handler(error.handle_error) dispatcher.add_error_handler(clear_conversation_status) # Schedule jobs check_user_status.schedule_daily_job(dispatcher) backup.PATH = oc_path backup.URL = oc_url backup.USERNAME = oc_username backup.PASSWORD = oc_password backup.schedule_daily_job(dispatcher) # Set up AkaDressen credentials Member.set_akadressen_credentials(ad_url, ad_url_active, ad_username, ad_password) # Set up bot_data bot_data = dispatcher.bot_data if not bot_data.get(ORCHESTRA_KEY): bot_data[ORCHESTRA_KEY] = Orchestra() else: # We rebuild the orchestra on start up to make sure code changes are applied old_orchestra = bot_data.pop(ORCHESTRA_KEY) new_orchestra = old_orchestra.copy() bot_data[ORCHESTRA_KEY] = new_orchestra if not bot_data.get(PENDING_REGISTRATIONS_KEY): bot_data[PENDING_REGISTRATIONS_KEY] = dict() if not bot_data.get(DENIED_USERS_KEY): bot_data[DENIED_USERS_KEY] = list() bot_data[ADMIN_KEY] = int(admin) yourls_client = YOURLSClient(yourls_url, signature=yourls_signature, nonce_life=True) bot_data[YOURLS_KEY] = yourls_client # Clear conversation key user_data = dispatcher.user_data for user_id in user_data: user_data[user_id].pop(CONVERSATION_KEY, None)
async def main() -> None: """Set up the application and a custom webserver.""" url = "https://domain.tld" admin_chat_id = 123456 port = 8000 context_types = ContextTypes(context=CustomContext) # Here we set updater to None because we want our custom webhook server to handle the updates # and hence we don't need an Updater instance application = (Application.builder().token("TOKEN").updater( None).context_types(context_types).build()) # save the values in `bot_data` such that we may easily access them in the callbacks application.bot_data["url"] = url application.bot_data["admin_chat_id"] = admin_chat_id # register handlers application.add_handler(CommandHandler("start", start)) application.add_handler( TypeHandler(type=WebhookUpdate, callback=webhook_update)) # Pass webhook settings to telegram await application.bot.set_webhook(url=f"{url}/telegram") # Set up webserver async def telegram(request: Request) -> Response: """Handle incoming Telegram updates by putting them into the `update_queue`""" await application.update_queue.put( Update.de_json(data=await request.json(), bot=application.bot)) return Response() async def custom_updates(request: Request) -> PlainTextResponse: """ Handle incoming webhook updates by also putting them into the `update_queue` if the required parameters were passed correctly. """ try: user_id = int(request.query_params["user_id"]) payload = request.query_params["payload"] except KeyError: return PlainTextResponse( status_code=HTTPStatus.BAD_REQUEST, content= "Please pass both `user_id` and `payload` as query parameters.", ) except ValueError: return PlainTextResponse( status_code=HTTPStatus.BAD_REQUEST, content="The `user_id` must be a string!", ) await application.update_queue.put( WebhookUpdate(user_id=user_id, payload=payload)) return PlainTextResponse( "Thank you for the submission! It's being forwarded.") async def health(_: Request) -> PlainTextResponse: """For the health endpoint, reply with a simple plain text message.""" return PlainTextResponse(content="The bot is still running fine :)") starlette_app = Starlette(routes=[ Route("/telegram", telegram, methods=["POST"]), Route("/healthcheck", health, methods=["GET"]), Route("/submitpayload", custom_updates, methods=["POST", "GET"]), ]) webserver = uvicorn.Server(config=uvicorn.Config( app=starlette_app, port=port, use_colors=False, host="127.0.0.1", )) # Run application and webserver together async with application: await application.start() await webserver.serve() await application.stop()
import commands mode = os.getenv("MODE") TOKEN = os.getenv("TOKEN") if __name__ == '__main__': logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) logging.info("Bot launched") updater = Updater(TOKEN) dispatcher = updater.dispatcher # Before all handlers dispatcher.add_handler(TypeHandler(TelegramObject, commands.check_database), group=0) # Inline Handler dispatcher.add_handler(InlineQueryHandler(commands.inline_status), group=1) # Commands Handlers dispatcher.add_handler(CommandHandler('start', commands.cmd_start), group=2) dispatcher.add_handler(CommandHandler('status', commands.cmd_status), group=2) dispatcher.add_handler(CommandHandler('players', commands.cmd_players), group=2) # Message Handler dispatcher.add_handler(MessageHandler(None, commands.message), group=2)
def test_context(self, cdp): handler = TypeHandler(dict, self.callback_context) cdp.add_handler(handler) cdp.process_update({'a': 1, 'b': 2}) assert self.test_flag