async def _get_new_ub_pack( conv: custom.conversation.Conversation, packs: list, is_animated: bool ) -> Tuple[str, str, bool]: ub_packs = [] new_pack = False user = await client.get_me() tag = "@" + user.username if user.username else user.id for pack in packs: if "_kang_pack" in pack: if "_animated" in pack: if is_animated: ub_packs.append(pack) else: if not is_animated: ub_packs.append(pack) pack = sorted(ub_packs)[-1] # Fetch the last pack await conv.send_message(pack) r11 = await conv.get_response() LOGGER.debug("Stickers:" + r11.text) if "120 stickers" in r11.text: l_char = pack[-1:] # Check if the suffix is a digit if l_char.isdigit(): pack = pack[:-1] + str(int(l_char) + 1) # ++ the suffix else: pack = pack + "_2" # Append the suffix new_pack = True if is_animated: packnick = f"{tag}'s animated kang pack {pack[-1:]}" else: packnick = f"{tag}'s kang pack {pack[-1:]}" await client.send_read_acknowledge(conv.chat_id) return pack, packnick, new_pack
async def upload_progress(current, total): """ Logs the upload progress """ # Quite spammy, find a better way to log the progress percentage = round((current / total) * 100, 2) LOGGER.debug( f"Uploaded {current} of {total} bytes. Progress: {percentage}%" )
async def whois(event: NewMessage.Event) -> None: """Get your or a user's/chat's information.""" match = event.matches[0].group(1) entities = [] if match: entities, _ = await client.parse_arguments(match) if "this" in entities: entities.remove("this") entities.append(event.chat_id) elif event.reply_to_msg_id: if not entities: reply = await event.get_reply_message() user = reply.sender_id if reply.fwd_from: if reply.fwd_from.from_id: user = reply.fwd_from.from_id entities.append(user) else: entities.append("self") users = "" chats = "" channels = "" failed = [] for user in entities: try: input_entity = await client.get_input_entity(user) if isinstance(input_entity, types.InputPeerChat): full_chat = await client( functions.messages.GetFullChatRequest(input_entity)) string = await Parser.parse_full_chat(full_chat, event) chats += f"\n{chats}\n" elif isinstance(input_entity, types.InputPeerChannel): full_channel = await client( functions.channels.GetFullChannelRequest(input_entity)) string = await Parser.parse_full_chat(full_channel, event) channels += f"\n{string}\n" else: full_user = await client( functions.users.GetFullUserRequest(input_entity)) string = await Parser.parse_full_user(full_user, event) users += f"\n{string}\n" except Exception as e: LOGGER.debug(e) failed.append(user) if users: await event.answer("**USERS**" + users, reply=True) if chats: await event.answer("**CHATS**" + chats, reply=True) if channels: await event.answer("**CHANNELS**" + channels, reply=True) if failed: failedtext = "**Unable to fetch:**\n" failedtext += ", ".join(f'`{u}`' for u in failed) await event.answer(failedtext) elif not (users or chats or channels): await event.answer("__Something went wrong!__", self_destruct=2)
async def get_peer_id(entity: str or int) -> int: peer = None try: peer = await client.get_peer_id(entity) except Exception as e: LOGGER.debug(e) return peer
async def git_repo(event: NewMessage.Event) -> None: """Get the repo url.""" try: repo = git.Repo('.') remote_url = repo.remote().url.replace(".git", '/') if remote_url[-1] != '/': remote_url = remote_url + '/' repo.__del__() except Exception as e: LOGGER.info("Couldnt fetch the repo link.") LOGGER.debug(e) remote_url = "https://github.com/kandnub/TG-UserBot/" await event.answer(f"[TG-UserBot]({remote_url})")
async def git_repo(event: NewMessage.Event) -> None: """Get the repo url.""" try: repo = git.Repo('.') remote_url = repo.remote().url.replace(".git", '/') if remote_url[-1] != '/': remote_url = remote_url + '/' repo.__del__() except Exception as e: LOGGER.info("Couldnt fetch the repo link.") LOGGER.debug(e) remote_url = "https://github.com/AvinashReddy3108/PaperplaneRemix.git" await event.answer( f"Click [here]({remote_url}) to check out my userbot's source code.")
async def download(update): global is_downloading path = "/tmp/{}".format(os.getpid()) if not os.path.exists(path): os.mkdir(path) args = get_args(update) if len(args) < 1: await update.edit("`Usage: .spotdl <link>`") return link = args[0] if not "track" in link: await update.edit("`Invalid link. Please note that playlist links won't work!`") return if is_downloading: await update.edit("`Already downloading a song, please wait.`") return else: is_downloading = True try: await update.edit("`Downloading song, please wait...`") LOGGER.info("Starting download of " + link + ".") fetch = await create_subprocess_exec( "spotdl", "--ignore-ffmpeg-version", # TODO: Change this - It is required in order to run on Leap 15.2 Arm link, "--output", path, stdout=PIPE, stderr=PIPE, ) stdout, stderr = await fetch.communicate() result = str(stdout.decode().strip()) \ + str(stderr.decode().strip()) directory = os.fsencode(path) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".mp3"): await update.edit("`Sucessfully downloaded " + filename.replace(".mp3", "") + "`") LOGGER.info("Serving " + filename.replace(".mp3", "") + "...") await update.client.send_file(update.chat_id, path + "/" + filename) LOGGER.info("Serving " + filename.replace(".mp3", "") + " - Done.") LOGGER.debug("Deleting old files...") os.remove(path + "/" + filename) LOGGER.debug("Done deleting old files.") except FileNotFoundError: await update.edit("`Spotify-downloader is not installed.`") is_downloading = False
async def translateme(e): global langi translator=Translator() textx=await e.get_reply_message() message = e.text if textx: message = textx text = str(message.message) else: text = str(message[4:]) text = (deEmojify(text)) reply_text=translator.translate(text, dest=langi).text reply_text="`Source: `\n"+text+"`\n\nTranslation: `\n"+reply_text await client.send_message(e.chat_id,reply_text) await e.delete() LOGGER.debug("Translate query "+text+" was executed successfully")
async def whichid(event: NewMessage.Event) -> None: """ Get the ID of a chat/channel or user. `{prefix}id` or **{prefix}id user1 user2** """ match = event.matches[0].group(1) text = "" if not match and not event.reply_to_msg_id: attr = "first_name" if event.is_private else "title" text = f"{getattr(event.chat, attr)}: " text += f"`{get_peer_id(event.chat_id)}`" elif event.reply_to_msg_id: reply = await event.get_reply_message() user = reply.sender_id if reply.fwd_from: if reply.fwd_from.from_id: user = reply.fwd_from.from_id peer = get_peer_id(user) text = f"[{peer}](tg://user?id={peer}): `{peer}`" else: failed = [] strings = [] users, _ = await client.parse_arguments(match) for user in users: try: entity = await client.get_input_entity(user) peer = get_peer_id(entity) strings.append( f"[{user}](tg://user?id={peer}): `{peer}`" ) except Exception as e: failed.append(user) LOGGER.debug(e) if strings: text = ",\n".join(strings) if failed: ftext = "**Users which weren't resolved:**\n" ftext += ", ".join(f'`{f}`' for f in failed) await event.answer(ftext, reply=True) if text: await event.answer(text)
async def _list_packs() -> Tuple[List[str], types.Message]: async with client.conversation(**conversation_args) as conv: first = await conv.send_message("/cancel") r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await conv.send_message("/packstats") r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) if r2.text.startswith("You don't have any sticker packs yet."): return [], first buttons = list(itertools.chain.from_iterable(r2.buttons or [])) await conv.send_message("/cancel") r3 = await conv.get_response() LOGGER.debug("Stickers:" + r3.text) await client.send_read_acknowledge(conv.chat_id) return [button.text for button in buttons] if buttons else [], first
async def _list_packs(): async with client.conversation(**conversation_args) as conv: first = await conv.send_message('/cancel') r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message('/packstats') r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) if r2.text.startswith("You don't have any sticker packs yet."): return [], first await client.send_read_acknowledge(conv.chat_id) buttons = list(chain.from_iterable(r2.buttons)) await conv.send_message('/cancel') r3 = await conv.get_response() LOGGER.debug("Stickers:" + r3.text) await client.send_read_acknowledge(conv.chat_id) return [button.text for button in buttons], first
async def kang(event): """Steal stickers to your Sticker packs""" if event.reply_to_msg_id: sticker_event = await event.get_reply_message() if not await _is_sticker_event(sticker_event): await event.edit("`Invalid message type!`") return else: sticker_event = None async for msg in client.iter_messages(event.chat_id, offset_id=event.message.id, limit=10): if await _is_sticker_event(msg): sticker_event = msg break if not sticker_event: await event.edit( "`Couldn't find any acceptable media in the recent messages.`") return new_pack = False first_msg = None new_first_msg = None pack, emojis, name, is_animated = await _resolve_messages( event, sticker_event) prefix = client.prefix if client.prefix is not None else '.' if pack: if (':' in pack) or ('=' in pack): text = event.matches[0].group(1) pack, packnick, new_emojis = await _resolve_pack_name( text, is_animated) if not pack and not packnick: await event.edit( "`Are you sure you're using the correct syntax?`\n" f"`{prefix}kang <packName>=<packsShortName>`\n" "`You can also choose emojis whilst making a new pack.`") return packs, first_msg = await _list_packs() is_pack = await _verify_cs_name(pack, packs) if is_pack: pack = is_pack new_pack = False else: new_pack = True attribute_emoji = None if sticker_event.sticker: attribute_emoji = ( attribute.alt for attribute in sticker_event.media.document.attributes if isinstance(attribute, DocumentAttributeSticker)) emojis = new_emojis or attribute_emoji or default_emoji else: packs, first_msg = await _list_packs() is_pack = await _verify_cs_name(pack, packs) if "_kang_pack" in pack: new_pack = True elif not is_pack: await event.edit( NO_PACK.format(pack, prefix, pack or "<pack username>", emojis or default_emoji)) await _delete_sticker_messages(first_msg) return else: pack = is_pack else: basic, animated = await _get_default_packs() packs, first_msg = await _list_packs() if is_animated: pack = await _verify_cs_name(animated, packs) if not pack: if "_kang_pack" in animated: await event.edit("`Making a custom TG-UserBot pack!`") user = await client.get_me() tag = '@' + user.username if user.username else user.id new_pack = True pack = animated packnick = f"{tag}'s animated kang pack" else: pack = animated or "a default animated pack" await event.edit(FALSE_DEFAULT.format(pack, prefix)) await _delete_sticker_messages(first_msg) return else: pack = await _verify_cs_name(basic, packs) if not pack: if "_kang_pack" in basic: await event.edit("`Making a custom TG-UserBot pack!`") user = await client.get_me() tag = '@' + user.username if user.username else user.id new_pack = True pack = basic packnick = f"{tag}'s kang pack" else: pack = basic or "a default pack" await event.edit(FALSE_DEFAULT.format(pack, prefix)) await _delete_sticker_messages(first_msg) return await event.edit( "`Turning on the kang machine... Your sticker? My sticker!`") async with client.conversation(**conversation_args) as conv: if new_pack: packtype = "/newanimated" if is_animated else "/newpack" new_first_msg = await conv.send_message(packtype) r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message(packnick) r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) await client.send_read_acknowledge(conv.chat_id) else: await conv.send_message('/addsticker') r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message(pack) r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) await client.send_read_acknowledge(conv.chat_id) if "120 stickers" in r2.text: if "_kang_pack" in pack: await event.edit( "`Current userbot pack is full, making a new one!`") await conv.send_message('/cancel') r11 = await conv.get_response() LOGGER.debug("Stickers:" + r11.text) await client.send_read_acknowledge(conv.chat_id) pack, packnick = await _get_new_ub_pack(packs, is_animated) packtype = "/newanimated" if is_animated else "/newpack" await conv.send_message(packtype) r12 = await conv.get_response() LOGGER.debug("Stickers:" + r12.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message(packnick) r13 = await conv.get_response() LOGGER.debug("Stickers:" + r13.text) await client.send_read_acknowledge(conv.chat_id) new_pack = True else: await event.edit(f"`{pack} has reached it's limit!`") await _delete_sticker_messages(first_msg or new_first_msg) return elif ".TGS" in r2.text and not is_animated: await event.edit( "`You're trying to kang a normal sticker " "to an animated pack. Choose the correct pack!`") await _delete_sticker_messages(first_msg or new_first_msg) return elif ".PSD" in r2.text and is_animated: await event.edit("`You're trying to kang an animated sticker " "to a normal pack. Choose the correct pack!`") await _delete_sticker_messages(first_msg or new_first_msg) return sticker = BytesIO() sticker.name = name await sticker_event.download_media(file=sticker) sticker.seek(0) if sticker_event.sticker: await conv.send_message(file=sticker, force_document=True) else: new_sticker = BytesIO() resized_sticker = await _resize_image(sticker, new_sticker) new_sticker.name = name new_sticker.seek(0) await conv.send_message(file=resized_sticker, force_document=True) new_sticker.close() sticker.close() r3 = await conv.get_response() LOGGER.debug("Stickers:" + r3.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message(emojis) r4 = await conv.get_response() LOGGER.debug("Stickers:" + r4.text) await client.send_read_acknowledge(conv.chat_id) if new_pack: await conv.send_message('/publish') r5 = await conv.get_response() LOGGER.debug("Stickers:" + r5.text) await client.send_read_acknowledge(conv.chat_id) if is_animated: await conv.send_message('<' + packnick + '>') r41 = await conv.get_response() LOGGER.debug("Stickers:" + r41.text) await client.send_read_acknowledge(conv.chat_id) if r41.text == "Invalid pack selected.": await event.edit("`You tried to kang to an invalid pack.`") await conv.send_message('/cancel') await conv.get_response() await client.send_read_acknowledge(conv.chat_id) return await conv.send_message('/skip') r6 = await conv.get_response() LOGGER.debug("Stickers:" + r6.text) await client.send_read_acknowledge(conv.chat_id) await conv.send_message(pack) r7 = await conv.get_response() LOGGER.debug("Stickers:" + r7.text) await client.send_read_acknowledge(conv.chat_id) if "Sorry" in r7.text: await conv.send_message('/cancel') r61 = await conv.get_response() LOGGER.debug("Stickers:" + r61.text) await client.send_read_acknowledge(conv.chat_id) await event.edit( "`Pack's short name is unacceptable or already taken. " "Try thinking of a better short name.`") await _delete_sticker_messages(first_msg or new_first_msg) return else: await conv.send_message('/done') r5 = await conv.get_response() LOGGER.debug("Stickers:" + r5.text) await client.send_read_acknowledge(conv.chat_id) await event.edit("`Successfully added the sticker to` " f"[{pack}](https://t.me/addstickers/{pack})`!`") await _delete_sticker_messages(first_msg or new_first_msg)
async def inc_listener(event: NewMessage.Event) -> None: """Filter incoming messages for blacklisting.""" broadcast = getattr(event.chat, 'broadcast', False) if not redis or event.is_private or broadcast: return if (event.chat_id in whitelistedChats or event.from_id in whitelistedUsers or await is_admin(event.chat_id, event.sender_id)): return elif event.from_id in blacklistedUsers: if event.from_id not in temp_banlist: await ban_user(event, blacklisted_text) return invite = False invite_match = invite_pattern.search(event.text) tgid_check = False localbl = localBlacklists.get(event.chat_id, False) if invite_match: _, invite, _ = resolve_invite_link(invite_match.group('hash')) try: invite = await client.get_peer_id(invite, False) except Exception as e: LOGGER.debug(e) if GlobalBlacklist.txt: for value in GlobalBlacklist.txt: string = await escape_string(value) if re.search(string, event.text, flags=re.I): if await ban_user(event, str_text, 'txt', value, True): return break elif localbl and getattr(localbl, 'txt', False): for value in localBlacklists[event.chat_id].txt: string = await escape_string(value) if re.search(string, event.text, flags=re.I): if await ban_user(event, str_text, 'txt', value): return break if GlobalBlacklist.url: for value in GlobalBlacklist.url: string = re.sub(r'(?<!\\)\*', r'\\w+', value, count=0) if re.search(string, event.text, flags=re.I): if await ban_user(event, url_str, 'url', value, True): return break elif localbl and getattr(localbl, 'url', False): for value in localBlacklists[event.chat_id].url: string = re.sub(r'(?<!\\)\*', r'\\w+', value, count=0) if re.search(string, event.text, flags=re.I): if await ban_user(event, url_str, 'url', value): return break if GlobalBlacklist.tgid or (localbl and hasattr(localbl, 'tgid')): tgid_check = True if tgid_check: globalid = getattr(GlobalBlacklist, 'tgid', []) or [] localid = getattr(localbl, 'tgid', []) or [] if event.sender_id in globalid: if await ban_user(event, id_str, 'tgid', value.sender_id, True): return elif event.sender_id in localid: if await ban_user(event, id_str, 'tgid', value.sender_id): return entities = getattr(event, 'entities', None) or [] for entity in entities: if (isinstance( entity, (types.MessageEntityMention, types.MessageEntityUrl))): entity = id_pattern.search( event.text[entity.offset:entity.offset + entity.length]) entity = entity.group('e') if entity else entity value = await client.get_peer_id(entity) if entity else None elif isinstance(entity, types.MessageEntityMentionName): value = entity.user_id else: value = None if value and invite: if invite == value: if await ban_user(event, id_str, 'tgid', value): return break if value in globalid: if await ban_user(event, id_str, 'tgid', value, True): return break elif localbl and hasattr(localbl, 'tgid'): if value in localBlacklists[event.chat_id].tgid: if await ban_user(event, id_str, 'tgid', value): return break
async def updater(event: NewMessage.Event) -> None: """ Pull newest changes from the official repo and update the script/app. `{prefix}update` or `{prefix}update reset` or `{prefix}update add` Reset will reset the repository and add will commit your changes. """ arg = event.matches[0].group(1) await event.answer("`Checking for updates!`") try: repo = git.Repo(basedir) fetched_items = repo.remotes.origin.fetch() except git.exc.NoSuchPathError as path: await event.answer(f"`Couldn't find {path}!`") repo.__del__() return except git.exc.GitCommandError as command: await event.answer( f"`An error occured trying to get the Git Repo.`\n`{command}`" ) repo.__del__() return except git.exc.InvalidGitRepositoryError: repo = git.Repo.init(basedir) origin = repo.create_remote("origin", main_repo) if not origin.exists(): await event.answer( "`The main repository does not exist. Remote is invalid!`" ) repo.__del__() return fetched_items = origin.fetch() repo.create_head("master", origin.refs.master).set_tracking_branch( origin.refs.master ).checkout(force=True) fetched_commits = repo.iter_commits(f"HEAD..{fetched_items[0].ref.name}") untracked_files = repo.untracked_files old_commit = repo.head.commit for diff_added in old_commit.diff("FETCH_HEAD").iter_change_type("M"): if "requirements.txt" in diff_added.b_path: await event.answer("`Updating the pip requirements!`") updated = await update_requirements() if updated == 0: await event.answer("`Successfully updated the requirements.`") else: if isinstance(updated, int): await event.answer( "`Failed trying to install requirements." " Install them manually and run the command again.`" ) else: await event.answer(f"```{updated}```") return break if arg == "add": repo.index.add(untracked_files, force=True) repo.index.commit("[PaperplaneRemix] Updater: Untracked files") elif arg == "reset": repo.head.reset("--hard") try: config = repo.config_reader() try: LOGGER.debug( f"Found Git user: {config.get_value('user', 'name')} <{config.get_value('user', 'email')}>" ) except (NoSectionError, NoOptionError): LOGGER.warning( "No 'git' credentials found, falling back to generic data for the git pull." ) repo.config_writer().set_value( "user", "name", "PaperplaneRemix Updater" ).release() repo.config_writer().set_value("user", "email", "<>").release() repo.remotes.origin.pull() except git.exc.GitCommandError as command: text = ( "`An error occured trying to Git pull:`\n`{0}`\n\n" "`Use` **{1}update reset** to reset the repo `or` **{1}update add** " "`to add and commit the changes as well.`" ) prefix = client.prefix if client.prefix is not None else "." await event.answer(text.format(command, prefix)) repo.__del__() return new_commit = repo.head.commit if old_commit == new_commit: await event.answer("`Already up-to-date!`") repo.__del__() return remote_url = repo.remote().url.replace(".git", "/") if remote_url[-1] != "/": remote_url = remote_url + "/" now = datetime.datetime.now(datetime.timezone.utc) def_changelog = changelog = "**PaperplaneRemix changelog:**" for commit in reversed(list(fetched_commits)): changelog += summary.format( rev=repo.git.rev_parse(commit.hexsha, short=7), summary=commit.summary, url=remote_url, sha=commit.hexsha, ) ago = (now - commit.committed_datetime).total_seconds() elspased = (await _humanfriendly_seconds(ago)).split(",")[0] committers_link = author_link.format(author=commit.committer, url=remote_url) authors_link = author_link.format(author=commit.author, url=remote_url) if commit.author == commit.committer: committed = commited.format(committer=committers_link, elapsed=elspased) else: committed = authored.format( author=authors_link, committer=committers_link, elapsed=elspased ) changelog += f"{committed:>{len(committed) + 8}}" if changelog == def_changelog: changelog = "`No changelog for you! IDK what happened.`" toast = await event.answer( "`Successfully pulled the new commits. Updating the userbot!`", log=("update", changelog.strip()), ) if not client.logger: await event.answer(changelog.strip(), reply_to=toast.id, link_preview=False) os.environ["userbot_update"] = "True" heroku_api_key = client.config["api_keys"].get("api_key_heroku", False) if os.getenv("DYNO", False) and heroku_api_key: heroku_conn = heroku3.from_key(heroku_api_key) app = None for heroku_app in heroku_conn.apps(): if "api_key_heroku" in heroku_app.config(): app = heroku_app break if app is None: await event.answer( "`I seem to be running the userbot on Heroku " "with an invalid environment. Couldn't update the app.`\n" "`The changes will be reverted upon dyno restart.`" ) repo.__del__() await restart(event) else: for build in app.builds(): if build.status == "pending": await event.answer( "`There seems to be an ongoing build in your app.`" " `Try again after it's finished.`" ) return # Don't update the telethon environment varaibles userbot_config = dict(client.config["userbot"]) app.config().update(userbot_config) # "Dirty Fix" for Heroku Dynos to update proper environment # variables for external plugin flags. heroku_ext_flags = { x[12:]: os.getenv(x, None) for x in list(os.environ) if x.startswith("ext_userbot_") } for flag in userbot_config: if flag in heroku_ext_flags: app.config().update({f"ext_userbot_{flag}": userbot_config[flag]}) app.config().update({flag: None}) app.config().update( { "userbot_restarted": f"{event.chat_id}/{event.message.id}", "userbot_update": "True", } ) if event.client.disabled_commands: disabled_list = ", ".join(client.disabled_commands.keys()) app.config().update({"userbot_disabled_commands": disabled_list}) url = f"https://*****:*****@git.heroku.com/{app.name}.git" if "heroku" in repo.remotes: repo.remotes["heroku"].set_url(url) else: repo.create_remote("heroku", url) if repo.untracked_files: repo.index.add(untracked_files, force=True) repo.index.commit("[PaperplaneRemix] Updater: Untracked files") app.enable_feature("runtime-dyno-metadata") await event.answer( "`Pushing all the changes to Heroku. This might take a while.`" ) remote = repo.remotes["heroku"] try: remote.push(refspec=f"{repo.active_branch.name}:master", force=True) await event.answer("`There was nothing to push to Heroku?`") except git.exc.GitCommandError as command: await event.answer( "`An error occured trying to pull and push to Heorku`" f"\n`{command}`" ) LOGGER.exception(command) repo.__del__() else: repo.__del__() await restart(event)
async def fban(event: NewMessage.Event) -> None: """ Fban a user in all your feds. `{prefix}fban` in reply or **{prefix}fban user1 user2 [kwargs]** **Arguments:** `r` """ match = event.matches[0].group(1) args, kwargs = await client.parse_arguments(match) reason = kwargs.get("r", None) skipped = {} fbanned = [] failed = [] fban_admin_chats_list = client.config["userbot"].get("fban_admin_chats", None) if not fban_admin_chats_list: await event.answer( "`Atleast one fedadmin chat should be set up for this to work!`" ) return fban_admin_chats = set(int(x) for x in fban_admin_chats_list.split(",")) if not args and event.reply_to_msg_id: reply = await event.get_reply_message() args.append(reply.sender_id) if not args: await event.answer("`At least specifiy a user, maybe?`") return entity = await event.get_chat() for chat in fban_admin_chats: if event.reply_to_msg_id: reply = await event.get_reply_message() await reply.forward_to(chat) for user in args: if isinstance(user, list): continue try: async with client.conversation(chat) as conv: spammer = await client.get_entity(user) await conv.send_message( f'/fban [{spammer.id}](tg://user?id={spammer.id}){" " + reason if reason else ""}' ) resp = await conv.get_response() LOGGER.debug(f"FBan: {resp.text}") await client.send_read_acknowledge(conv.chat_id, resp) if resp.sender_id in success_toasts and any( success_toast in resp.message for success_toast in success_toasts[resp.sender_id] ): fbanned.append(user) await asyncio.sleep(0.3) else: failed.append(chat) skipped.update({str(user): failed}) continue except Exception as error: LOGGER.debug(f"FBan failed: {error}") failed.append(chat) skipped.update({str(user): failed}) if fbanned: text = f"`Successfully FBanned:`\n" text += ", ".join((f"`{user}`" for user in fbanned)) if reason: text += f"\n`Reason:` `{reason}`" e2 = await get_chat_link(entity, event.id) log_msg = text + f"\n`Chat:` {e2}" await event.answer(text, log=("fban", log_msg)) if skipped: text = "`Failed FBan requests:`\n" text += "\n".join( ( f"`{user}: [{', '.join(str(x) for x in feds)}]`" for user, feds in skipped.items() ) ) await event.answer(text, reply=True)
async def kang(event: NewMessage.Event) -> None: """ Steal (AKA kang) stickers and images to your Sticker packs. `{prefix}kang [pack] [emojis]` or **{prefix}kang (short)=(title) [emojis]** `pack` and `emojis` can be used as arguments as well. """ match = event.matches[0].group(1) or "" if event.reply_to_msg_id: sticker_event = await event.get_reply_message() if not await _is_sticker_event(sticker_event): await event.answer("`Invalid message type!`") return else: sticker_event = None async for msg in client.iter_messages( event.chat_id, offset_id=event.message.id, limit=10 ): if await _is_sticker_event(msg): sticker_event = msg break if not sticker_event: await event.answer( "`Couldn't find any acceptable media in the recent messages.`" ) return new_pack = False first_msg = None new_first_msg = None args, kwargs = await client.parse_arguments(match) pack, emojis, name, is_animated = await _resolve_messages( args, kwargs, sticker_event ) prefix = client.prefix if client.prefix is not None else "." notif = await client(functions.account.GetNotifySettingsRequest(peer="Stickers")) await _update_stickers_notif(DEFAULT_MUTE) if pack or len(kwargs) == 1: if pack and pack.lower() == "auto": pack, packnick = await _get_userbot_auto_pack(is_animated) if kwargs: pack = None packnick = None for x, y in kwargs.items(): pack = str(x) packnick = str(y) if not (pack and packnick): await event.answer( "`Are you sure you're using the correct syntax?`\n" f"`{prefix}kang <packName>=<packsShortName>`\n" "`You can also choose emojis whilst making a new pack.`" ) await _update_stickers_notif(notif) return packs, first_msg = await _list_packs() is_pack = await _verify_cs_name(pack, packs) if is_pack: pack = is_pack new_pack = False else: new_pack = True attribute_emoji = None if sticker_event.sticker: for attribute in sticker_event.media.document.attributes: if isinstance(attribute, types.DocumentAttributeSticker): attribute_emoji = attribute.alt if attribute_emoji: if emojis and attribute_emoji not in emojis: emojis += attribute_emoji else: emojis = attribute_emoji else: packs, first_msg = await _list_packs() is_pack = await _verify_cs_name(pack, packs) if "_kang_pack" in pack: new_pack = True elif not is_pack: await event.answer( NO_PACK.format( pack, prefix, pack or "<pack username>", emojis or default_emoji ) ) await _delete_sticker_messages(first_msg) await _update_stickers_notif(notif) return else: pack = is_pack else: basic, animated = await _get_default_packs() packs, first_msg = await _list_packs() if is_animated: pack = await _verify_cs_name(animated, packs) if not pack: if "_kang_pack" in animated: await event.answer( "`Making a new animated kang pack, please wait!`" ) pack = animated _, packnick = await _get_userbot_auto_pack(is_animated) new_pack = True else: pack = animated or "a default animated pack" await event.answer(FALSE_DEFAULT.format(pack, prefix)) await _delete_sticker_messages(first_msg) await _update_stickers_notif(notif) return else: pack = await _verify_cs_name(basic, packs) if not pack: if "_kang_pack" in basic: await event.answer("`Making a new kang pack, please wait!`") pack = basic _, packnick = await _get_userbot_auto_pack(is_animated) new_pack = True else: pack = basic or "a default pack" await event.answer(FALSE_DEFAULT.format(pack, prefix)) await _delete_sticker_messages(first_msg) await _update_stickers_notif(notif) return await event.answer(f"`{random.choice(KANGING_STR)}`") async with client.conversation(**conversation_args) as conv: if new_pack: packtype = "/newanimated" if is_animated else "/newpack" new_first_msg = await conv.send_message(packtype) r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await conv.send_message(packnick) r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) else: await conv.send_message("/addsticker") r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await conv.send_message(pack) r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) if "120 stickers" in r2.text: if "_kang_pack" in pack: pack, packnick, new_pack = await _get_new_ub_pack( conv, packs, is_animated ) if new_pack: await event.answer( "`Current kang pack is full, making a new one!`" ) await conv.send_message("/cancel") r12 = await conv.get_response() LOGGER.debug("Stickers:" + r12.text) packtype = "/newanimated" if is_animated else "/newpack" await conv.send_message(packtype) r13 = await conv.get_response() LOGGER.debug("Stickers:" + r13.text) await conv.send_message(packnick) r14 = await conv.get_response() LOGGER.debug("Stickers:" + r14.text) else: await event.answer(f"`{pack} has reached it's limit!`") await _delete_sticker_messages(first_msg or new_first_msg) await _update_stickers_notif(notif) return elif ".TGS" in r2.text and not is_animated: await event.answer( "`I can't kang a normal sticker" " to an animated pack!`" ) await _delete_sticker_messages(first_msg or new_first_msg) await _update_stickers_notif(notif) return elif ".PSD" in r2.text and is_animated: await event.answer( "`I can't kang an animated sticker" "to a normal pack!`" ) await _delete_sticker_messages(first_msg or new_first_msg) await _update_stickers_notif(notif) return sticker = io.BytesIO() sticker.name = name await sticker_event.download_media(file=sticker) if ( sticker_event.sticker and sticker_event.sticker.mime_type == "application/x-tgsticker" ): sticker.seek(0) await conv.send_message(file=sticker, force_document=True) else: new_sticker = io.BytesIO() if sticker_event.sticker: resized_sticker = await _resize_image(sticker, new_sticker, False) else: resized_sticker = await _resize_image(sticker, new_sticker) if isinstance(resized_sticker, str): await event.answer(resized_sticker) await _update_stickers_notif(notif) return await conv.send_message(file=new_sticker, force_document=True) new_sticker.close() sticker.close() r3 = await conv.get_response() LOGGER.debug("Stickers:" + r3.text) await conv.send_message(emojis) r4 = await conv.get_response() LOGGER.debug("Stickers:" + r4.text) if new_pack: await conv.send_message("/publish") r5 = await conv.get_response() LOGGER.debug("Stickers:" + r5.text) if is_animated: await conv.send_message("<" + packnick + ">") r41 = await conv.get_response() LOGGER.debug("Stickers:" + r41.text) if r41.text == "Invalid pack selected.": await event.answer("`Invalid pack selected.`") await conv.send_message("/cancel") await conv.get_response() await client.send_read_acknowledge(conv.chat_id) await _update_stickers_notif(notif) return await conv.send_message("/skip") r6 = await conv.get_response() LOGGER.debug("Stickers:" + r6.text) await conv.send_message(pack) r7 = await conv.get_response() LOGGER.debug("Stickers:" + r7.text) if "Sorry" in r7.text: await conv.send_message("/cancel") r61 = await conv.get_response() LOGGER.debug("Stickers:" + r61.text) await event.answer( "`Pack's short name is unacceptable or already taken. " "Try thinking of a better short name.`" ) await _delete_sticker_messages(first_msg or new_first_msg) await _update_stickers_notif(notif) return else: await conv.send_message("/done") r5 = await conv.get_response() LOGGER.debug("Stickers:" + r5.text) pack = f"[{pack}](https://t.me/addstickers/{pack})" extra = await get_chat_link(event, sticker_event.id) await event.answer( f"`Successfully added the sticker to` {pack} `!`", self_destruct=4, log=("kang", f"Successfully kanged a sticker from {extra} to {pack}"), ) await client.send_read_acknowledge(conv.chat_id) await _delete_sticker_messages(first_msg or new_first_msg) await _update_stickers_notif(notif)
async def delsticker(event: NewMessage.Event) -> None: """ Remove a sticker from your existing pack. `{prefix}delsticker` in reply to your sticker """ if not event.reply_to_msg_id: await event.answer("`Reply to a sticker to delete it.`") return reply = await event.get_reply_message() if not reply.sticker: await event.answer("`Wait a minute, this isn't a sticker!`") return stickerset = None for a in reply.document.attributes: if isinstance(a, types.DocumentAttributeSticker): stickerset = a.stickerset break if not stickerset: await event.answer("`Couldn't find the sticker set.`") return result = await client( functions.messages.GetStickerSetRequest(stickerset=stickerset) ) short_name = result.set.short_name notif = await client(functions.account.GetNotifySettingsRequest(peer="Stickers")) await _update_stickers_notif(DEFAULT_MUTE) await event.answer("`Fetching all your sticker packs.`") packs, first_msg = await _list_packs() target_pack = None for pack in packs: if short_name in pack: target_pack = pack break if not target_pack: await event.answer("`Couldn't find the specified set in your packs.`") await _delete_sticker_messages(first_msg) await _update_stickers_notif(notif) return await event.answer("`Deleting the sticker from your pack.`") async with client.conversation(**conversation_args) as conv: await conv.send_message("/delsticker") await conv.get_response() await conv.send_message(target_pack) r1 = await conv.get_response() LOGGER.debug("Stickers:" + r1.text) await reply.forward_to("@Stickers") r2 = await conv.get_response() LOGGER.debug("Stickers:" + r2.text) status = True if "I have deleted that sticker for you" in r2.text else r2.text await conv.send_message("/cancel") await conv.get_response() if status is True: pack = f"[{short_name}](https://t.me/addstickers/{short_name})" await event.answer( f"`Successfully removed the sticker from` {pack}!", self_destruct=4, log=("delsticker", f"Successfully deleted a sticker from {pack}!"), ) await _delete_sticker_messages(first_msg) else: await event.answer( "**Couldn't delete the sticker. Perhaps it's not in your pack.**" "\n`Check the chat with @Stickers for more information.`" ) await client.send_read_acknowledge("@Stickers") await _update_stickers_notif(notif)
MIGRATEABLE = [] HELPABLE = {} HELPS = [] STATS = [] USER_INFO = [] DATA_IMPORT = [] DATA_EXPORT = [] CHAT_SETTINGS = {} USER_SETTINGS = {} for module_name in ALL_MODULES: imported_module = importlib.import_module("userbot.modules." + module_name) if not hasattr(imported_module, "__mod_name__"): imported_module.__mod_name__ = imported_module.__name__ LOGGER.debug("Loaded Module {}".format(imported_module.__mod_name__)) if not imported_module.__mod_name__.lower() in IMPORTED: IMPORTED[imported_module.__mod_name__.lower()] = imported_module else: raise Exception("Can't have two helper_funcs with the same name! Please change one") # NO_TWO_MODULES if hasattr(imported_module, "__help__") and imported_module.__help__: HELPABLE[imported_module.__mod_name__.lower()] = imported_module HELPS.append(imported_module.__mod_name__.lower()) LOGGER.debug(HELPS) # Chats to migrate on chat_migrated events if hasattr(imported_module, "__migrate__"): MIGRATEABLE.append(imported_module) if hasattr(imported_module, "__stats__"):
async def lang(e): global langi message=await client.get_messages(e.chat_id) langi = str(message[0].message[6:]) LOGGER.debug("trt language changed to **"+langi+"**") LOGGER.debug("tts language changed to **"+langi+"**")