def set_spamwatch_action(bot: octobot.OctoBot, ctx: octobot.Context): if len(ctx.args) > 0: action = ctx.args[0] if action in VALID_ACTIONS: ctx.chat_db[SPAMWATCH_DB_KEY] = action ctx.reply( ctx.localize("Action {action} set. ").format(action=action) + ctx.localize(VALID_ACTIONS[action][0])) return else: msg = [ f'<code>{action}</code> ' + ctx.localize("is not a valid action.") ] else: msg = [ ctx.localize("You hadn't specified action to set!"), ] msg.append(ctx.localize("Available actions:")) cur_act = ctx.chat_db.get(SPAMWATCH_DB_KEY, Settings.spamwatch.default_action) is_default_str = f'<b>({ctx.localize("Default")})</b>' for action, (action_desc, _) in VALID_ACTIONS.items(): msg.append( f"<code>{action}</code> - {ctx.localize(action_desc)} " f"{is_default_str if action == Settings.spamwatch.default_action else ''}" ) msg.append( ctx.localize("Current action in this chat is") + f" <code>{cur_act}</code>") ctx.reply("\n".join(msg), parse_mode="HTML")
def start(bot: octobot.OctoBot, ctx: octobot.Context): if ctx.query == "": kbd = telegram.InlineKeyboardMarkup( [[ telegram.InlineKeyboardButton( ctx.localize("Command list"), url=f"https://t.me/{bot.me.username}?start=help") ], [ telegram.InlineKeyboardButton(ctx.localize("Support chat"), url=Settings.support_url) ]]) ctx.reply(ctx.localize( "Hi! I am {bot.me.first_name}, a Telegram bot with features and bugs and blah blah, noone reads /start anyway." ).format(bot=bot), reply_markup=kbd) else: # Proxify to other command update = ctx.update if ctx.args[0].startswith("b64-"): b64data = ctx.args[0].replace("b64-", "", 1) data = base64.urlsafe_b64decode(b64data) logger.debug(f'proxying b64 command {data} ({b64data})') update.message.text = data.decode() else: update.message.text = "/" + ctx.args[0] logger.debug("proxying plaintext command", update.message.text) bot.handle_update(bot, update)
def warnlist(bot: octobot.OctoBot, context: octobot.Context): if octobot.Database.redis is None: raise octobot.DatabaseNotAvailable reply = context.update.message.reply_to_message if reply is not None: target = reply.from_user.id target_name = reply.from_user.first_name elif len(context.args) > 0: target = context.args[0] if target.isdigit(): target = int(target) target_name = f"ID:{target}" else: if target.startswith("@"): target = target[1:] target_name = target res, target = lookup_username(target) if not res: return context.reply( context.localize("Failed to find username {username}"). format(username=target_name)) else: target = context.user.id target_name = context.user.first_name message = [context.localize("Warns for {name}:").format(name=target_name)] warns = octobot.Database.redis.lrange( create_warn_db_id(context.chat.id, target), 0, -1) if len(warns) == 0: context.reply( context.localize("{name} has no warns!").format(name=target_name)) else: for warn_reason in warns: message.append(f"- {warn_reason.decode()}") context.reply("\n".join(message))
def ping(bot: OctoBot, ctx: Context): user_id = ctx.user.id if ctx.update.message: chat_id = ctx.update.message.chat.id chat_type = ctx.update.message.chat.type elif ctx.update.inline_query: chat_id = "None" chat_type = "Inline Query" else: return ctx.reply("Cant understand what is going on in that update of yours") message = [ctx.localize("{} ID:<code>{}</code>").format(ctx.user.mention_html(ctx.localize("Your")), user_id), ctx.localize("Chat ID:<code>{}</code>").format(chat_id), ctx.localize("Chat type is <code>{}</code>").format(chat_type)] if ctx.update.message: msg = ctx.update.message message.append(ctx.localize("ID of your message: <code>{}</code>").format(ctx.update.message.message_id)) if msg.reply_to_message: reply = msg.reply_to_message message.append(ctx.localize("ID of replied message: <code>{}</code>").format(reply.message_id)) if reply.from_user.id: message.append(ctx.localize("ID of {} from replied message: {}").format((reply.from_user.mention_html("user")), reply.from_user.id)) if reply.forward_from: message.append(ctx.localize("Forward {} ID: {}").format((reply.forward_from.mention_html("user")), reply.forward_from.id)) if reply.forward_from_message_id: message.append(ctx.localize("Forwarded message ID in original chat: {}").format(reply.forward_from_message_id)) if reply.forward_from_chat: message.append(ctx.localize("Forwarded message original chat ({}) ID: {}").format(reply.forward_from_chat.title, reply.forward_from_chat.id)) ctx.reply("\n".join(message), parse_mode='html')
def help_extra(bot, ctx: octobot.Context): if ctx.query != "": cmd = ctx.query for handlers in bot.handlers.values(): for handler in handlers: if isinstance( handler, octobot.CommandHandler) and cmd in handler.command: message = "{helpfor} {command}.\n{description}\n\n{long_description}".format( helpfor=ctx.localize("Help for"), command=handler.prefix + ctx.query, description=html.escape(handler.description), long_description=html.escape(handler.long_description)) ctx.reply(message) return
def list_bannedpacks(bot: octobot.OctoBot, context: octobot.Context): if octobot.Database.redis is None: raise octobot.DatabaseNotAvailable if octobot.Database.redis.scard(create_redis_set_name(context.chat)) > 0: message = [ context.localize( "This stickerpacks are currently banned in <b>{chat_name}</b>:" ).format(chat_name=html.escape(context.chat.title)) ] for pack in octobot.Database.redis.smembers( create_redis_set_name(context.chat)): message.append( '- <a href="https://t.me/addstickers/{pack_id}">{pack_id}</a>'. format(pack_id=html.escape(pack.decode()))) context.reply("\n".join(message), parse_mode="HTML") else: context.reply( context.localize( "There are no stickerpacks that are banned in this chat"))
def button_pin(bot: octobot.OctoBot, context: octobot.Context): chat_id, message_id = context.text.split(":")[1:] perm_check, missing_perms = octobot.check_permissions( chat=chat_id, user=context.user.id, bot=bot, permissions_to_check={"can_pin_messages"}) if perm_check: bot.pin_chat_message(chat_id, message_id, disable_notification=True) context.reply(context.localize("Pinned back the old message")) msg = context.update.effective_message.text_html + "\n\n" + context.localize( 'This action was undone by <a href="tg://user?id={admin_id}">{admin}</a>' ).format(admin_id=context.user.id, admin=html.escape(context.user.first_name)) context.edit(msg, parse_mode="HTML") else: context.reply( context.localize( "Sorry, you can't execute this command cause you lack following permissions: {}" ).format(", ".join(missing_perms)))
def toggle_pack_command(bot: octobot.OctoBot, context: octobot.Context): if octobot.Database.redis is None: raise octobot.DatabaseNotAvailable no_pack_msg = context.localize( "Reply to sticker from stickerpack which you want to ban or pass the pack name as argument" ) if context.update.message.reply_to_message is not None: if context.update.message.reply_to_message.sticker is not None: target_pack = str( context.update.message.reply_to_message.sticker.set_name) else: return context.reply(no_pack_msg) elif len(context.args) > 0: target_pack = context.args[0] else: return context.reply(no_pack_msg) if octobot.Database.redis.sadd(create_redis_set_name(context.chat), target_pack) == 1: context.reply(context.localize( 'Pack <a href="https://t.me/addstickers/{pack_id}">{pack_id}</a> banned successfully' .format(pack_id=target_pack)), parse_mode="HTML") else: octobot.Database.redis.srem(create_redis_set_name(context.chat), target_pack) context.reply(context.localize( 'Pack <a href="https://t.me/addstickers/{pack_id}">{pack_id}</a> unbanned successfully' .format(pack_id=target_pack)), parse_mode="HTML")
def warn(bot: octobot.OctoBot, context: octobot.Context): if octobot.Database.redis is None: raise octobot.DatabaseNotAvailable if context.update.message.reply_to_message is None: context.reply(context.localize("Reply to user to give them a warn")) return if octobot.check_permissions( chat=context.chat, user=context.update.message.reply_to_message.from_user, permissions_to_check={"is_admin"})[0]: context.reply(context.localize("Can't warn administrator")) return target_id = context.update.message.reply_to_message.from_user.id target_name = context.update.message.reply_to_message.from_user.first_name user_warns_db_id = create_warn_db_id(context.chat.id, target_id) max_warns = int(context.chat_db.get("max_warns", 3)) reason = context.query if reason == "": reason = context.localize("Warn reason not specified") octobot.Database.redis.lpush(user_warns_db_id, reason) user_warn_count = int(octobot.Database.redis.llen(user_warns_db_id)) action_taken = "" reply_markup = telegram.InlineKeyboardMarkup.from_button( telegram.InlineKeyboardButton( text="Remove last warn", callback_data=f"warn_cancel:{target_id}:{context.chat.id}")) if user_warn_count >= max_warns: action_taken = context.localize( "\n\n<i>User had reached maximum warnings in chat and was banned</i>" ) bot.kick_chat_member(chat_id=context.chat.id, user_id=target_id) octobot.Database.redis.delete(user_warns_db_id) reply_markup = telegram.InlineKeyboardMarkup.from_button( telegram.InlineKeyboardButton( callback_data=f"ban_cancel:{target_id}:{context.chat.id}", text=context.localize("Unban"))) context.reply(context.localize('⚠�<a href="tg://user?id={admin_id}">{admin}</a> warned ' + \ '<a href="tg://user?id={target_id}">{target_name}</a> ' + \ '({warn_count}/{max_warns})' + \ '\nReason: <i>{reason}</i>').format( admin_id=context.user.id, admin=html.escape(context.user.first_name), target_id=target_id, target_name=html.escape(target_name), reason=html.escape(reason), warn_count=user_warn_count, max_warns=max_warns ) + action_taken, parse_mode="HTML", reply_markup=reply_markup)
def gtl(bot: octobot.OctoBot, context: octobot.Context): if context.update.message is not None and context.update.message.reply_to_message is not None: reply = context.update.message.reply_to_message if reply.caption is not None: text = reply.caption else: text = reply.text text_type = "reply" else: text = str(context.query) text_type = "args" source_language = None destination_language = None default_language = octobot.localization.get_chat_locale(context.update) if len(context.args) > 0: arg_0 = context.args[0] if arg_0 in googletrans.LANGUAGES: destination_language = arg_0 destination_language.replace("_", "-") if text_type == "args": text = " ".join(context.args[1:]) elif arg_0.count("-") == 1: source_language, destination_language = arg_0.split("-") source_language.replace("_", "-") destination_language.replace("_", "-") if text_type == "args": text = " ".join(context.args[1:]) if source_language not in googletrans.LANGUAGES: source_language = "auto" if destination_language not in googletrans.LANGUAGES: destination_language = default_language translation = translator.translate(text, dest=destination_language, src=source_language) return context.reply(context.localize(TRANSLATION_TEMPLATE).format( source_language=googletrans.LANGUAGES[translation.src].title(), target_language=googletrans.LANGUAGES[translation.dest].title(), text=html.escape(translation.text)), parse_mode="HTML")
def execute_cancel(bot: octobot.OctoBot, context: octobot.Context, func: typing.Callable, reply_text: str): tgt_id, chat_id = context.text.split(":")[1:] perm_check, missing_perms = octobot.check_permissions( chat=chat_id, user=context.user.id, bot=bot, permissions_to_check={"can_restrict_members"}) if perm_check: if tgt_id.isdigit(): func(chat_id=chat_id, user_id=tgt_id) context.reply(reply_text) msg = context.update.effective_message.text_html + "\n\n" + context.localize( 'This action was undone by <a href="tg://user?id={admin_id}">{admin}</a>' ).format(admin_id=context.user.id, admin=html.escape(context.user.first_name)) context.edit(msg, parse_mode="HTML") else: context.reply(context.localize("Invalid ID passed")) else: context.reply( context.localize( "Sorry, you can't execute this command cause you lack following permissions: {}" ).format(", ".join(missing_perms)))
def pmtest(bot, ctx: octobot.Context): ctx.reply("Check your PMs!") ctx.reply("Test", to_pm=True)
def ping(bot: OctoBot, ctx: Context): time = (datetime.datetime.utcnow().replace(tzinfo=pytz.UTC) - ctx.update.message.date).total_seconds() ctx.reply(ctx.localize("🏓 Pong! Reply latency: %.2fs") % time)
def execute_command(func: typing.Callable, context: octobot.Context, success_message: str, action: str, cancel: str = None): reply = context.update.message.reply_to_message if reply is not None: target = reply.from_user.id target_name = reply.from_user.first_name elif len(context.args) > 0: target = context.args[0] target_name = f"ID:{target}" if not target.isdigit(): if target.startswith("@"): target = target[1:] target_name = f"@{target}" success, target = lookup_username(target) if not success: context.reply( context.localize( "I hadn't seen the person whose username is @{username}" ).format(target)) return else: target = int(target) else: context.reply( context.localize( "You hadn't specified the target!" + \ "Reply to message of person you want to {action} or specify their ID or username").format( action=action)) return if octobot.check_permissions(chat=context.chat, user=target, permissions_to_check={"is_admin"})[0]: context.reply( context.localize("I can't {action} administrators.").format( action=action)) return try: func(chat_id=context.chat.id, user_id=target) except telegram.error.BadRequest as e: context.reply(context.localize( 'Can\'t {action} <a href="tg://user?id={target}">{target_name}</a>.\nError: <code>{error}</code>.' ).format(action=action, target=html.escape(target_name), error=html.escape(e.message)), parse_mode="html") else: cancel_markup = None if cancel is not None: cancel_markup = telegram.InlineKeyboardMarkup.from_button( telegram.InlineKeyboardButton( text=context.localize("Cancel"), callback_data=f"{cancel}:{target}:{context.chat.id}")) context.reply(success_message.format( admin_name=html.escape(context.user.first_name), admin_id=context.user.id, target=target, target_name=html.escape(target_name)), parse_mode="html", reply_markup=cancel_markup)