def send_debug(client: Client, message: Message, action: str, uid: int, aid: int, em: Message = None, reason: str = None) -> bool: # Send the debug message try: text = get_debug_text(client, message.chat) text += (f"{lang('user_id')}{lang('colon')}{code(uid)}\n" f"{lang('action')}{lang('colon')}{code(action)}\n" f"{lang('admin_group')}{lang('colon')}{code(aid)}\n") if em: text += f"{lang('stored_message')}{lang('colon')}{general_link(em.message_id, message_link(em))}\n" # If the message is a report callback message if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" elif message.from_user.is_self and action not in { lang("action_unban"), lang("action_unwarns") }: text += f"{lang('reason')}{lang('colon')}{code(lang('by_button'))}\n" else: reason = get_command_type(message) if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" thread(send_message, (client, glovar.debug_channel_id, text)) except Exception as e: logger.warning(f"Send debug error: {e}", exc_info=True) return False
def get_config_text(config: dict) -> str: # Get config text result = "" try: # Basic default_text = (lambda x: lang("default") if x else lang("custom"))(config.get("default")) delete_text = (lambda x: lang("enabled") if x else lang("disabled"))(config.get("delete")) result += (f"{lang('config')}{lang('colon')}{code(default_text)}\n" f"{lang('delete')}{lang('colon')}{code(delete_text)}\n") # Limit limit_text = config.get("limit") result += f"{lang('limit')}{lang('colon')}{code(limit_text)}\n" # Mention mention_text = (lambda x: lang("enabled") if x else lang("disabled"))(config.get("mention")) result += f"{lang('mention')}{lang('colon')}{code(mention_text)}\n" # Report for the_type in ["auto", "manual"]: the_bool = config.get("report") and config["report"].get(the_type) the_text = (lambda x: lang("enabled") if x else lang("disabled"))(the_bool) result += f"{lang(f'report_{the_type}')}{lang('colon')}{code(the_text)}\n" except Exception as e: logger.warning(f"Get config text error: {e}", exc_info=True) return result
def undo_user(client: Client, message: Message, aid: int, uid: int, action_type: str) -> str: try: # Basic gid = message.chat.id mid = message.message_id # Init user data if not init_user_id(uid): return "" # Check the user's lock if gid in glovar.user_ids[uid]["lock"]: return lang("answer_proceeded") # Proceed glovar.user_ids[uid]["lock"].add(gid) try: if action_type == "ban": text = unban_user(client, message, uid, aid) else: text = unwarn_user(client, message, uid, aid) thread(edit_message_text, (client, gid, mid, text)) finally: glovar.user_ids[uid]["lock"].discard(gid) # Save data save("user_ids") except Exception as e: logger.warning(f"Undo user error: {e}", exc_info=True) return ""
def unban_user(client: Client, message: Message, uid: int, aid: int) -> str: # Unban a user text = "" try: # Basic data gid = message.chat.id # Check ban status if gid not in glovar.user_ids[uid]["ban"]: text = ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_unban'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text # Proceed unban_chat_member(client, gid, uid) glovar.user_ids[uid]["ban"].discard(gid) update_score(client, uid) text = ( f"{lang('user_unbanned')}{lang('colon')}{code(uid)}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) send_debug(client=client, message=message, action=lang("action_unban"), uid=uid, aid=aid) except Exception as e: logger.warning(f"Unban user error: {e}", exc_info=True) return text
def mention_answer(client: Client, message: Message, aid: int, uid: int, action_type: str) -> str: # Mention abuse try: # Basic data gid = message.chat.id mid = message.message_id # Abuse if action_type == "abuse": message.reply_to_message = message message.reply_to_message.from_user.id = uid message.reply_to_message.from_user.is_self = lang("abuse_mention") text, markup = warn_user(client, message, uid, aid) text += f"{lang('reason')}{lang('colon')}{code(lang('reason_abuse'))}\n" # Edit the report message thread(edit_message_text, (client, gid, mid, text, markup)) delay(180, delete_message, [client, gid, mid]) # Delete elif action_type == "delete": glovar.message_ids[gid] = (0, 0) save("message_ids") delete_message(client, gid, mid) except Exception as e: logger.warning(f"Mention answer error: {e}", exc_info=True) return ""
def receive_leave_approve(client: Client, data: dict) -> bool: # Receive leave approve result = False try: # Basic data admin_id = data["admin_id"] the_id = data["group_id"] force = data["force"] reason = data["reason"] if reason in {"permissions", "user"}: reason = lang(f"reason_{reason}") if not glovar.admin_ids.get(the_id) and not force: return True text = get_debug_text(client, the_id) text += ( f"{lang('admin_project')}{lang('colon')}{mention_id(admin_id)}\n" f"{lang('status')}{lang('colon')}{code(lang('leave_approve'))}\n") if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" leave_group(client, the_id) thread(send_message, (client, glovar.debug_channel_id, text)) result = True except Exception as e: logger.warning(f"Receive leave approve error: {e}", exc_info=True) return result
def unwarn_user(client: Client, message: Message, uid: int, aid: int) -> str: # Unwarn a user text = "" try: # Basic data gid = message.chat.id # Check ban status if gid in glovar.user_ids[uid]["ban"]: text = ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_unwarn'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text # Check warnings count if not glovar.user_ids[uid]["warn"].get(gid, 0): text = ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{lang('action_unwarn')}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text # Proceed glovar.user_ids[uid]["warn"][gid] -= 1 warn_count = glovar.user_ids[uid]["warn"][gid] if warn_count == 0: glovar.user_ids[uid]["warn"].pop(gid, 0) update_score(client, uid) text = ( f"{lang('user_unwarned')}{lang('colon')}{mention_id(uid)}\n" f"{lang('user_warns')}{lang('colon')}{code(lang('reason_none'))}\n" ) send_debug(client=client, message=message, action=lang("action_unwarns"), uid=uid, aid=aid) else: limit = glovar.configs[gid]["limit"] text = ( f"{lang('user_unwarned')}{lang('colon')}{mention_id(uid)}\n" f"{lang('user_warns')}{lang('colon')}{code(f'{warn_count}/{limit}')}\n" ) text += f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" except Exception as e: logger.warning(f"Unwarn user error: {e}", exc_info=True) return text
def receive_config_reply(client: Client, data: dict) -> bool: # Receive config reply try: # Basic data gid = data["group_id"] uid = data["user_id"] link = data["config_link"] text = ( f"{lang('admin')}{lang('colon')}{code(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n" f"{lang('description')}{lang('colon')}{code(lang('config_button'))}\n" ) markup = InlineKeyboardMarkup( [[InlineKeyboardButton(text=lang("config_go"), url=link)]]) thread(send_report_message, (180, client, gid, text, None, markup)) return True except Exception as e: logger.warning(f"Receive config reply error: {e}", exc_info=True) return False
def get_class_d_id(message: Message) -> (int, int): # Get Class D personnel's id uid = 0 mid = 0 try: r_message = message.reply_to_message if not r_message or not is_from_user(None, None, r_message): return 0, 0 if not is_class_c(None, None, r_message): uid = r_message.from_user.id mid = r_message.message_id elif r_message.from_user.is_self: uid = get_int( r_message.text.split("\n")[0].split(lang("colon"))[1]) if uid in glovar.admin_ids[message.chat.id]: uid = 0 except Exception as e: logger.warning(f"Get class d id error: {e}", exc_info=True) return uid, mid
def warn_user(client: Client, message: Message, uid: int, aid: int, reason: str = None) -> (str, InlineKeyboardMarkup): # Warn a user text = "" markup = None try: # Basic data gid = message.chat.id # Init user data if not init_user_id(uid): return "", None # Check users' locks if gid in glovar.user_ids[uid]["lock"]: return "", None # Proceed glovar.user_ids[uid]["lock"].add(gid) try: # Check ban status if gid in glovar.user_ids[uid]["ban"]: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_warn'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, None # Forward evidence result = forward_evidence(client=client, message=message.reply_to_message, level=lang("action_warn")) # Check message if not result: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_warn'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, None # Add warn count if not glovar.user_ids[uid]["warn"].get(gid, 0): glovar.user_ids[uid]["warn"][gid] = 1 update_score(client, uid) else: glovar.user_ids[uid]["warn"][gid] += 1 # Read count and group config warn_count = glovar.user_ids[uid]["warn"][gid] limit = glovar.configs[gid]["limit"] # Warn or ban if warn_count >= limit: glovar.user_ids[uid]["lock"].discard(gid) text = ( f"{lang('user_banned')}{lang('colon')}{mention_id(uid)}\n" f"{lang('ban_reason')}{lang('colon')}{code(lang('reason_limit'))}\n" ) _, markup = ban_user(client, message, uid, aid, result, reason) else: text = ( f"{lang('user_warned')}{lang('colon')}{mention_id(uid)}\n" f"{lang('user_warns')}{lang('colon')}{code(f'{warn_count}/{limit}')}\n" ) data = button_data("undo", "warn", uid) markup = InlineKeyboardMarkup([[ InlineKeyboardButton(text=lang("undo"), callback_data=data) ]]) send_debug(client=client, message=message, action=lang("action_warn"), uid=uid, aid=aid, em=result, reason=reason) stored_link = general_link(result.message_id, message_link(result)) text += ( f"{lang('stored_message')}{lang('colon')}{stored_link}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) if markup and reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" finally: glovar.user_ids[uid]["lock"].discard(gid) except Exception as e: logger.warning(f"Warn user error: {e}", exc_info=True) return text, markup
def report_user(gid: int, user: User, rid: int, mid: int, name: str = None, reason: str = None) -> (str, InlineKeyboardMarkup, str): # Report a user text = "" markup = None key = "" try: if user: uid = user.id else: return "", None glovar.user_ids[uid]["waiting"].add(gid) glovar.user_ids[rid]["waiting"].add(gid) save("user_ids") key = random_str(8) while glovar.reports.get(key): key = random_str(8) glovar.reports[key] = { "time": get_now(), "group_id": gid, "reporter_id": rid, "user_id": uid, "message_id": mid, "report_id": 0, "reason": reason } if rid: reporter_text = code("██████") else: reporter_text = code(lang("auto_triggered")) text = f"{lang('reported_user')}{lang('colon')}{mention_id(uid)}\n" if name: text += f"{lang('reported_name')}{lang('colon')}{code(name)}\n" text += ( f"{lang('reported_message')}{lang('colon')}{general_link(mid, f'{get_channel_link(gid)}/{mid}')}\n" f"{lang('reporter')}{lang('colon')}{reporter_text}\n" f"{lang('mention_admins')}{lang('colon')}{get_admin_text(gid)}\n" f"{lang('description')}{lang('colon')}{code(lang('description_wait_admin'))}\n" ) if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" warn_data = button_data("report", "warn", key) ban_data = button_data("report", "ban", key) cancel_data = button_data("report", "cancel", key) markup_list = [[ InlineKeyboardButton(text=lang("warn"), callback_data=warn_data), InlineKeyboardButton(text=lang("ban"), callback_data=ban_data) ], [ InlineKeyboardButton(text=lang("cancel"), callback_data=cancel_data) ]] if rid: abuse_data = button_data("report", "abuse", key) markup_list[1].append( InlineKeyboardButton(text=lang("abuse"), callback_data=abuse_data)) markup = InlineKeyboardMarkup(markup_list) except Exception as e: logger.warning(f"Report user error: {e}", exc_info=True) return text, markup, key
def remove_user(client: Client, message: Message, uid: int, aid: int, reason: str = None) -> (str, bool): # Kick a user text = "" success = False try: # Basic data gid = message.chat.id # Check admin if is_limited_admin(gid, aid): return "", False # Init user data if not init_user_id(uid): return "", False # Check users' locks if gid in glovar.user_ids[uid]["lock"]: return "", False # Proceed glovar.user_ids[uid]["lock"].add(gid) try: # Check ban status if gid in glovar.user_ids[uid]["ban"]: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_kick'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, False # Forward evidence result = forward_evidence(client=client, message=message.reply_to_message, level=lang("action_kick")) # Check message if not result: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_kick'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, False # Count admin operation glovar.counts[gid][aid] += 1 # Kick the user kick_user(client, gid, uid) glovar.user_ids[uid]["kick"].add(gid) update_score(client, uid) # Generate report text stored_link = general_link(result.message_id, message_link(result)) text += ( f"{lang('user_kicked')}{lang('colon')}{mention_id(uid)}\n" f"{lang('stored_message')}{lang('colon')}{stored_link}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" # Update success status success = True # Share ask_for_help(client, "delete", gid, uid) send_debug(client=client, message=message, action=lang("action_kick"), uid=uid, aid=aid, em=result, reason=reason) finally: glovar.user_ids[uid]["lock"].discard(gid) except Exception as e: logger.warning(f"Remove user error: {e}", exc_info=True) return text, success
def forgive_user(client: Client, message: Message, uid: int, reason: str = None) -> (str, bool): # Forgive user text = "" success = False try: # Basic data gid = message.chat.id aid = message.from_user.id # Init user data if not init_user_id(uid): return "", False # Check users' locks if gid in glovar.user_ids[uid]["lock"]: return "", False # Proceed glovar.user_ids[uid]["lock"].add(gid) try: # Text prefix text += f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" if gid in glovar.user_ids[uid]["ban"]: glovar.user_ids[uid]["ban"].discard(gid) thread(unban_chat_member, (client, gid, uid)) text += ( f"{lang('action')}{lang('colon')}{code(lang('action_unban'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n" ) success = True elif glovar.user_ids[uid]["warn"].get(gid, 0): glovar.user_ids[uid]["warn"].pop(gid, 0) text += ( f"{lang('action')}{lang('colon')}{code(lang('action_unwarns'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n" ) success = True elif gid in glovar.user_ids[uid]["waiting"]: glovar.user_ids[uid]["waiting"].discard(gid) text += ( f"{lang('action')}{lang('colon')}{code(lang('action_unwait'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n" ) success = True else: text += ( f"{lang('action')}{lang('colon')}{code(lang('action_forgive'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n" ) success = False text += f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" if not success: return text, success save("user_ids") if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" update_score(client, uid) send_debug(client=client, message=message, action=lang("action_forgive"), uid=uid, aid=aid, reason=reason) finally: glovar.user_ids[uid]["lock"].discard(gid) except Exception as e: logger.warning(f"Forgive user error: {e}") return text, success
def forward_evidence(client: Client, message: Message, level: str, more: str = None) -> Optional[Union[bool, Message]]: # Forward the message to logging channel as evidence result = None try: if not message or not message.from_user: return result # Basic information uid = message.from_user.id text = (f"{lang('project')}{lang('colon')}{code(glovar.sender)}\n" f"{lang('user_id')}{lang('colon')}{code(uid)}\n" f"{lang('level')}{lang('colon')}{code(level)}\n" f"{lang('rule')}{lang('colon')}{code(lang('rule_admin'))}\n") # Additional information if message.game: text += f"{lang('message_type')}{lang('colon')}{code(lang('gam'))}\n" elif message.service: text += f"{lang('message_type')}{lang('colon')}{code(lang('ser'))}\n" if message.game: text += f"{lang('message_game')}{lang('colon')}{code(message.game.short_name)}\n" if message.from_user.is_self: if message.from_user.is_self is True: if message.entities: for en in message.entities: if not en.user: continue name = get_full_name(en.user) if not name: continue text += f"{lang('user_name')}{lang('colon')}{code(name)}\n" break text += f"{lang('more')}{lang('colon')}{code(lang('from_self'))}\n" # User didn't use report function wisely, should not forward evidence else: text += f"{lang('more')}{lang('colon')}{code(message.from_user.is_self)}" result = send_message(client, glovar.warn_channel_id, text) return result name = get_full_name(message.from_user) if name: text += f"{lang('user_name')}{lang('colon')}{code(name)}\n" if message.service and level == lang("action_ban"): bio = get_user_bio(client, uid) if bio: text += f"{lang('user_bio')}{lang('colon')}{code(bio)}\n" # Extra information if message.contact or message.location or message.venue or message.video_note or message.voice: text += f"{lang('more')}{lang('colon')}{code(lang('privacy'))}\n" elif message.game or message.service: text += f"{lang('more')}{lang('colon')}{code(lang('cannot_forward'))}\n" elif more: text += f"{lang('more')}{lang('colon')}{code(more)}\n" # DO NOT try to forward these types of message if (message.contact or message.location or message.venue or message.video_note or message.voice or message.game or message.service): result = send_message(client, glovar.warn_channel_id, text) return result flood_wait = True while flood_wait: flood_wait = False try: result = message.forward(chat_id=glovar.warn_channel_id, disable_notification=True) except FloodWait as e: flood_wait = True wait_flood(e) except Exception as e: logger.info(f"Forward evidence message error: {e}", exc_info=True) return False result = result.message_id result = send_message(client, glovar.warn_channel_id, text, result) except Exception as e: logger.warning(f"Forward evidence error: {e}", exc_info=True) return result
def config_directly(client: Client, message: Message) -> bool: # Config the bot directly if not message or not message.chat: return True # Basic data gid = message.chat.id mid = message.message_id try: # Check permission if not is_class_c(None, None, message): return True aid = message.from_user.id success = True reason = lang("config_updated") new_config = deepcopy(glovar.configs[gid]) text = f"{lang('admin_group')}{lang('colon')}{code(aid)}\n" # Check command format command_type, command_context = get_command_context(message) if command_type: if command_type == "show": text += f"{lang('action')}{lang('colon')}{code(lang('config_show'))}\n" text += get_config_text(new_config) thread(send_report_message, (30, client, gid, text)) return True now = get_now() if now - new_config["lock"] > 310: if command_type == "default": new_config = deepcopy(glovar.default_config) else: if command_context: if command_type in {"delete", "mention"}: if command_context == "off": new_config[command_type] = False elif command_context == "on": new_config[command_type] = True else: success = False reason = lang("command_para") elif command_type == "limit": limit = get_int(command_context) if 2 <= limit <= 5: new_config["limit"] = limit else: success = False reason = lang("command_para") elif command_type == "report": if not new_config.get("report"): new_config["report"] = {} if command_context == "off": new_config["report"]["auto"] = False new_config["report"]["manual"] = False elif command_context == "auto": new_config["report"]["auto"] = True new_config["report"]["manual"] = False elif command_context == "manual": new_config["report"]["auto"] = False new_config["report"]["manual"] = True elif command_context == "both": new_config["report"]["auto"] = True new_config["report"]["manual"] = True else: success = False reason = lang("command_para") else: success = False reason = lang("command_type") else: success = False reason = lang("command_lack") if success: new_config["default"] = False else: success = False reason = lang("config_locked") else: success = False reason = lang("command_usage") if success and new_config != glovar.configs[gid]: # Save new config glovar.configs[gid] = new_config save("configs") # Send debug message debug_text = get_debug_text(client, message.chat) debug_text += ( f"{lang('admin_group')}{lang('colon')}{code(message.from_user.id)}\n" f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n" f"{lang('more')}{lang('colon')}{code(f'{command_type} {command_context}')}\n" ) thread(send_message, (client, glovar.debug_channel_id, debug_text)) text += ( f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n" f"{lang('status')}{lang('colon')}{code(reason)}\n") thread(send_report_message, ((lambda x: 10 if x else 5)(success), client, gid, text)) return True except Exception as e: logger.warning(f"Config directly error: {e}", exc_info=True) finally: delete_message(client, gid, mid) return False
def admin(client: Client, message: Message) -> bool: # Mention admins if not message or not message.chat: return True # Basic data gid = message.chat.id mid = message.message_id try: # Check permission if is_class_c(None, None, message): return True # Check config if not glovar.configs[gid].get("mention"): return True uid = message.from_user.id # Init user data if not init_user_id(uid): return True # Warned user and the user having report status can't mention admins if (gid in glovar.user_ids[uid]["waiting"] or gid in glovar.user_ids[uid]["ban"] or glovar.user_ids[uid]["warn"].get(gid)): return True # Generate report text text = ( f"{lang('from_user')}{lang('colon')}{mention_id(uid)}\n" f"{lang('mention_admins')}{lang('colon')}{get_admin_text(gid)}\n") reason = get_command_type(message) if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" # Generate report markup button_abuse = button_data("mention", "abuse", uid) button_delete = button_data("mention", "delete", uid) markup = InlineKeyboardMarkup([[ InlineKeyboardButton(text=lang("abuse"), callback_data=button_abuse), InlineKeyboardButton(text=lang("del"), callback_data=button_delete) ]]) # Send the report message if message.reply_to_message: rid = message.reply_to_message.message_id else: rid = None result = send_message(client, gid, text, rid, markup) if not result: return True old_mid, _ = glovar.message_ids.get(gid, (0, 0)) old_mid and thread(delete_message, (client, gid, old_mid)) sent_mid = result.message_id glovar.message_ids[gid] = (sent_mid, get_now()) save("message_ids") return True except Exception as e: logger.warning(f"Admin error: {e}", exc_info=True) finally: delete_message(client, gid, mid) return False
def ban_user(client: Client, message: Message, uid: int, aid: int, result: int = 0, reason: str = None) -> (str, InlineKeyboardMarkup): # Ban a user text = "" markup = None try: # Basic data gid = message.chat.id # Check admin if is_limited_admin(gid, aid): return "", None # Init user data if not init_user_id(uid): return "", None # Check users' locks if gid in glovar.user_ids[uid]["lock"]: return "", None # Proceed glovar.user_ids[uid]["lock"].add(gid) try: if gid in glovar.user_ids[uid]["ban"]: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_ban'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, None if not result: result = forward_evidence(client=client, message=message.reply_to_message, level=lang("action_ban")) if not result: text += ( f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_ban'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) return text, None # Count admin operation glovar.counts[gid][aid] += 1 # Ban the user thread(kick_chat_member, (client, gid, uid)) glovar.user_ids[uid]["ban"].add(gid) glovar.user_ids[uid]["warn"].pop(gid, 0) update_score(client, uid) # Generate report text stored_link = general_link(result.message_id, message_link(result)) text += ( f"{lang('user_banned')}{lang('colon')}{mention_id(uid)}\n" f"{lang('stored_message')}{lang('colon')}{stored_link}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) if reason: text += f"{lang('reason')}{lang('colon')}{code(reason)}\n" # Generate report markup data = button_data("undo", "ban", uid) markup = InlineKeyboardMarkup([[ InlineKeyboardButton(text=lang("unban"), callback_data=data) ]]) # Share ask_for_help(client, "delete", gid, uid) send_debug(client=client, message=message, action=lang("action_ban"), uid=uid, aid=aid, em=result, reason=reason) finally: glovar.user_ids[uid]["lock"].discard(gid) except Exception as e: logger.warning(f"Ban user error: {e}", exc_info=True) return text, markup
def report_answer(client: Client, message: Message, gid: int, aid: int, mid: int, action_type: str, key: str, reason: str = None) -> str: # Answer the user's report try: report_record = glovar.reports.get(key) if not report_record: message_text = get_text(message) uid = get_int(message_text.split("\n")[0].split(lang("colon"))[1]) text = ( f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('expired'))}\n") thread(edit_message_text, (client, gid, mid, text)) delay(15, delete_message, [client, gid, mid]) glovar.user_ids[uid]["waiting"].discard(gid) save("user_ids") return "" if not report_record["time"]: return "" rid = report_record["reporter_id"] uid = report_record["user_id"] r_mid = report_record["message_id"] record_reason = report_record["reason"] if not reason: reason = record_reason if not (init_user_id(rid) and init_user_id(uid)): return "" # Check users' locks if gid in glovar.user_ids[uid]["lock"] or gid in glovar.user_ids[rid][ "lock"]: return lang("answer_proceeded") # Lock the report status glovar.reports[key]["time"] = 0 try: if action_type == "ban": text, markup = ban_user(client, message, uid, aid, 0, reason) thread(delete_message, (client, gid, r_mid)) elif action_type == "warn": text, markup = warn_user(client, message, uid, aid, reason) thread(delete_message, (client, gid, r_mid)) elif action_type == "abuse": if not rid: return "" message.reply_to_message.from_user.id = rid message.reply_to_message.from_user.is_self = lang( "abuse_report") text, markup = warn_user(client, message, rid, aid) text += f"{lang('reason')}{lang('colon')}{code(lang('reason_abuse'))}\n" else: reported_link = general_link( r_mid, f'{get_channel_link(message)}/{r_mid}') if rid: reporter_text = code(rid) else: reporter_text = code(lang("auto_triggered")) text = ( f"{lang('reported_user')}{lang('colon')}{mention_id(uid)}\n" f"{lang('reported_message')}{lang('colon')}{reported_link}\n" f"{lang('reporter')}{lang('colon')}{reporter_text}\n" f"{lang('action')}{lang('colon')}{code(lang('action_cancel'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) markup = None if markup: secs = 180 else: secs = 15 thread(edit_message_text, (client, gid, mid, text, markup)) delay(secs, delete_message, [client, gid, mid]) finally: glovar.user_ids[uid]["lock"].discard(gid) glovar.user_ids[rid]["lock"].discard(gid) glovar.user_ids[uid]["waiting"].discard(gid) glovar.user_ids[rid]["waiting"].discard(gid) save("user_ids") except Exception as e: logger.warning(f"Report answer error: {e}", exc_info=True) return ""
def update_admins(client: Client) -> bool: # Update admin list every day result = False glovar.locks["admin"].acquire() try: # Basic data group_list = list(glovar.admin_ids) # Check groups for gid in group_list: group_name, group_link = get_group_info(client, gid) admin_members = get_admins(client, gid) # Bot is not in the chat, leave automatically without approve if admin_members is False or any( admin.user.is_self for admin in admin_members) is False: leave_group(client, gid) share_data(client=client, receivers=["MANAGE"], action="leave", action_type="info", data={ "group_id": gid, "group_name": group_name, "group_link": group_link }) project_text = general_link(glovar.project_name, glovar.project_link) debug_text = ( f"{lang('project')}{lang('colon')}{project_text}\n" f"{lang('group_name')}{lang('colon')}{general_link(group_name, group_link)}\n" f"{lang('group_id')}{lang('colon')}{code(gid)}\n" f"{lang('status')}{lang('colon')}{code(lang('leave_auto'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('reason_leave'))}\n" ) thread(send_message, (client, glovar.debug_channel_id, debug_text)) continue # Check the admin list if not (admin_members and any([admin.user.is_self for admin in admin_members])): continue # Save the admin list save_admins(gid, admin_members) # Ignore the group if gid in glovar.lack_group_ids: continue # Check the permissions if glovar.user_id not in glovar.admin_ids[gid]: reason = "user" elif any(admin.user.is_self and admin.can_delete_messages and admin.can_restrict_members for admin in admin_members): glovar.lack_group_ids.discard(gid) save("lack_group_ids") continue else: reason = "permissions" glovar.lack_group_ids.add(gid) save("lack_group_ids") # Send the leave request share_data(client=client, receivers=["MANAGE"], action="leave", action_type="request", data={ "group_id": gid, "group_name": group_name, "group_link": group_link, "reason": reason }) reason = lang(f"reason_{reason}") project_link = general_link(glovar.project_name, glovar.project_link) debug_text = ( f"{lang('project')}{lang('colon')}{project_link}\n" f"{lang('group_name')}{lang('colon')}{general_link(group_name, group_link)}\n" f"{lang('group_id')}{lang('colon')}{code(gid)}\n" f"{lang('status')}{lang('colon')}{code(reason)}\n") thread(send_message, (client, glovar.debug_channel_id, debug_text)) result = True except Exception as e: logger.warning(f"Update admin error: {e}", exc_info=True) finally: glovar.locks["admin"].release() return result