def rules(bot, update, quote=True): chat_id = update.effective_chat.id if chat_id == settings.BOTLISTCHAT_ID or util.is_private_message(update): reroute_private_chat(bot, update, quote, const.DeepLinkingActions.RULES, messages.BOTLISTCHAT_RULES) else: update.message.reply_text("Sorry, but I don't know the rules in this group 👻\n\n" + messages.PROMOTION_MESSAGE, parse_mode=ParseMode.MARKDOWN) return ConversationHandler.END
def explore(bot, update, chat_data): cid = update.effective_chat.id uid = update.effective_user.id mid = util.mid_from_update(update) explorable_bots = Bot.explorable_bots() chat_data["explored"] = chat_data.get("explored", list()) # don't explore twice for explored in chat_data["explored"]: explorable_bots.remove(explored) if len(explorable_bots) == 0: util.send_md_message( bot, cid, mdformat.none_action( "You have explored all the bots. Congratulations, you might be the first 😜" ), ) return random_bot = random.choice(explorable_bots) buttons = [ [ InlineKeyboardButton( captions.ADD_TO_FAVORITES, callback_data=util.callback_for_action( CallbackActions.ADD_TO_FAVORITES, {"id": random_bot.id} ), ), InlineKeyboardButton( captions.SHARE, switch_inline_query=random_bot.username ), ], [ InlineKeyboardButton( random_explore_text(), callback_data=util.callback_for_action(CallbackActions.EXPLORE_NEXT), ) ], ] markup = InlineKeyboardMarkup(buttons) text = random_bot.detail_text if uid in settings.MODERATORS and util.is_private_message(update): text += "\n\n🛃 /edit{}".format(random_bot.id) msg = bot.formatter.send_or_edit(cid, text, to_edit=mid, reply_markup=markup) chat_data["explored"].append(random_bot)
def main_menu(bot, update): chat_id = update.effective_chat.id is_admin = chat_id in settings.MODERATORS reply_markup = (ReplyKeyboardMarkup(main_menu_buttons(is_admin), resize_keyboard=True, one_time_keyboard=True) if util.is_private_message(update) else ReplyKeyboardRemove()) bot.sendMessage( chat_id, mdformat.action_hint("What would you like to do?"), reply_markup=reply_markup, )
def start(bot, update, chat_data, args): tg_user = update.message.from_user chat_id = tg_user.id # Get or create the user from/in database User.from_telegram_object(tg_user) if isinstance(args, list) and len(args) > 0: # CATEGORY BY ID try: cat = Category.get(Category.id == args[0]) from botlistbot.components.explore import send_category return send_category(bot, update, chat_data, cat) except (ValueError, Category.DoesNotExist): pass query = " ".join(args).lower() # SPECIFIC DEEP-LINKED QUERIES if query == const.DeepLinkingActions.CONTRIBUTING: return help.contributing(bot, update, quote=False) elif query == const.DeepLinkingActions.EXAMPLES: return help.examples(bot, update, quote=False) elif query == const.DeepLinkingActions.RULES: return help.rules(bot, update, quote=False) elif query == const.DeepLinkingActions.SEARCH: return search_handler(bot, update, chat_data) # SEARCH QUERY search_query(bot, update, chat_data, query) else: bot.sendSticker( chat_id, open( os.path.join(appglobals.ROOT_DIR, "assets", "sticker", "greetings-humanoids.webp"), "rb", ), ) help.help(bot, update) util.wait(bot, update) if util.is_private_message(update): main_menu(bot, update) return ConversationHandler.END
def short_approve_list(bot, update): uid = update.effective_chat.id bots = Bot.select_unapproved() if len(bots) == 0: update.message.reply_text("No bots to be approved.") return txt = "Bots pending approval:\n\n" if uid in settings.MODERATORS and util.is_private_message(update): # append admin edit buttons txt += "\n".join(["{} — /approve{}".format(b, b.id) for b in bots]) else: txt += "\n".join([str(b) for b in bots]) bot.formatter.send_message(uid, txt)
def pending_update(bot, update): uid = update.effective_chat.id bots = Bot.select_pending_update() if len(bots) == 0: update.message.reply_text("No bots pending for update.") return txt = "Bots pending for next Update:\n\n" if uid in settings.MODERATORS and util.is_private_message(update): # append admin edit buttons txt += "\n".join(["{} — /edit{}".format(b, b.id) for b in bots]) else: txt += "\n".join([str(b) for b in bots]) bot.formatter.send_message(uid, txt)
def send_category(bot, update, chat_data, category): uid = util.uid_from_update(update) cid = update.effective_chat.id bots = Bot.of_category_without_new(category)[: settings.MAX_BOTS_PER_MESSAGE] bots_with_description = [b for b in bots if b.description is not None] detailed_buttons_enabled = len( bots_with_description ) > 0 and util.is_private_message(update) callback = CallbackActions.SEND_BOT_DETAILS if detailed_buttons_enabled: buttons = [ InlineKeyboardButton( x.username, callback_data=util.callback_for_action(callback, {"id": x.id}), ) for x in bots_with_description ] else: buttons = [] menu = util.build_menu(buttons, 2) menu.insert( 0, [ InlineKeyboardButton( captions.BACK, callback_data=util.callback_for_action(CallbackActions.SELECT_CATEGORY), ), InlineKeyboardButton( "Show in BotList", url="http://t.me/botlist/{}".format(category.current_message_id), ), InlineKeyboardButton("Share", switch_inline_query=category.name), ], ) txt = "There are *{}* bots in the category *{}*:\n\n".format( len(bots), str(category) ) if uid in settings.MODERATORS and util.is_private_message(update): # append admin edit buttons txt += "\n".join(["{} — /edit{} 🛃".format(b, b.id) for b in bots]) else: txt += "\n".join([str(b) for b in bots]) if detailed_buttons_enabled: txt += "\n\n" + util.action_hint( "Press a button below to get a detailed description." ) reply_markup = InlineKeyboardMarkup(menu) reply_markup, callback = botlistchat.append_restricted_delete_button( update, chat_data, reply_markup ) msg = bot.formatter.send_or_edit( cid, txt, to_edit=util.mid_from_update(update), reply_markup=reply_markup ) callback(msg) Statistic.of( update, "menu", "of category {}".format(str(category)), Statistic.ANALYSIS )
def new_bot_submission(bot, update, chat_data, args=None, bot_checker=None): tg_user = update.message.from_user user = User.from_telegram_object(tg_user) if util.stop_banned(update, user): return reply_to = util.original_reply_id(update) if args: text = " ".join(args) else: text = update.message.text command_no_args = ( len(re.findall(r"^/new\s*$", text)) > 0 or text.lower().strip() == "/new@botlistbot" ) if command_no_args: update.message.reply_text( util.action_hint( "Please use this command with an argument. For example:\n/new @mybot 🔎" ), reply_to_message_id=reply_to, ) return # `#new` is already checked by handler try: username = re.match(settings.REGEX_BOT_IN_TEXT, text).groups()[0] if username.lower() == "@" + settings.SELF_BOT_NAME.lower(): log.info("Ignoring {}".format(text)) return except AttributeError: if args: update.message.reply_text( util.failure("Sorry, but you didn't send me a bot `@username`."), quote=True, parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply_to, ) log.info("Ignoring {}".format(text)) # no bot username, ignore update return try: new_bot = Bot.by_username(username, include_disabled=True) if new_bot.disabled: update.message.reply_text( util.failure( "{} is banned from the @BotList.".format(new_bot.username) ), reply_to_message_id=reply_to, ) elif new_bot.approved: update.message.reply_text( util.action_hint( "Sorry fool, but {} is already in the @BotList 😉".format( new_bot.username ) ), reply_to_message_id=reply_to, ) else: update.message.reply_text( util.action_hint( "{} has already been submitted. Please have patience...".format( new_bot.username ) ), reply_to_message_id=reply_to, ) return except Bot.DoesNotExist: new_bot = Bot( revision=Revision.get_instance().next, approved=False, username=username, submitted_by=user, ) new_bot.inlinequeries = "🔎" in text new_bot.official = "🔹" in text # find language languages = Country.select().execute() for lang in languages: if lang.emoji in text: new_bot.country = lang new_bot.date_added = datetime.date.today() description_reg = re.match(settings.REGEX_BOT_IN_TEXT + " -\s?(.*)", text) description_notify = "" if description_reg: description = description_reg.group(2) new_bot.description = description description_notify = " Your description was included." new_bot.save() if ( util.is_private_message(update) and util.uid_from_update(update) in settings.MODERATORS ): from botlistbot.components.explore import send_bot_details send_bot_details(bot, update, chat_data, new_bot) else: update.message.reply_text( util.success( "You submitted {} for approval.{}".format(new_bot, description_notify) ), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply_to, ) # Ask the user to fill in the bot details util.send_md_message( bot, update.effective_user.id, "Congratulations, you just submitted a bot to the @BotList. Please help us fill in the details below:", ) edit_bot(bot, update, chat_data, to_edit=new_bot) try: check_submission(bot, bot_checker, new_bot) except Exception as e: log.exception(e) return ConversationHandler.END
def search_query(bot, update: Update, chat_data, query, send_errors=True): cid: int = update.effective_chat.id user: User = User.from_update(update) is_admin: bool = cid in settings.MODERATORS replied_to_message_id: Optional[int] = util.original_reply_id(update) is_suggestion_by_other: bool = (update.effective_chat and update.effective_chat.id == settings.BOTLISTCHAT_ID) results = search.search_bots(query) reply_markup = (ReplyKeyboardMarkup(basic.main_menu_buttons(is_admin), resize_keyboard=True) if util.is_private_message(update) else None) if results: if len(results) == 1: update.effective_message.delete() if is_suggestion_by_other: header = f"{user.markdown_short} found the following bot for you:" else: header = "I found the following bot for you:" return send_bot_details(bot, update, chat_data, results[0], header_msg=header) too_many_results = len(results) > settings.MAX_SEARCH_RESULTS bots_list = "" if cid in settings.MODERATORS: # private chat with moderator # append edit buttons bots_list += "\n".join([ "{} — /edit{} 🛃".format(b, b.id) for b in list(results)[:100] ]) else: bots_list += "\n".join( [str(b) for b in list(results)[:settings.MAX_SEARCH_RESULTS]]) bots_list += "\n…" if too_many_results else "" bots_list = messages.SEARCH_RESULTS.format( bots=bots_list, num_results=len(results), plural="s" if len(results) > 1 else "", query=query, ) if util.is_group_message( update) and not update.message.reply_to_message: try: bot.formatter.send_message( update.effective_user.id, bots_list, reply_markup=reply_markup, disable_web_page_preview=True, ) reply_markup, callback = botlistchat.append_restricted_delete_button( update, chat_data, InlineKeyboardMarkup([[]])) msg = bot.formatter.send_message( update.effective_chat.id, f"Hey {user.plaintext}, let's not annoy the others. I sent you the search results " f"[in private chat](https://t.me/{settings.SELF_BOT_NAME}).", disable_web_page_preview=True, reply_markup=reply_markup, ) callback(msg) update.effective_message.delete() except TelegramError: hint_msg, hint_reply_markup, _ = get_hint_data("#private") bot.formatter.send_message( update.effective_chat.id, hint_msg, reply_markup=hint_reply_markup, reply_to_message_id=update.effective_message.id, disable_web_page_preview=True, ) return ConversationHandler.END if is_suggestion_by_other and replied_to_message_id: bots_list = f"{user.markdown_short} suggests to search and {bots_list}" bot.formatter.send_message( update.effective_chat.id, bots_list, parse_mode=ParseMode.MARKDOWN, reply_markup=reply_markup, disable_web_page_preview=True, reply_to_message_id=replied_to_message_id, ) update.effective_message.delete() else: if send_errors: callback = None if util.is_group_message(update): reply_markup, callback = botlistchat.append_restricted_delete_button( update, chat_data, InlineKeyboardMarkup([[]])) msg = update.message.reply_text( util.failure("Sorry, I couldn't find anything related " "to *{}* in the @BotList. /search".format( util.escape_markdown(query))), parse_mode=ParseMode.MARKDOWN, reply_markup=reply_markup, ) if callback: callback(msg) return ConversationHandler.END