├── userbot ├── manager │ ├── __init__.py │ ├── FontRemix2.ttf │ ├── tools.py │ └── utils.py ├── plugins │ ├── assistant │ │ └── __init__.py │ ├── README.md │ ├── pmto.py │ ├── myusernames.py │ ├── __init__ │ ├── sql_helper │ │ ├── __init__.py │ │ ├── no_log_pms_sql.py │ │ ├── gmute_sql.py │ │ ├── mute_sql.py │ │ ├── pmpermit_sql.py │ │ ├── echo_sql.py │ │ ├── gban_sql_helper.py │ │ ├── globals.py │ │ ├── notes_sql.py │ │ ├── idadder_sql.py │ │ ├── blacklist_assistant.py │ │ ├── botusers_sql.py │ │ ├── snips_sql.py │ │ ├── welcome_sql.py │ │ ├── locks_sql.py │ │ ├── filter_sql.py │ │ ├── antiflood_sql.py │ │ ├── blacklist_sql.py │ │ └── broadcast_sql.py │ ├── wikipedia.py │ ├── cmds.py │ ├── ping.py │ ├── phone.py │ ├── news.py │ ├── music.py │ ├── iplookup.py │ ├── wikimedia.py │ ├── tagall.py │ ├── imgtostkr.py │ ├── images.py │ ├── google.py │ ├── quotly.py │ ├── powertools.py │ ├── emojify.py │ ├── calculator.py │ ├── tagnotify.py │ ├── barcode.py │ ├── groupcall.py │ ├── invite.py │ ├── alive.py │ ├── gbun.py │ ├── create.py │ ├── sticklet.py │ ├── anime.py │ ├── spam.py │ ├── songs.py │ ├── _helper.py │ ├── wordcloud │ ├── remove_bg.py │ ├── mystats.py │ ├── welcome.py │ ├── telegraph.py │ ├── mute.py │ ├── imdb.py │ ├── getqr.py │ ├── echo │ ├── fastdownload.py │ ├── translate.py │ ├── stats.py │ ├── mp3_convertor.py │ ├── zombies.py │ ├── reverseImg.py │ ├── corecmds.py │ ├── ascii.py │ ├── app.py │ ├── clone.py │ └── filters.py ├── __main__.py ├── tweet.py ├── __init__.py └── events.py ├── requirements.txt ├── .gitlab-ci.yml ├── Fonts ├── go3v2.ttf ├── Orlline.otf ├── againts.otf ├── digital.ttf ├── 1942 (1).ttf └── vermin_vibes.ttf ├── resources ├── FontRemix2.ttf └── Tamiluserbot.jpg ├── var.py ├── telesetup.py ├── requirements-startup.txt ├── LICENSE ├── .gitignore ├── heroku_config.py └── sample_config.py /userbot/manager/__init__.py: -------------------------------------------------------------------------------- 1 | from userbot.utils import * 2 | -------------------------------------------------------------------------------- /userbot/plugins/assistant/__init__.py: -------------------------------------------------------------------------------- 1 | # TamilBOT Assistant 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | telethon>=1.24.0 2 | -r requirements-startup.txt 3 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | CheckUserBotWorking: 2 | script: 3 | - echo "Nothing" 4 | -------------------------------------------------------------------------------- /Fonts/go3v2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/go3v2.ttf -------------------------------------------------------------------------------- /Fonts/Orlline.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/Orlline.otf -------------------------------------------------------------------------------- /Fonts/againts.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/againts.otf -------------------------------------------------------------------------------- /Fonts/digital.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/digital.ttf -------------------------------------------------------------------------------- /Fonts/1942 (1).ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/1942 (1).ttf -------------------------------------------------------------------------------- /Fonts/vermin_vibes.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/Fonts/vermin_vibes.ttf -------------------------------------------------------------------------------- /resources/FontRemix2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/resources/FontRemix2.ttf -------------------------------------------------------------------------------- /resources/Tamiluserbot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/resources/Tamiluserbot.jpg -------------------------------------------------------------------------------- /userbot/manager/FontRemix2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TamilBots/TamilUserBot/HEAD/userbot/manager/FontRemix2.ttf -------------------------------------------------------------------------------- /var.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | ENV = bool(os.environ.get("ENV", False)) 4 | if ENV: 5 | from heroku_config import Var as Config 6 | else: 7 | from sample_config import Development as Config 8 | 9 | 10 | Var = Config 11 | -------------------------------------------------------------------------------- /userbot/manager/tools.py: -------------------------------------------------------------------------------- 1 | def media_type(message): 2 | if message and message.photo: 3 | return "Photo" 4 | if message and message.audio: 5 | return "Audio" 6 | if message and message.voice: 7 | return "Voice" 8 | if message and message.video_note: 9 | return "Round Video" 10 | if message and message.gif: 11 | return "Gif" 12 | if message and message.sticker: 13 | return "Sticker" 14 | if message and message.video: 15 | return "Video" 16 | if message and message.document: 17 | return "Document" 18 | return None 19 | -------------------------------------------------------------------------------- /userbot/plugins/README.md: -------------------------------------------------------------------------------- 1 | ## Mandatory Imports 2 | ```python3 3 | None 4 | ``` 5 | There is None Mandatory Imports. Because Var, bot and command are already automatically imported. 6 | 7 | ## Explanation 8 | The Mandatory Imports are now automatically imported. 9 | 10 | ### Formation 11 | Now I will show a short script to show the formation of the desired script. 12 | ```python3 13 | @command(pattern="^.alive", outgoing=True) 14 | async def hello_world(event): 15 | if event.fwd_from: 16 | return 17 | await event.edit("**HELLO WORLD**\n\nThe following is controlling me too!\n" + Var.SUDO_USERS) 18 | ``` 19 | -------------------------------------------------------------------------------- /userbot/plugins/pmto.py: -------------------------------------------------------------------------------- 1 | from userbot.utils import admin_cmd 2 | 3 | 4 | @borg.on(admin_cmd(pattern="pmto ?(.*)")) 5 | async def pmto(event): 6 | a = event.pattern_match.group(1) 7 | b = a.split(" ") 8 | chat_id = b[0] 9 | try: 10 | chat_id = int(chat_id) 11 | except BaseException: 12 | pass 13 | msg = "" 14 | for i in b[1:]: 15 | msg += i + " " 16 | if msg == "": 17 | return 18 | try: 19 | await borg.send_message(chat_id, msg) 20 | await event.edit("Message sent!") 21 | except BaseException: 22 | await event.edit("Something went wrong.") 23 | -------------------------------------------------------------------------------- /userbot/plugins/myusernames.py: -------------------------------------------------------------------------------- 1 | # For @UniBorg 2 | # (c) Shrimadhav U K 3 | 4 | from telethon import events, functions, types 5 | from uniborg.util import admin_cmd 6 | 7 | from telethon.tl.functions.channels import GetAdminedPublicChannelsRequest 8 | 9 | @borg.on(admin_cmd("myusernames")) 10 | async def mine(event): 11 | """ For .reserved command, get a list of your reserved usernames. """ 12 | result = await bot(GetAdminedPublicChannelsRequest()) 13 | output_str = "" 14 | for channel_obj in result.chats: 15 | output_str += f"{channel_obj.title}\n@{channel_obj.username}\n\n" 16 | await event.edit(output_str) 17 | 18 | 19 | -------------------------------------------------------------------------------- /userbot/plugins/__init__: -------------------------------------------------------------------------------- 1 | import math 2 | import os 3 | import re 4 | import time 5 | 6 | import heroku3 7 | import lottie 8 | import requests 9 | 10 | from .. import * 11 | from ..uniborgConfig import Config 12 | 13 | # =================== CONSTANT =================== 14 | 15 | USERID = bot.uid if uniborgConfig.OWNER_ID == 0 else Config.OWNER_ID 16 | ALIVE_NAME = Config.ALIVE_NAME 17 | AUTONAME = Config.AUTONAME 18 | DEFAULT_BIO = Config.DEFAULT_BIO 19 | DEFAULTUSER = str(ALIVE_NAME) if ALIVE_NAME else "TamilUserBot" 20 | BOT_USERNAME = Config.TG_BOT_USERNAME 21 | # mention user 22 | mention = f"[{DEFAULTUSER}](tg://user?id={USERID})" 23 | hmention = f"{DEFAULTUSER}" 24 | -------------------------------------------------------------------------------- /telesetup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # (c) https://t.me/TelethonChat/37677 3 | # This Source Code Form is subject to the terms of the GNU 4 | # General Public License, v.3.0. If a copy of the GPL was not distributed with this 5 | # file, You can obtain one at https://www.gnu.org/licenses/gpl-3.0.en.html. 6 | 7 | from telethon.sync import TelegramClient 8 | from telethon.sessions import StringSession 9 | 10 | print("""Please go-to my.telegram.org 11 | Login using your Telegram account 12 | Click on API Development Tools 13 | Create a new application, by entering the required details""") 14 | APP_ID = int(input("Enter APP ID here: ")) 15 | API_HASH = input("Enter API HASH here: ") 16 | 17 | with TelegramClient(StringSession(), APP_ID, API_HASH) as client: 18 | print(client.session.save()) 19 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | 6 | 7 | # the secret configuration specific things 8 | from var import Var 9 | 10 | 11 | def start() -> scoped_session: 12 | engine = create_engine(Var.DB_URI) 13 | BASE.metadata.bind = engine 14 | BASE.metadata.create_all(engine) 15 | return scoped_session(sessionmaker(bind=engine, autoflush=False)) 16 | 17 | 18 | try: 19 | BASE = declarative_base() 20 | SESSION = start() 21 | except AttributeError as e: 22 | # this is a dirty way for the work-around required for #23 23 | print("DB_URI is not configured. Features depending on the database might have issues.") 24 | print(str(e)) 25 | -------------------------------------------------------------------------------- /userbot/plugins/wikipedia.py: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | """WikiPedia.ORG 5 | Syntax: .wikipedia Query""" 6 | from telethon import events 7 | import wikipedia 8 | from uniborg.util import admin_cmd 9 | 10 | 11 | @borg.on(admin_cmd(pattern="wikipedia (.*)")) 12 | async def _(event): 13 | if event.fwd_from: 14 | return 15 | await event.edit("Processing ...") 16 | input_str = event.pattern_match.group(1) 17 | result = "" 18 | results = wikipedia.search(input_str) 19 | for s in results: 20 | page = wikipedia.page(s) 21 | url = page.url 22 | result += f"> [{s}]({url}) \n" 23 | await event.edit("WikiPedia **Search**: {} \n\n **Result**: \n\n{}".format(input_str, result)) 24 | -------------------------------------------------------------------------------- /userbot/plugins/cmds.py: -------------------------------------------------------------------------------- 1 | from telethon import events 2 | import subprocess 3 | import asyncio 4 | import time 5 | from userbot.utils import admin_cmd 6 | 7 | #@command(pattern="^.cmds", outgoing=True) 8 | @borg.on(admin_cmd(pattern=r"cmds")) 9 | async def install(event): 10 | if event.fwd_from: 11 | return 12 | cmd = "ls userbot/plugins" 13 | process = await asyncio.create_subprocess_shell( 14 | cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE 15 | ) 16 | stdout, stderr = await process.communicate() 17 | o = stdout.decode() 18 | _o = o.split("\n") 19 | o = "\n".join(_o) 20 | OUTPUT = f"**Plugins பட்டியல்:**\n{o}\n\n**TIP:** __நீங்கள் ஒரு கட்டளைகளை அறிய விரும்பினால்plugin, செய்:-__ \n `.help `அடைப்புக்குறிகள் ** < > இல்லாமல்.**\n__All plugins நேரடியாக வேலை செய்யாமல் போகலாம். Visit:__ @TamilSupport __உதவிக்காக.__" 21 | await event.edit(OUTPUT) 22 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/no_log_pms_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, Numeric 2 | 3 | from userbot.plugins.sql_helper import BASE, SESSION 4 | 5 | 6 | class NOLogPMs(BASE): 7 | __tablename__ = "no_log_pms" 8 | chat_id = Column(Numeric, primary_key=True) 9 | 10 | def __init__(self, chat_id, reason=""): 11 | self.chat_id = chat_id 12 | 13 | 14 | NOLogPMs.__table__.create(checkfirst=True) 15 | 16 | 17 | def is_approved(chat_id): 18 | try: 19 | return SESSION.query(NOLogPMs).filter(NOLogPMs.chat_id == chat_id).one() 20 | except BaseException: 21 | return None 22 | finally: 23 | SESSION.close() 24 | 25 | 26 | def approve(chat_id): 27 | adder = NOLogPMs(chat_id) 28 | SESSION.add(adder) 29 | SESSION.commit() 30 | 31 | 32 | def disapprove(chat_id): 33 | rem = SESSION.query(NOLogPMs).get(chat_id) 34 | if rem: 35 | SESSION.delete(rem) 36 | SESSION.commit() 37 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/gmute_sql.py: -------------------------------------------------------------------------------- 1 | try: 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | except ImportError: 4 | raise Exception("Hello!") 5 | 6 | from sqlalchemy import Column, String, UnicodeText 7 | 8 | 9 | class GMute(BASE): 10 | __tablename__ = "gmute" 11 | sender = Column(String(14), primary_key=True) 12 | 13 | def __init__(self, sender): 14 | self.sender = str(sender) 15 | 16 | 17 | GMute.__table__.create(checkfirst=True) 18 | 19 | 20 | def is_gmuted(sender_id): 21 | try: 22 | return SESSION.query(GMute).all() 23 | except: 24 | return None 25 | finally: 26 | SESSION.close() 27 | 28 | 29 | def gmute(sender): 30 | adder = GMute(str(sender)) 31 | SESSION.add(adder) 32 | SESSION.commit() 33 | 34 | 35 | def ungmute(sender): 36 | rem = SESSION.query(GMute).get((str(sender))) 37 | if rem: 38 | SESSION.delete(rem) 39 | SESSION.commit() 40 | -------------------------------------------------------------------------------- /userbot/plugins/ping.py: -------------------------------------------------------------------------------- 1 | # rewritten by @saravanakrish 2 | 3 | from telethon import events 4 | from datetime import datetime 5 | 6 | from userbot import ALIVE_NAME, CMD_HELP 7 | from userbot.utils import admin_cmd 8 | from userbot.manager.utils import edit_or_reply 9 | 10 | DEFAULTUSER = str(ALIVE_NAME) if ALIVE_NAME else "TamilBot🇮🇳" 11 | 12 | 13 | @command(pattern="^.ping") 14 | async def _(event): 15 | if event.fwd_from: 16 | return 17 | IMSID = bot.uid 18 | start = datetime.now() 19 | event = await edit_or_reply(event, "__**🚴🏻‍♂️ Pong!__**") 20 | end = datetime.now() 21 | ms = (end - start).microseconds / 1000 22 | await event.edit( 23 | f"__**🚴🏻‍♂️ ᴘᴏɴɢ!__**\n➥__**ᴘɪɴɢ ꜱᴘᴇᴇᴅ**__ {ms}\n➥ __**ʙᴏᴛ**__ __**ᴏꜰ**__ [{DEFAULTUSER}](tg://user?id={IMSID})" 24 | ) 25 | 26 | CMD_HELP.update( 27 | { 28 | "Ping": 29 | 30 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ :`.ping`\ 31 | \n╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ Check your bot status.\ 32 | """ 33 | } 34 | ) 35 | -------------------------------------------------------------------------------- /requirements-startup.txt: -------------------------------------------------------------------------------- 1 | Pillow>=5.3.0 2 | telethon==1.24.0 3 | PyGithub 4 | aiofiles 5 | aiohttp 6 | aria2p 7 | async_generator 8 | beautifulsoup4 9 | bs4 10 | bwb==3.0.0 11 | cfscrape 12 | coffeehouse 13 | colour 14 | cowpy 15 | cryptg 16 | dnspython 17 | emoji 18 | gTTS-token>=1.1.3 19 | gTTS>=2.0.1 20 | gitpython 21 | geopy 22 | google-api-python-client==1.8.0 23 | google-auth-oauthlib 24 | google_images_download>=2.7.1 25 | googletrans>=2.4.0 26 | gsearch 27 | hachoir 28 | heroku3 29 | httplib2 30 | humanize 31 | lxml 32 | oauth2client 33 | psycopg2 34 | psycopg2-binary 35 | PyLyrics 36 | pySmartDL 37 | pybase64>=0.4.0 38 | pyfiglet 39 | pylast 40 | pymongo 41 | python-barcode 42 | python-dotenv 43 | python-magic 44 | pytube 45 | pytz 46 | qrcode 47 | regex 48 | requests>=2.18.4 49 | scipy 50 | search-engine-parser>=0.4.2 51 | selenium 52 | speedtest-cli>=2.0.2 53 | sqlalchemy==1.3.23 54 | telegraph 55 | urbandict>=0.5 56 | urllib3==1.26.2 57 | wikipedia>=1.4.0 58 | youtube-dl 59 | validators 60 | youtube_search 61 | Pyrogram 62 | instantmusic 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 TamilBots 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/mute_sql.py: -------------------------------------------------------------------------------- 1 | try: 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | except ImportError: 4 | raise Exception("Hello!") 5 | 6 | from sqlalchemy import Column, String, UnicodeText 7 | 8 | 9 | class Mute(BASE): 10 | __tablename__ = "mute" 11 | sender = Column(String(14), primary_key=True) 12 | chat_id = Column(String(14), primary_key=True) 13 | 14 | def __init__(self, sender, chat_id): 15 | self.sender = str(sender) 16 | self.chat_id = str(chat_id) 17 | 18 | 19 | Mute.__table__.create(checkfirst=True) 20 | 21 | 22 | def is_muted(sender, chat_id): 23 | user = SESSION.query(Mute).get((str(sender), str(chat_id))) 24 | if user: 25 | return True 26 | else: 27 | return False 28 | 29 | 30 | def mute(sender, chat_id): 31 | adder = Mute(str(sender), str(chat_id)) 32 | SESSION.add(adder) 33 | SESSION.commit() 34 | 35 | 36 | def unmute(sender, chat_id): 37 | rem = SESSION.query(Mute).get((str(sender), str(chat_id))) 38 | if rem: 39 | SESSION.delete(rem) 40 | SESSION.commit() 41 | 42 | def get_all_muted(): 43 | rem = SESSION.query(Mute).all() 44 | SESSION.close() 45 | return rem 46 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/pmpermit_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, String 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | 4 | 5 | class PMPermit(BASE): 6 | __tablename__ = "pmpermit" 7 | chat_id = Column(String(14), primary_key=True) 8 | reason = Column(String(127)) 9 | 10 | def __init__(self, chat_id, reason=""): 11 | self.chat_id = chat_id 12 | self.reason = reason 13 | 14 | 15 | PMPermit.__table__.create(checkfirst=True) 16 | 17 | 18 | def is_approved(chat_id): 19 | try: 20 | return SESSION.query(PMPermit).filter(PMPermit.chat_id == str(chat_id)).one() 21 | except: 22 | return None 23 | finally: 24 | SESSION.close() 25 | 26 | 27 | def approve(chat_id, reason): 28 | adder = PMPermit(str(chat_id), str(reason)) 29 | SESSION.add(adder) 30 | SESSION.commit() 31 | 32 | 33 | def disapprove(chat_id): 34 | rem = SESSION.query(PMPermit).get(str(chat_id)) 35 | if rem: 36 | SESSION.delete(rem) 37 | SESSION.commit() 38 | 39 | 40 | def get_all_approved(): 41 | rem = SESSION.query(PMPermit).all() 42 | SESSION.close() 43 | return rem 44 | 45 | def disapprove_all(): 46 | SESSION.query(PMPermit).delete() 47 | SESSION.commit() 48 | -------------------------------------------------------------------------------- /userbot/plugins/phone.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import requests 3 | import json 4 | import time 5 | import urllib 6 | import os 7 | 8 | from userbot.utils import admin_cmd 9 | from userbot.manager.utils import edit_or_reply 10 | 11 | 12 | 13 | @borg.on(admin_cmd(pattern="phone (.*)")) 14 | async def phone(event): 15 | if event.fwd_from: 16 | return 17 | information = event.pattern_match.group(1) 18 | number = information 19 | key = "fe65b94e78fc2e3234c1c6ed1b771abd" 20 | api = "http://apilayer.net/api/validate?access_key=" + key + "&number=" + number + "&country_code=&format=1" 21 | output = requests.get(api) 22 | content = output.text 23 | obj = json.loads(content) 24 | country_code = obj['country_code'] 25 | country_name = obj['country_name'] 26 | location = obj['location'] 27 | carrier = obj['carrier'] 28 | line_type = obj['line_type'] 29 | validornot = obj['valid'] 30 | aa = "Valid: "+str(validornot) 31 | a = "Phone number: "+str(number) 32 | b = "Country: " +str(country_code) 33 | c = "Country Name: " +str(country_name) 34 | d = "Location: " +str(location) 35 | e = "Carrier: " +str(carrier) 36 | f = "Device: " +str(line_type) 37 | g = f"{aa}\n{a}\n{b}\n{c}\n{d}\n{e}\n{f}" 38 | await event.reply(g) 39 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/echo_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, String 2 | 3 | from userbot.plugins.sql_helper import BASE, SESSION 4 | 5 | 6 | class ECHOSQL(BASE): 7 | __tablename__ = "echo_sql" 8 | user_id = Column(String(14), primary_key=True) 9 | chat_id = Column(String(14), primary_key=True) 10 | 11 | def __init__(self, user_id, chat_id): 12 | self.user_id = str(user_id) 13 | self.chat_id = str(chat_id) 14 | 15 | 16 | ECHOSQL.__table__.create(checkfirst=True) 17 | 18 | 19 | def is_echo(user_id, chat_id): 20 | try: 21 | return SESSION.query(ECHOSQL).get((str(user_id), str(chat_id))) 22 | except BaseException: 23 | return None 24 | finally: 25 | SESSION.close() 26 | 27 | 28 | def get_all_echos(): 29 | try: 30 | return SESSION.query(ECHOSQL).all() 31 | except BaseException: 32 | return None 33 | finally: 34 | SESSION.close() 35 | 36 | 37 | def addecho(user_id, chat_id): 38 | adder = ECHOSQL(str(user_id), str(chat_id)) 39 | SESSION.add(adder) 40 | SESSION.commit() 41 | 42 | 43 | def remove_echo(user_id, chat_id): 44 | note = SESSION.query(ECHOSQL).get((str(user_id), str(chat_id))) 45 | if note: 46 | SESSION.delete(note) 47 | SESSION.commit() 48 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/gban_sql_helper.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, String 2 | 3 | from userbot.plugins.sql_helper import BASE, SESSION 4 | 5 | 6 | class GBan(BASE): 7 | __tablename__ = "gban" 8 | chat_id = Column(String(14), primary_key=True) 9 | reason = Column(String(127)) 10 | 11 | def __init__(self, chat_id, reason=""): 12 | self.chat_id = chat_id 13 | self.reason = reason 14 | 15 | 16 | GBan.__table__.create(checkfirst=True) 17 | 18 | 19 | def is_gbanned(chat_id): 20 | try: 21 | return SESSION.query(GBan).filter(GBan.chat_id == str(chat_id)).one() 22 | except BaseException: 23 | return None 24 | finally: 25 | SESSION.close() 26 | 27 | 28 | def get_gbanuser(chat_id): 29 | try: 30 | return SESSION.query(GBan).get(str(chat_id)) 31 | finally: 32 | SESSION.close() 33 | 34 | 35 | def catgban(chat_id, reason): 36 | adder = GBan(str(chat_id), str(reason)) 37 | SESSION.add(adder) 38 | SESSION.commit() 39 | 40 | 41 | def catungban(chat_id): 42 | rem = SESSION.query(GBan).get(str(chat_id)) 43 | if rem: 44 | SESSION.delete(rem) 45 | SESSION.commit() 46 | 47 | 48 | def get_all_gbanned(): 49 | rem = SESSION.query(GBan).all() 50 | SESSION.close() 51 | return rem 52 | -------------------------------------------------------------------------------- /userbot/plugins/news.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | from userbot.utils import admin_cmd 4 | from userbot.manager.utils import edit_or_reply 5 | 6 | 7 | newslog = Config.NEWS_CHANNEL_ID 8 | 9 | 10 | @borg.on(admin_cmd("news (.*)")) 11 | async def _(event): 12 | if event.fwd_from: 13 | return 14 | if Config.NEWS_CHANNEL_ID is None: 15 | await edit_or_reply( 16 | event, "`Please ADD NEWS_CHANNEL_ID For This Module To Work`" 17 | ) 18 | return 19 | infintyvar = event.pattern_match.group(1) 20 | main_url = f"https://inshortsapi.vercel.app/news?category={infintyvar}" 21 | stuber = await edit_or_reply( 22 | event, 23 | f"Ok ! Fectching {infintyvar} From inshortsapi Server And Sending To News Channel", 24 | ) 25 | await stuber.edit("All News Has Been Sucessfully Send To News Channel") 26 | starknews = requests.get(main_url).json() 27 | for item in starknews["data"]: 28 | sedlyf = item["content"] 29 | img = item["imageUrl"] 30 | writter = item["author"] 31 | dateis = item["date"] 32 | readthis = item["readMoreUrl"] 33 | titles = item["title"] 34 | sed1 = img 35 | sedm = f"**Title : {titles}** \n{sedlyf} \nDate : {dateis} \nAuthor : {writter} \nReadMore : {readthis}" 36 | await borg.send_file(newslog, sed1, caption=sedm) 37 | -------------------------------------------------------------------------------- /userbot/plugins/music.py: -------------------------------------------------------------------------------- 1 | from telethon import events 2 | import subprocess 3 | from telethon.errors import MessageEmptyError, MessageTooLongError, MessageNotModifiedError 4 | import io 5 | import asyncio 6 | import time 7 | from userbot.utils import admin_cmd 8 | import glob 9 | import os 10 | try: 11 | import instantmusic , subprocess 12 | except: 13 | os.system("pip install instantmusic") 14 | 15 | 16 | 17 | os.system("rm -rf *.mp3") 18 | 19 | 20 | def bruh(name): 21 | 22 | os.system("instantmusic -q -s "+name) 23 | 24 | @borg.on(admin_cmd(pattern="sng ?(.*)")) 25 | async def _(event): 26 | if event.fwd_from: 27 | return 28 | DELAY_BETWEEN_EDITS = 0.3 29 | PROCESS_RUN_TIME = 100 30 | cmd = event.pattern_match.group(1) 31 | reply_to_id = event.message.id 32 | if event.reply_to_msg_id: 33 | reply_to_id = event.reply_to_msg_id 34 | await event.edit("ok finding the song") 35 | bruh(str(cmd)) 36 | l = glob.glob("*.mp3") 37 | loa = l[0] 38 | await event.edit("sending song") 39 | await borg.send_file( 40 | event.chat_id, 41 | loa, 42 | force_document=True, 43 | allow_cache=False, 44 | caption=cmd, 45 | reply_to=reply_to_id 46 | ) 47 | os.system("rm -rf *.mp3") 48 | subprocess.check_output("rm -rf *.mp3",shell=True) 49 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/globals.py: -------------------------------------------------------------------------------- 1 | try: 2 | from userbot.plugins.sql_helper import BASE, SESSION 3 | except ImportError: 4 | raise AttributeError 5 | from sqlalchemy import Column, String, UnicodeText 6 | 7 | 8 | class Globals(BASE): 9 | __tablename__ = "globals" 10 | variable = Column(String, primary_key=True, nullable=False) 11 | value = Column(UnicodeText, primary_key=True, nullable=False) 12 | 13 | def __init__(self, variable, value): 14 | self.variable = str(variable) 15 | self.value = value 16 | 17 | 18 | Globals.__table__.create(checkfirst=True) 19 | 20 | 21 | def gvarstatus(variable): 22 | try: 23 | return ( 24 | SESSION.query(Globals) 25 | .filter(Globals.variable == str(variable)) 26 | .first() 27 | .value 28 | ) 29 | except BaseException: 30 | return None 31 | finally: 32 | SESSION.close() 33 | 34 | 35 | def addgvar(variable, value): 36 | if SESSION.query(Globals).filter(Globals.variable == str(variable)).one_or_none(): 37 | delgvar(variable) 38 | adder = Globals(str(variable), value) 39 | SESSION.add(adder) 40 | SESSION.commit() 41 | 42 | 43 | def delgvar(variable): 44 | rem = ( 45 | SESSION.query(Globals) 46 | .filter(Globals.variable == str(variable)) 47 | .delete(synchronize_session="fetch") 48 | ) 49 | if rem: 50 | SESSION.commit() 51 | -------------------------------------------------------------------------------- /userbot/plugins/iplookup.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | 4 | from userbot.utils import admin_cmd 5 | from userbot import CMD_HELP 6 | 7 | 8 | @borg.on(admin_cmd(pattern="iplookup (.*)")) 9 | async def _(event): 10 | if event.fwd_from: 11 | return 12 | input_str = event.pattern_match.group(1) 13 | 14 | adress = input_str 15 | 16 | token = "19e7f2b6fe27deb566140aae134dec6b" 17 | 18 | api = "http://api.ipstack.com/" + adress + "?access_key=" + token + "&format=1" 19 | 20 | result = urllib.request.urlopen(api).read() 21 | result = result.decode() 22 | 23 | result = json.loads(result) 24 | a = result["type"] 25 | b = result["country_code"] 26 | c = result["region_name"] 27 | d = result["city"] 28 | e = result["zip"] 29 | f = result["latitude"] 30 | g = result["longitude"] 31 | await event.edit( 32 | f"INFORMATION GATHERED SUCCESSFULLY\n\nIp type :-{a}\nCountry code:- {b}\nState name :-{c}\nCity name :- {d}\nzip :-{e}\nLatitude:- {f}\nLongitude :- {g}\n", 33 | parse_mode="HTML", 34 | ) 35 | 36 | 37 | CMD_HELP.update( 38 | { 39 | "iplookup": "**IP LOOKUP**\ 40 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ :`.iplookup `\ 41 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : Gives details about the ip address." 42 | } 43 | ) 44 | -------------------------------------------------------------------------------- /userbot/plugins/wikimedia.py: -------------------------------------------------------------------------------- 1 | """WikiMedia.ORG 2 | Syntax: .wikimedia Query""" 3 | from telethon import events 4 | import requests 5 | from uniborg.util import admin_cmd 6 | 7 | 8 | @borg.on(admin_cmd(pattern="wikimedia (.*)")) 9 | async def _(event): 10 | if event.fwd_from: 11 | return 12 | input_str = event.pattern_match.group(1) 13 | url = "https://commons.wikimedia.org/w/api.php?action={}&generator={}&prop=imageinfo&gimlimit={}&redirects=1&titles={}&iiprop={}&format={}".format( 14 | "query", 15 | "images", 16 | "5", 17 | input_str, 18 | "timestamp|user|url|mime|thumbmime|mediatype", 19 | "json" 20 | ) 21 | r = requests.get(url).json() 22 | result = "" 23 | results = r["query"]["pages"] 24 | for key in results: 25 | current_value = results[key] 26 | pageid = current_value["pageid"] 27 | title = current_value["title"] 28 | imageinfo = current_value["imageinfo"][0] 29 | timestamp = imageinfo["timestamp"] 30 | user = imageinfo["user"] 31 | descriptionurl = imageinfo["descriptionurl"] 32 | mime = imageinfo["mime"] 33 | mediatype = imageinfo["mediatype"] 34 | result += """\n 35 | pageid: {} 36 | title: {} 37 | timestamp: {} 38 | user: [{}]({}) 39 | mime: {} 40 | mediatype: {} 41 | """.format(pageid, title, timestamp, user, descriptionurl, mime, mediatype) 42 | await event.edit("**Search**: {} \n\n **Results**: {}".format(input_str, result)) 43 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/notes_sql.py: -------------------------------------------------------------------------------- 1 | try: 2 | from userbot.modules.sql_helper import SESSION, BASE 3 | except ImportError: 4 | raise Exception("Hello!") 5 | from sqlalchemy import Column, String, UnicodeText, Boolean, Integer, distinct, func 6 | 7 | 8 | class Notes(BASE): 9 | __tablename__ = "notes" 10 | chat_id = Column(String(14), primary_key=True) 11 | keyword = Column(UnicodeText, primary_key=True, nullable=False) 12 | reply = Column(UnicodeText, nullable=False) 13 | 14 | def __init__(self, chat_id, keyword, reply): 15 | self.chat_id = str(chat_id) # ensure string 16 | self.keyword = keyword 17 | self.reply = reply 18 | 19 | 20 | Notes.__table__.create(checkfirst=True) 21 | 22 | 23 | def get_notes(chat_id): 24 | try: 25 | return SESSION.query(Notes).filter(Notes.chat_id == str(chat_id)).all() 26 | finally: 27 | SESSION.close() 28 | 29 | 30 | def add_note(chat_id, keyword, reply): 31 | adder = SESSION.query(Notes).get((str(chat_id), keyword)) 32 | if adder: 33 | adder.reply = reply 34 | else: 35 | adder = Notes(str(chat_id), keyword, reply) 36 | SESSION.add(adder) 37 | SESSION.commit() 38 | 39 | 40 | def rm_note(chat_id, keyword): 41 | note = SESSION.query(Notes).filter(Notes.chat_id == str(chat_id), Notes.keyword == keyword) 42 | if note: 43 | note.delete() 44 | SESSION.commit() 45 | 46 | def rm_all_notes(chat_id): 47 | notes = SESSION.query(Notes).filter(Notes.chat_id == str(chat_id)) 48 | if notes: 49 | notes.delete() 50 | SESSION.commit() 51 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/idadder_sql.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) Midhun KM 2020-2021 2 | # This program is free software: you can redistribute it and/or modify 3 | # it under the terms of the GNU Affero General Public License as published by 4 | # the Free Software Foundation, either version 3 of the License, or 5 | # 6 | # This program is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | # GNU Affero General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Affero General Public License 12 | # along with this program. If not, see . 13 | 14 | 15 | from sqlalchemy import Column, String 16 | 17 | from . import BASE, SESSION 18 | 19 | 20 | class Moidata(BASE): 21 | __tablename__ = "moidata" 22 | chat_id = Column(String(14), primary_key=True) 23 | 24 | def __init__(self, chat_id): 25 | self.chat_id = chat_id 26 | 27 | 28 | Moidata.__table__.create(checkfirst=True) 29 | 30 | 31 | def add_usersid_in_db(chat_id: int): 32 | id_user = Moidata(str(chat_id)) 33 | SESSION.add(id_user) 34 | SESSION.commit() 35 | 36 | 37 | def get_all_users(): 38 | stark = SESSION.query(Moidata).all() 39 | SESSION.close() 40 | return stark 41 | 42 | 43 | def already_added(chat_id): 44 | try: 45 | return SESSION.query(Moidata).filter(Moidata.chat_id == str(chat_id)).one() 46 | except: 47 | return None 48 | finally: 49 | SESSION.close() 50 | -------------------------------------------------------------------------------- /userbot/plugins/tagall.py: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2 4 | 5 | from telethon.tl.types import ChannelParticipantsAdmins 6 | 7 | from userbot.utils import admin_cmd 8 | from userbot import CMD_HELP 9 | 10 | 11 | @borg.on(admin_cmd(pattern=r"administrator", outgoing=True)) 12 | async def _(event): 13 | if event.fwd_from: 14 | return 15 | mentions = "Administrators in the chat : " 16 | chat = await event.get_input_chat() 17 | async for x in borg.iter_participants(chat, filter=ChannelParticipantsAdmins): 18 | mentions += f" \n [{x.first_name}](tg://user?id={x.id})" 19 | reply_message = None 20 | if event.reply_to_msg_id: 21 | reply_message = await event.get_reply_message() 22 | await reply_message.reply(mentions) 23 | else: 24 | await event.reply(mentions) 25 | await event.delete() 26 | 27 | 28 | 29 | 30 | @borg.on(admin_cmd(pattern=r"tagall", outgoing=True)) 31 | async def _(event): 32 | if event.fwd_from: 33 | return 34 | mentions = "Hey there!" 35 | chat = await event.get_input_chat() 36 | async for x in borg.iter_participants(chat, 100): 37 | mentions += f" \n [{x.first_name}](tg://user?id={x.id})" 38 | await event.reply(mentions) 39 | await event.delete() 40 | 41 | CMD_HELP.update( 42 | { 43 | "Tagall": 44 | "\n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.tagall`\ 45 | \n╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ Tag Top 100 member in a chat .\ 46 | " 47 | } 48 | ) 49 | -------------------------------------------------------------------------------- /userbot/plugins/imgtostkr.py: -------------------------------------------------------------------------------- 1 | """ 2 | QuotLy: Avaible commands: .imagetostkr 3 | """ 4 | from telethon import events 5 | from telethon.errors.rpcerrorlist import YouBlockedUserError 6 | 7 | from userbot.utils import admin_cmd 8 | 9 | 10 | @borg.on(admin_cmd(pattern="imgtostkr ?(.*)")) 11 | async def _(event): 12 | if event.fwd_from: 13 | return 14 | if not event.reply_to_msg_id: 15 | await event.edit("```Reply to any user message.```") 16 | return 17 | reply_message = await event.get_reply_message() 18 | if not reply_message.media: 19 | await event.edit("```Reply to image message```") 20 | return 21 | chat = "@buildstickerbot" 22 | reply_message.sender 23 | if reply_message.sender.bot: 24 | await event.edit("```Reply to actual users message.```") 25 | return 26 | await event.edit("```Making a sticker```") 27 | async with event.client.conversation(chat) as conv: 28 | try: 29 | response = conv.wait_event( 30 | events.NewMessage(incoming=True, from_users=164977173) 31 | ) 32 | await event.client.forward_messages(chat, reply_message) 33 | response = await response 34 | except YouBlockedUserError: 35 | await event.reply("```Please unblock me (@buildstickerbot) u Nigga```") 36 | return 37 | if response.text.startswith("Hi!"): 38 | await event.edit( 39 | "```Can you kindly disable your forward privacy settings for good?```" 40 | ) 41 | else: 42 | await event.delete() 43 | await event.client.send_message(event.chat_id, response.message) 44 | -------------------------------------------------------------------------------- /userbot/plugins/images.py: -------------------------------------------------------------------------------- 1 | # Adapted from OpenUserBot for Uniborg, X-tra-Telegram 2 | 3 | """Download & Upload Images on Telegram\n 4 | Syntax: `.img ` or `.img (replied message)` 5 | \n Upgraded and Google Image Error Fixed by @NeoMatrix90 aka @kirito6969 6 | """ 7 | 8 | from userbot.googol_images import googleimagesdownload 9 | import os 10 | import shutil 11 | from re import findall 12 | from userbot.utils import admin_cmd 13 | 14 | 15 | @borg.on(admin_cmd(pattern="img ?(.*)")) 16 | async def img_sampler(event): 17 | await event.edit("`Processing...`") 18 | reply = await event.get_reply_message() 19 | if event.pattern_match.group(1): 20 | query = event.pattern_match.group(1) 21 | elif reply: 22 | query = reply.message 23 | else: 24 | await event.edit("`um, mind mentioning what I actually need to search for (❁´◡`❁)`") 25 | return 26 | 27 | lim = findall(r"lim=\d+", query) 28 | # lim = event.pattern_match.group(1) 29 | try: 30 | lim = lim[0] 31 | lim = lim.replace("lim=", "") 32 | query = query.replace("lim=" + lim[0], "") 33 | except IndexError: 34 | lim = 5 35 | response = googleimagesdownload() 36 | 37 | # creating list of arguments 38 | arguments = { 39 | "keywords": query, 40 | "limit": lim, 41 | "format": "jpg", 42 | "no_directory": "no_directory" 43 | } 44 | 45 | # passing the arguments to the function 46 | paths = response.download(arguments) 47 | lst = paths[0][query] 48 | await event.client.send_file(await event.client.get_input_entity(event.chat_id), lst) 49 | shutil.rmtree(os.path.dirname(os.path.abspath(lst[0]))) 50 | await event.delete() 51 | -------------------------------------------------------------------------------- /userbot/plugins/google.py: -------------------------------------------------------------------------------- 1 | """ Powered by @Google 2 | Available Commands: 3 | .go 4 | """ 5 | 6 | import asyncio 7 | import os 8 | from re import findall 9 | import requests 10 | from bs4 import BeautifulSoup 11 | from datetime import datetime 12 | from requests import get 13 | from urllib.parse import quote_plus 14 | from urllib.error import HTTPError 15 | from google_images_download import google_images_download 16 | from gsearch.googlesearch import search 17 | from userbot.utils import admin_cmd 18 | from search_engine_parser import GoogleSearch 19 | 20 | 21 | def progress(current, total): 22 | logger.info("Downloaded {} of {}\nCompleted {}".format(current, total, (current / total) * 100)) 23 | 24 | 25 | @borg.on(admin_cmd("go (.*)")) 26 | async def gsearch(q_event): 27 | """ For .google command, do a Google search. """ 28 | match = q_event.pattern_match.group(1) 29 | page = findall(r"page=\d+", match) 30 | try: 31 | page = page[0] 32 | page = page.replace("page=", "") 33 | match = match.replace("page=" + page[0], "") 34 | except IndexError: 35 | page = 1 36 | search_args = (str(match), int(page)) 37 | gsearch = GoogleSearch() 38 | gresults = await gsearch.async_search(*search_args) 39 | msg = "" 40 | for i in range(len(gresults["links"])): 41 | try: 42 | title = gresults["titles"][i] 43 | link = gresults["links"][i] 44 | desc = gresults["descriptions"][i] 45 | msg += f"[{title}]({link})\n`{desc}`\n\n" 46 | except IndexError: 47 | break 48 | await q_event.edit("**Search Query:**\n`" + match + "`\n\n**Results:**\n" + 49 | msg, 50 | link_preview=False) 51 | -------------------------------------------------------------------------------- /userbot/plugins/quotly.py: -------------------------------------------------------------------------------- 1 | #port to userbot by @MoveAngel 2 | 3 | import datetime 4 | from telethon import events 5 | from telethon.errors.rpcerrorlist import YouBlockedUserError 6 | from telethon.tl.functions.account import UpdateNotifySettingsRequest 7 | from userbot import bot, CMD_HELP 8 | from userbot.utils import admin_cmd 9 | 10 | #@register(outgoing=True, pattern="^.q(?: |$)(.*)") 11 | @borg.on(admin_cmd(pattern=r"qbot(?: |$)(.*)")) 12 | async def _(event): 13 | if event.fwd_from: 14 | return 15 | if not event.reply_to_msg_id: 16 | await event.edit("```Reply to any user message.```") 17 | return 18 | reply_message = await event.get_reply_message() 19 | if not reply_message.text: 20 | await event.edit("```Reply to text message```") 21 | return 22 | chat = "@QuotLyBot" 23 | sender = reply_message.sender 24 | if reply_message.sender.bot: 25 | await event.edit("```Reply to actual users message.```") 26 | return 27 | await event.edit("```Making a Quote```") 28 | async with bot.conversation(chat) as conv: 29 | try: 30 | response = conv.wait_event(events.NewMessage(incoming=True,from_users=1031952739)) 31 | await bot.forward_messages(chat, reply_message) 32 | response = await response 33 | except YouBlockedUserError: 34 | await event.reply("```Please unblock @QuotLyBot and try again```") 35 | return 36 | if response.text.startswith("Hi!"): 37 | await event.edit("```Can you kindly disable your forward privacy settings for good?```") 38 | else: 39 | await event.delete() 40 | await bot.forward_messages(event.chat_id, response.message) 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /userbot/plugins/powertools.py: -------------------------------------------------------------------------------- 1 | """Restart or Terminate the bot from any chat 2 | Available Commands: 3 | .restart 4 | .shutdown""" 5 | # This Source Code Form is subject to the terms of the GNU 6 | # General Public License, v.3.0. If a copy of the GPL was not distributed with this 7 | # file, You can obtain one at https://www.gnu.org/licenses/gpl-3.0.en.html 8 | from telethon import events 9 | import asyncio 10 | import os 11 | import sys 12 | from userbot.utils import admin_cmd 13 | from userbot import CMD_HELP 14 | 15 | @borg.on(admin_cmd("restart")) 16 | async def _(event): 17 | if event.fwd_from: 18 | return 19 | # await asyncio.sleep(2) 20 | # await event.edit("Restarting [██░] ...\n`.ping` me or `.helpme` to check if I am online") 21 | # await asyncio.sleep(2) 22 | # await event.edit("Restarting [███]...\n`.ping` me or `.helpme` to check if I am online") 23 | # await asyncio.sleep(2) 24 | await event.edit("Restarted. `.ping` me or `.alive` to check if I am online") 25 | await borg.disconnect() 26 | # https://archive.is/im3rt 27 | os.execl(sys.executable, sys.executable, *sys.argv) 28 | # You probably don't need it but whatever 29 | quit() 30 | 31 | 32 | @borg.on(admin_cmd("shutdown")) 33 | async def _(event): 34 | if event.fwd_from: 35 | return 36 | await event.edit("Turning off ...Manually turn me on later") 37 | await borg.disconnect() 38 | 39 | CMD_HELP.update( 40 | { 41 | "Powertools": 42 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.restart`\ 43 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : __Restarts the bot !!__\ 44 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.shutdown`\ 45 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : __To turn off the dyno of heroku. you cant turn on by bot you need to got to heroku and turn on or use__ @hk_heroku_bot""" 46 | } 47 | ) 48 | -------------------------------------------------------------------------------- /userbot/plugins/emojify.py: -------------------------------------------------------------------------------- 1 | from userbot.utils import admin_cmd 2 | 3 | from userbot.manager.utils import edit_or_reply 4 | from userbot import fonts as emojify 5 | 6 | 7 | 8 | @borg.on(admin_cmd(pattern="emoji(?: |$)(.*)")) 9 | async def _(event): 10 | "To get emoji art text." 11 | args = event.pattern_match.group(1) 12 | get = await event.get_reply_message() 13 | if not args and get: 14 | args = get.text 15 | if not args: 16 | await edit_or_reply( 17 | event, "__What am I Supposed to do with this idiot, Give me a text.__" 18 | ) 19 | return 20 | result = "" 21 | for a in args: 22 | a = a.lower() 23 | if a in emojify.kakashitext: 24 | char = emojify.kakashiemoji[emojify.kakashitext.index(a)] 25 | result += char 26 | else: 27 | result += a 28 | await edit_or_reply(event, result) 29 | 30 | 31 | @borg.on(admin_cmd(pattern="cmoji(?: |$)(.*)")) 32 | async def _(event): 33 | "To get custom emoji art text." 34 | args = event.pattern_match.group(1) 35 | get = await event.get_reply_message() 36 | if not args and get: 37 | args = get.text 38 | if not args: 39 | return await edit_or_reply( 40 | event, "__What am I Supposed to do with this idiot, Give me a text.__" 41 | ) 42 | try: 43 | emoji, arg = args.split(" ", 1) 44 | except Exception: 45 | arg = args 46 | emoji = "😺" 47 | result = "" 48 | for a in arg: 49 | a = a.lower() 50 | if a in emojify.kakashitext: 51 | char = emojify.itachiemoji[emojify.kakashitext.index(a)].format(cj=emoji) 52 | result += char 53 | else: 54 | result += a 55 | await edit_or_reply(event, result) 56 | 57 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/blacklist_assistant.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) Midhun KM 2020-2021 2 | # This program is free software: you can redistribute it and/or modify 3 | # it under the terms of the GNU Affero General Public License as published by 4 | # the Free Software Foundation, either version 3 of the License, or 5 | # 6 | # This program is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | # GNU Affero General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Affero General Public License 12 | # along with this program. If not, see . 13 | 14 | 15 | from sqlalchemy import Column, String 16 | 17 | from . import BASE, SESSION 18 | 19 | 20 | class Blockedid(BASE): 21 | __tablename__ = "blockedid" 22 | chat_id = Column(String(14), primary_key=True) 23 | 24 | def __init__(self, chat_id): 25 | self.chat_id = chat_id 26 | 27 | 28 | Blockedid.__table__.create(checkfirst=True) 29 | 30 | 31 | def add_nibba_in_db(chat_id: int): 32 | id_user = Blockedid(str(chat_id)) 33 | SESSION.add(id_user) 34 | SESSION.commit() 35 | 36 | 37 | def get_all_nibba(): 38 | nibbaid = SESSION.query(Blockedid).all() 39 | SESSION.close() 40 | return nibbaid 41 | 42 | 43 | def is_he_added(chat_id): 44 | try: 45 | return SESSION.query(Blockedid).filter(Blockedid.chat_id == str(chat_id)).one() 46 | except: 47 | return None 48 | finally: 49 | SESSION.close() 50 | 51 | 52 | def removenibba(chat_id): 53 | nibbanoob = SESSION.query(Blockedid).get(str(chat_id)) 54 | if nibbanoob: 55 | SESSION.delete(nibbanoob) 56 | SESSION.commit() 57 | -------------------------------------------------------------------------------- /userbot/plugins/calculator.py: -------------------------------------------------------------------------------- 1 | import io 2 | import sys 3 | import traceback 4 | 5 | from userbot import CMD_HELP 6 | from userbot.utils import admin_cmd 7 | 8 | 9 | @borg.on(admin_cmd(pattern="calc")) 10 | async def _(event): 11 | if event.fwd_from or event.via_bot_id: 12 | return 13 | await event.edit("Lemme calculate🤔 ...") 14 | cmd = event.text.split(" ", maxsplit=1)[1] 15 | event.message.id 16 | if event.reply_to_msg_id: 17 | event.reply_to_msg_id 18 | 19 | san = f"print({cmd})" 20 | old_stderr = sys.stderr 21 | old_stdout = sys.stdout 22 | redirected_output = sys.stdout = io.StringIO() 23 | redirected_error = sys.stderr = io.StringIO() 24 | stdout, stderr, exc = None, None, None 25 | try: 26 | await aexec(san, event) 27 | except Exception: 28 | exc = traceback.format_exc() 29 | stdout = redirected_output.getvalue() 30 | stderr = redirected_error.getvalue() 31 | sys.stdout = old_stdout 32 | sys.stderr = old_stderr 33 | 34 | evaluation = "" 35 | if exc: 36 | evaluation = exc 37 | elif stderr: 38 | evaluation = stderr 39 | elif stdout: 40 | evaluation = stdout 41 | else: 42 | evaluation = "Something went rong" 43 | 44 | final_output = "**EQUATION**: `{}` \n\n **SOLUTION**: \n`{}` \n".format( 45 | cmd, evaluation 46 | ) 47 | await event.edit(final_output) 48 | 49 | 50 | async def aexec(code, event): 51 | exec(f"async def __aexec(event): " + "".join(f"\n {l}" for l in code.split("\n"))) 52 | return await locals()["__aexec"](event) 53 | 54 | 55 | CMD_HELP.update( 56 | { 57 | "calculator": 58 | "╼•∘ 🅲🅼🅽🅳 ∘•╾ : .calc \ 59 | \n\n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : solves the given maths equation by bodmass rule." 60 | 61 | } 62 | ) 63 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/botusers_sql.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # (c) Shrimadhav U K 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Affero General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Affero General Public License for more details. 13 | 14 | # You should have received a copy of the GNU Affero General Public License 15 | # along with this program. If not, see . 16 | 17 | """ users Table """ 18 | 19 | from sqlalchemy import Column, Integer, String 20 | 21 | from . import BASE, SESSION 22 | 23 | 24 | class Users(BASE): 25 | """ Table to store the received messages """ 26 | 27 | __tablename__ = "users" 28 | message_id = Column(Integer, primary_key=True) 29 | chat_id = Column(String(14)) 30 | um_id = Column(Integer) 31 | 32 | def __init__(self, message_id, chat_id, um_id): 33 | self.message_id = message_id 34 | self.chat_id = str(chat_id) # ensure string 35 | self.um_id = um_id 36 | 37 | def __repr__(self): 38 | return "" % self.chat_id 39 | 40 | 41 | Users.__table__.create(checkfirst=True) 42 | 43 | 44 | def add_me_in_db(message_id: int, chat_id: int, um_id: int): 45 | """ add the message to the table """ 46 | __user = Users(message_id, str(chat_id), um_id) 47 | SESSION.add(__user) 48 | SESSION.commit() 49 | 50 | 51 | def his_userid(message_id: int): 52 | """ get the user_id from the message_id """ 53 | try: 54 | s__ = SESSION.query(Users).get(str(message_id)) 55 | return int(s__.chat_id), s__.um_id 56 | finally: 57 | SESSION.close() 58 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/snips_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, UnicodeText, LargeBinary, Numeric 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | 4 | 5 | class Snips(BASE): 6 | __tablename__ = "snips" 7 | snip = Column(UnicodeText, primary_key=True) 8 | reply = Column(UnicodeText) 9 | snip_type = Column(Numeric) 10 | media_id = Column(UnicodeText) 11 | media_access_hash = Column(UnicodeText) 12 | media_file_reference = Column(LargeBinary) 13 | 14 | def __init__( 15 | self, 16 | snip, reply, snip_type, 17 | media_id=None, media_access_hash=None, media_file_reference=None 18 | ): 19 | self.snip = snip 20 | self.reply = reply 21 | self.snip_type = snip_type 22 | self.media_id = media_id 23 | self.media_access_hash = media_access_hash 24 | self.media_file_reference = media_file_reference 25 | 26 | 27 | Snips.__table__.create(checkfirst=True) 28 | 29 | 30 | def get_snips(keyword): 31 | try: 32 | return SESSION.query(Snips).get(keyword) 33 | except: 34 | return None 35 | finally: 36 | SESSION.close() 37 | 38 | 39 | def get_all_snips(): 40 | try: 41 | return SESSION.query(Snips).all() 42 | except: 43 | return None 44 | finally: 45 | SESSION.close() 46 | 47 | 48 | def add_snip(keyword, reply, snip_type, media_id, media_access_hash, media_file_reference): 49 | adder = SESSION.query(Snips).get(keyword) 50 | if adder: 51 | adder.reply = reply 52 | adder.snip_type = snip_type 53 | adder.media_id = media_id 54 | adder.media_access_hash = media_access_hash 55 | adder.media_file_reference = media_file_reference 56 | else: 57 | adder = Snips(keyword, reply, snip_type, media_id, 58 | media_access_hash, media_file_reference) 59 | SESSION.add(adder) 60 | SESSION.commit() 61 | 62 | 63 | def remove_snip(keyword): 64 | note = SESSION.query(Snips).filter(Snips.snip == keyword) 65 | if note: 66 | note.delete() 67 | SESSION.commit() 68 | -------------------------------------------------------------------------------- /userbot/plugins/tagnotify.py: -------------------------------------------------------------------------------- 1 | from telethon import custom, events 2 | from telethon.tl.types import Channel 3 | from telethon.utils import get_display_name 4 | 5 | from userbot.uniborgConfig import Config 6 | 7 | if Config.PRIVATE_GROUP_ID: 8 | NEEDTOLOG = int(Config.PRIVATE_GROUP_ID) 9 | 10 | if Config.PRIVATE_GROUP_ID: 11 | 12 | @borg.on( 13 | events.NewMessage( 14 | incoming=True, 15 | blacklist_chats=Config.UB_BLACK_LIST_CHAT, 16 | func=lambda e: (e.mentioned), 17 | ) 18 | ) 19 | async def all_messages_catcher(event): 20 | # the bot might not have the required access_hash to mention the 21 | # appropriate PM 22 | await event.forward_to(Var.TG_BOT_USERNAME) 23 | 24 | # construct message 25 | # the message format is stolen from @MasterTagAlertBot 26 | ammoca_message = "" 27 | 28 | who_ = await event.client.get_entity(event.sender_id) 29 | if who_.bot or who_.verified or who_.support: 30 | return 31 | 32 | who_m = f"[{get_display_name(who_)}](tg://user?id={who_.id})" 33 | 34 | where_ = await event.client.get_entity(event.chat_id) 35 | 36 | where_m = get_display_name(where_) 37 | button_text = "📨 Go to Message " 38 | 39 | if isinstance(where_, Channel): 40 | message_link = f"https://t.me/c/{where_.id}/{event.id}" 41 | else: 42 | # not an official link, 43 | # only works in DrKLO/Telegram, 44 | # for some reason 45 | message_link = f"tg://openmessage?chat_id={where_.id}&message_id={event.id}" 46 | # Telegram is weird :\ 47 | 48 | ammoca_message += f"{who_m} tagged you in [{where_m}]({message_link})" 49 | if NEEDTOLOG is not None: 50 | await tgbot.send_message( 51 | entity=NEEDTOLOG, 52 | message=ammoca_message, 53 | link_preview=False, 54 | buttons=[[custom.Button.url(button_text, message_link)]], 55 | silent=True, 56 | ) 57 | else: 58 | return 59 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/welcome_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import BigInteger, Boolean, Column, String, UnicodeText 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | 4 | 5 | class Welcome(BASE): 6 | __tablename__ = "welcome" 7 | chat_id = Column(String(14), primary_key=True) 8 | custom_welcome_message = Column(UnicodeText) 9 | media_file_id = Column(UnicodeText) 10 | should_clean_welcome = Column(Boolean, default=False) 11 | previous_welcome = Column(BigInteger) 12 | 13 | def __init__( 14 | self, 15 | chat_id, 16 | custom_welcome_message, 17 | should_clean_welcome, 18 | previous_welcome, 19 | media_file_id=None, 20 | ): 21 | self.chat_id = chat_id 22 | self.custom_welcome_message = custom_welcome_message 23 | self.media_file_id = media_file_id 24 | self.should_clean_welcome = should_clean_welcome 25 | self.previous_welcome = previous_welcome 26 | 27 | 28 | Welcome.__table__.create(checkfirst=True) 29 | 30 | 31 | def get_current_welcome_settings(chat_id): 32 | try: 33 | return SESSION.query(Welcome).filter(Welcome.chat_id == str(chat_id)).one() 34 | except: 35 | return None 36 | finally: 37 | SESSION.close() 38 | 39 | 40 | def add_welcome_setting( 41 | chat_id, 42 | custom_welcome_message, 43 | should_clean_welcome, 44 | previous_welcome, 45 | media_file_id 46 | ): 47 | # adder = SESSION.query(Welcome).get(chat_id) 48 | adder = Welcome( 49 | chat_id, 50 | custom_welcome_message, 51 | should_clean_welcome, 52 | previous_welcome, 53 | media_file_id 54 | ) 55 | SESSION.add(adder) 56 | SESSION.commit() 57 | 58 | 59 | def rm_welcome_setting(chat_id): 60 | rem = SESSION.query(Welcome).get(str(chat_id)) 61 | if rem: 62 | SESSION.delete(rem) 63 | SESSION.commit() 64 | 65 | 66 | def update_previous_welcome(chat_id, previous_welcome): 67 | row = SESSION.query(Welcome).get(chat_id) 68 | row.previous_welcome = previous_welcome 69 | # commit the changes to the DB 70 | SESSION.commit() 71 | -------------------------------------------------------------------------------- /heroku_config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class Var(object): 4 | APP_ID = int(os.environ.get("APP_ID", 6)) 5 | # 6 is a placeholder 6 | API_HASH = os.environ.get("API_HASH", "eb06d4abfb49dc3eeb1aeb98ae0f581e") 7 | STRING_SESSION = os.environ.get("STRING_SESSION", None) 8 | DB_URI = os.environ.get("DATABASE_URL", None) 9 | TEMP_DOWNLOAD_DIRECTORY = os.environ.get("TEMP_DOWNLOAD_DIRECTORY", None) 10 | LOGGER = True 11 | GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", None) 12 | GIT_REPO_NAME = os.environ.get("GIT_REPO_NAME", None) 13 | # Here for later purposes 14 | SUDO_USERS = os.environ.get("SUDO_USERS", "1492186775") 15 | # PLUGIN_CHANNEL = int(os.environ.get("PLUGIN_CHANNEL", None)) 16 | LYDIA_API_KEY = os.environ.get("LYDIA_API_KEY", None) 17 | HEROKU_API_KEY = os.environ.get("HEROKU_API_KEY", None) 18 | HEROKU_APP_NAME = os.environ.get("HEROKU_APP_NAME", None) 19 | TG_BOT_TOKEN = os.environ.get("TG_BOT_TOKEN", None) 20 | TG_BOT_USERNAME = os.environ.get("TG_BOT_USERNAME", None) 21 | DOWNLOAD_PFP_URL_CLOCK = os.environ.get("DOWNLOAD_PFP_URL_CLOCK", None) 22 | REM_BG_API_KEY = os.environ.get("REM_BG_API_KEY", None) 23 | OPEN_WEATHER_MAP_APPID = os.environ.get("OPEN_WEATHER_MAP_APPID", None) 24 | G_DRIVE_CLIENT_ID = os.environ.get("G_DRIVE_CLIENT_ID", None) 25 | G_DRIVE_CLIENT_SECRET = os.environ.get("G_DRIVE_CLIENT_SECRET", None) 26 | GDRIVE_FOLDER_ID = os.environ.get("GDRIVE_FOLDER_ID", "root") 27 | AUTH_TOKEN_DATA = os.environ.get("AUTH_TOKEN_DATA", None) 28 | if AUTH_TOKEN_DATA != None: 29 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY) 30 | t_file = open(TEMP_DOWNLOAD_DIRECTORY+"auth_token.txt","w") 31 | t_file.write(AUTH_TOKEN_DATA) 32 | t_file.close() 33 | PRIVATE_GROUP_ID = os.environ.get("PRIVATE_GROUP_ID", None) 34 | if PRIVATE_GROUP_ID != None: 35 | try: 36 | PRIVATE_GROUP_ID = int(PRIVATE_GROUP_ID) 37 | except ValueError: 38 | raise ValueError("Invalid Private Group ID. Make sure your ID is starts with -100 and make sure that it is only numbers.") 39 | 40 | class Development(Var): 41 | LOGGER = True 42 | # Here for later purposes 43 | -------------------------------------------------------------------------------- /userbot/__main__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from userbot import bot 3 | from sys import argv 4 | import sys 5 | from telethon.errors.rpcerrorlist import PhoneNumberInvalidError 6 | import os 7 | from telethon import TelegramClient 8 | from var import Var 9 | from userbot.uniborgConfig import Var 10 | from userbot.utils import load_module, start_assistant 11 | from userbot import LOAD_PLUG, BOTLOG_CHATID, LOGS 12 | from pathlib import Path 13 | import asyncio 14 | import telethon.utils 15 | 16 | sed = logging.getLogger("TamilUserBot") 17 | 18 | 19 | async def add_bot(bot_token): 20 | await bot.start(bot_token) 21 | bot.me = await bot.get_me() 22 | bot.uid = telethon.utils.get_peer_id(bot.me) 23 | 24 | 25 | 26 | if len(argv) not in (1, 3, 4): 27 | bot.disconnect() 28 | else: 29 | bot.tgbot = None 30 | if Var.TG_BOT_USERNAME is not None: 31 | print("Initiating Inline Bot") 32 | # ForTheGreatrerGood of beautification 33 | bot.tgbot = TelegramClient( 34 | "TG_BOT_TOKEN", 35 | api_id=Var.APP_ID, 36 | api_hash=Var.API_HASH 37 | ).start(bot_token=Var.TG_BOT_TOKEN) 38 | print("Initialisation finished with no errors") 39 | print("Starting Userbot") 40 | bot.loop.run_until_complete(add_bot(Var.TG_BOT_USERNAME)) 41 | print("Startup Completed") 42 | else: 43 | bot.start() 44 | 45 | 46 | import glob 47 | path = 'userbot/plugins/*.py' 48 | files = glob.glob(path) 49 | for name in files: 50 | with open(name) as f: 51 | path1 = Path(f.name) 52 | shortname = path1.stem 53 | load_module(shortname.replace(".py", "")) 54 | 55 | if Var.ENABLE_ASSISTANTBOT == "ENABLE": 56 | path = "userbot/plugins/assistant/*.py" 57 | files = glob.glob(path) 58 | for name in files: 59 | with open(name) as f: 60 | path1 = Path(f.name) 61 | shortname = path1.stem 62 | start_assistant(shortname.replace(".py", "")) 63 | sed.info("ஆம்! உங்கள் பயனர் போட் அதிகாரப்பூர்வமாக செயல்படுகிறது 🥳!") 64 | else: 65 | sed.info("TamilUserBot Been Installed Sucessfully !") 66 | sed.info("You Can Visit TamilBots For Any Support Or Doubts") 67 | 68 | if len(argv) not in (1, 3, 4): 69 | bot.disconnect() 70 | else: 71 | bot.run_until_disconnected() 72 | -------------------------------------------------------------------------------- /userbot/plugins/barcode.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from datetime import datetime 4 | 5 | import barcode 6 | from barcode.writer import ImageWriter 7 | 8 | from userbot.utils import admin_cmd 9 | 10 | 11 | @borg.on(admin_cmd(pattern="barcode ?(.*)")) 12 | async def _(event): 13 | if event.fwd_from: 14 | return 15 | await event.edit("...") 16 | start = datetime.now() 17 | input_str = event.pattern_match.group(1) 18 | message = "SYNTAX: `.barcode `" 19 | reply_msg_id = event.message.id 20 | if input_str: 21 | message = input_str 22 | elif event.reply_to_msg_id: 23 | previous_message = await event.get_reply_message() 24 | reply_msg_id = previous_message.id 25 | if previous_message.media: 26 | downloaded_file_name = await borg.download_media( 27 | previous_message, 28 | Config.TMP_DOWNLOAD_DIRECTORY, 29 | ) 30 | m_list = None 31 | with open(downloaded_file_name, "rb") as fd: 32 | m_list = fd.readlines() 33 | message = "" 34 | for m in m_list: 35 | message += m.decode("UTF-8") + "\r\n" 36 | os.remove(downloaded_file_name) 37 | else: 38 | message = previous_message.message 39 | else: 40 | message = "SYNTAX: `.barcode `" 41 | bar_code_type = "code128" 42 | try: 43 | bar_code_mode_f = barcode.get(bar_code_type, message, writer=ImageWriter()) 44 | filename = bar_code_mode_f.save(bar_code_type) 45 | await borg.send_file( 46 | event.chat_id, 47 | filename, 48 | caption=message, 49 | reply_to=reply_msg_id, 50 | ) 51 | os.remove(filename) 52 | except Exception as e: 53 | await event.edit(str(e)) 54 | return 55 | end = datetime.now() 56 | ms = (end - start).seconds 57 | await event.edit("Created BarCode in {} seconds".format(ms)) 58 | await asyncio.sleep(5) 59 | await event.delete() 60 | 61 | 62 | from userbot import CMD_HELP 63 | CMD_HELP.update( 64 | { 65 | "| | barcode | |": "`.barcode`\ 66 | \n\nBarCode Generator\ 67 | \n\n ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.barcode` `(your text)``\ 68 | \n\n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : To get the barcode of your text." 69 | } 70 | ) 71 | -------------------------------------------------------------------------------- /userbot/plugins/groupcall.py: -------------------------------------------------------------------------------- 1 | # TamilBots 2021-22 2 | 3 | from telethon.tl.functions.channels import GetFullChannelRequest as getchat 4 | from telethon.tl.functions.phone import CreateGroupCallRequest as startvc 5 | from telethon.tl.functions.phone import DiscardGroupCallRequest as stopvc 6 | from telethon.tl.functions.phone import GetGroupCallRequest as getvc 7 | from telethon.tl.functions.phone import InviteToGroupCallRequest as invitetovc 8 | from userbot.events import register 9 | from userbot import bot, get_call 10 | from userbot import CMD_HELP 11 | 12 | 13 | def user_list(l, n): 14 | for i in range(0, len(l), n): 15 | yield l[i : i + n] 16 | 17 | @register(outgoing=True, pattern="^.startvc$") 18 | async def start_voice(event): 19 | chat = await event.get_chat() 20 | admin = chat.admin_rights 21 | creator = chat.creator 22 | photo = None 23 | 24 | if not admin and not creator: 25 | await event.edit("*You Are Not An Admin* 👮🏻‍♂️") 26 | return 27 | try: 28 | await event.client(startvc(event.chat_id)) 29 | await event.edit("`Voice Call Started` 🤗") 30 | except Exception as ex: 31 | await event.edit(f"Error : `{ex}`") 32 | 33 | @register(outgoing=True, pattern="^.stopvc$") 34 | async def stop_voice(event): 35 | chat = await event.get_chat() 36 | admin = chat.admin_rights 37 | creator = chat.creator 38 | photo = None 39 | 40 | if not admin and not creator: 41 | await event.edit("*You Are Not An Admin* 👮") 42 | return 43 | try: 44 | await event.client(stopvc(await get_call(event))) 45 | await event.edit("`The Group Call Was Stopped` 😥") 46 | except Exception as ex: 47 | await event.edit(f"Error : `{ex}`") 48 | 49 | 50 | 51 | @register(outgoing=True, pattern="^.invitevc$") 52 | async def invite_voice(event): 53 | await event.edit("`Users are called by voice call ...` 😉") 54 | users = [] 55 | z = 0 56 | async for x in event.client.iter_participants(event.chat_id): 57 | if not x.bot: 58 | users.append(x.id) 59 | hmm = list(user_list(users, 6)) 60 | for p in hmm: 61 | try: 62 | await event.client(invitetovc(call=await get_call(event), users=p)) 63 | z += 6 64 | except BaseException: 65 | pass 66 | await event.edit(f"`{z} The User Was Called`") 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /userbot/plugins/invite.py: -------------------------------------------------------------------------------- 1 | """ Userbot module for adding users to group """ 2 | 3 | from telethon import functions 4 | from userbot.events import register 5 | from userbot.utils import admin_cmd 6 | 7 | @borg.on(admin_cmd(pattern=r"invite(?: |$)(.*)")) 8 | async def _(event): 9 | if event.fwd_from: 10 | return 11 | to_add_users = event.pattern_match.group(1) 12 | reply = await event.get_reply_message() 13 | if not to_add_users and not reply: 14 | await event.edit("`You\'re missing ppl(\'s) ok?`") 15 | elif reply: 16 | to_add_users = str(reply.from_id) 17 | if to_add_users: 18 | if not event.is_group and not event.is_channel: 19 | return await event.edit("`.add` users to a chat, not to a Private Message") 20 | else: 21 | if not event.is_channel and event.is_group: 22 | # https://lonamiwebs.github.io/Telethon/methods/messages/add_chat_user.html 23 | for user_id in to_add_users.split(" "): 24 | try: 25 | userID = int(user_id) 26 | except: 27 | userID = user_id 28 | try: 29 | await event.client( 30 | functions.messages.AddChatUserRequest( 31 | chat_id=event.chat_id, 32 | user_id=userID, 33 | fwd_limit=1000000)) 34 | except Exception as e: 35 | await event.reply(str(e)) 36 | return 37 | await event.edit("Added Successfully") 38 | else: 39 | # https://lonamiwebs.github.io/Telethon/methods/channels/invite_to_channel.html 40 | for user_id in to_add_users.split(" "): 41 | try: 42 | userID = int(user_id) 43 | except: 44 | userID = user_id 45 | try: 46 | await event.client( 47 | functions.channels.InviteToChannelRequest( 48 | channel=event.chat_id, users=[userID])) 49 | except Exception as e: 50 | await event.reply(str(e)) 51 | return 52 | await event.edit("Added Successfully") 53 | -------------------------------------------------------------------------------- /userbot/plugins/alive.py: -------------------------------------------------------------------------------- 1 | """Check if tamilBot alive. If you change these, you become the gayest gay such that even the gay world will disown you.""" 2 | # CREDITS: @WhySooSerious, @Sur_vivor 3 | 4 | # modified by @saravanakrish 5 | # Re-written by @iMvEtRi 6 | from userbot.utils import admin_cmd 7 | from userbot.uniborgConfig import Config 8 | from userbot import ALIVE_NAME, CMD_HELP 9 | 10 | DEFAULTUSER = str(ALIVE_NAME) if ALIVE_NAME else "TamilUserBot" 11 | 12 | PM_IMG = Config.ALIVE_IMAGE 13 | pm_caption = "🤖 **тαмιℓвσт ιѕ:** `ᴏɴʟɪɴᴇ`\n\n" 14 | pm_caption += "✮ **ѕуѕтємѕ ѕтαтѕ 💻:**\n" 15 | pm_caption += "✮ **тєℓєтнση νєяѕιση :** `1.15.0` \n" 16 | pm_caption += "✮ **ρутнση :** `3.7.4` \n" 17 | pm_caption += "✮ **∂αтαвαѕє ѕтαтυѕ :** `ꜰᴜɴᴄᴛɪᴏɴᴀʟ`\n" 18 | pm_caption += "✮ **¢υяяєηт вяαη¢н** : `ᴍᴀꜱᴛᴇʀ`\n" 19 | pm_caption += f"✮ **νєяѕιση** : `6.5`\n" 20 | pm_caption += f"✮ **му вσѕѕ** : {DEFAULTUSER} \n\n" 21 | # pm_caption += "✮ **Heroku Database** : `AWS -\nWorking Properly`💥\n\n" 22 | # pm_caption += "⫸ **License** : [MIT License](github.com/ivetri/tamilbot/blob/master/LICENSE) ✔\n" 23 | # pm_caption += "⫸ **Copyrights** : © By [TAMIL🤖BOT](https://github.com/IVETRI/TamilBot) 👨🏻‍💻\n\n" 24 | pm_caption += "•☆•»»**[🇮🇳 тαмιℓвσтѕ 🇮🇳]**(https://t.me/TamilBots)««•☆•" 25 | 26 | 27 | @borg.on(admin_cmd(pattern=r"alive")) 28 | async def tamilbot(alive): 29 | await alive.get_chat() 30 | """ For .alive command, check if the bot is running. """ 31 | await borg.send_file(alive.chat_id, PM_IMG, caption=pm_caption) 32 | await alive.delete() 33 | 34 | @borg.on(admin_cmd(pattern=r"sudoalive", allow_sudo=True)) 35 | async def amireallyalive(alive): 36 | """ For .alive command, check if the bot is running. """ 37 | await alive.edit("`என்னைப் பயன்படுத்தியதற்கு நன்றி🤖") 38 | 39 | @borg.on(admin_cmd(outgoing=True, pattern="repo")) 40 | async def repo(event): 41 | if event.fwd_from: 42 | return 43 | tgbotname = Var.TG_BOT_USERNAME 44 | if event.reply_to_msg_id: 45 | await event.get_reply_message() 46 | response = await bot.inline_query(tgbotname, "repo") 47 | await response[0].click(event.chat_id) 48 | await event.delete() 49 | 50 | CMD_HELP.update( 51 | { 52 | "alive": 53 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.alive`\ 54 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ Check your bot is alive or not.\ 55 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.repo`\ 56 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ get repository of TamilBot.\ 57 | """ 58 | 59 | } 60 | ) 61 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/locks_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Boolean, Column, String 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | 4 | 5 | class Locks(BASE): 6 | __tablename__ = "locks" 7 | chat_id = Column(String(14), primary_key=True) 8 | # Booleans are for "is this locked", _NOT_ "is this allowed" 9 | bots = Column(Boolean, default=False) 10 | commands = Column(Boolean, default=False) 11 | email = Column(Boolean, default=False) 12 | forward = Column(Boolean, default=False) 13 | url = Column(Boolean, default=False) 14 | 15 | 16 | def __init__(self, chat_id): 17 | self.chat_id = str(chat_id) # ensure string 18 | self.bots = False 19 | self.commands = False 20 | self.email = False 21 | self.forward = False 22 | self.url = False 23 | 24 | 25 | Locks.__table__.create(checkfirst=True) 26 | 27 | 28 | def init_locks(chat_id, reset=False): 29 | curr_restr = SESSION.query(Locks).get(str(chat_id)) 30 | if reset: 31 | SESSION.delete(curr_restr) 32 | SESSION.flush() 33 | restr = Locks(str(chat_id)) 34 | SESSION.add(restr) 35 | SESSION.commit() 36 | return restr 37 | 38 | 39 | def update_lock(chat_id, lock_type, locked): 40 | curr_perm = SESSION.query(Locks).get(str(chat_id)) 41 | if not curr_perm: 42 | curr_perm = init_locks(chat_id) 43 | if lock_type == "bots": 44 | curr_perm.bots = locked 45 | elif lock_type == "commands": 46 | curr_perm.commands = locked 47 | elif lock_type == "email": 48 | curr_perm.email = locked 49 | elif lock_type == "forward": 50 | curr_perm.forward = locked 51 | elif lock_type == "url": 52 | curr_perm.url = locked 53 | SESSION.add(curr_perm) 54 | SESSION.commit() 55 | 56 | 57 | def is_locked(chat_id, lock_type): 58 | curr_perm = SESSION.query(Locks).get(str(chat_id)) 59 | SESSION.close() 60 | if not curr_perm: 61 | return False 62 | elif lock_type == "bots": 63 | return curr_perm.bots 64 | elif lock_type == "commands": 65 | return curr_perm.commands 66 | elif lock_type == "email": 67 | return curr_perm.email 68 | elif lock_type == "forward": 69 | return curr_perm.forward 70 | elif lock_type == "url": 71 | return curr_perm.url 72 | 73 | 74 | def get_locks(chat_id): 75 | try: 76 | return SESSION.query(Locks).get(str(chat_id)) 77 | finally: 78 | SESSION.close() 79 | -------------------------------------------------------------------------------- /userbot/plugins/gbun.py: -------------------------------------------------------------------------------- 1 | # This is a troll indeed ffs *facepalm* 2 | import asyncio 3 | from telethon import events 4 | from telethon.tl.functions.users import GetFullUserRequest 5 | from telethon.tl.types import ChannelParticipantsAdmins 6 | from userbot.utils import admin_cmd 7 | 8 | 9 | @borg.on(admin_cmd("gbun")) 10 | async def gbun(event): 11 | if event.fwd_from: 12 | return 13 | gbunVar = event.text 14 | gbunVar = gbunVar[6:] 15 | mentions = "`Warning!! User 𝙂𝘽𝘼𝙉𝙉𝙀𝘿 By Admin...\n`" 16 | no_reason = "𝗥𝗲𝗮𝘀𝗼𝗻 : __Not given __" 17 | await event.edit("𝐔𝐬𝐞𝐫 𝐆𝐛𝐚𝐧𝐧𝐢𝐧𝐠 𝐒𝐨𝐨𝐧... ❗️⚜️☠️") 18 | asyncio.sleep(3.5) 19 | chat = await event.get_input_chat() 20 | async for x in borg.iter_participants(chat, filter=ChannelParticipantsAdmins): 21 | mentions += f"" 22 | reply_message = None 23 | if event.reply_to_msg_id: 24 | reply_message = await event.get_reply_message() 25 | replied_user = await event.client(GetFullUserRequest(reply_message.from_id)) 26 | firstname = replied_user.user.first_name 27 | usname = replied_user.user.username 28 | idd = reply_message.from_id 29 | # make meself invulnerable cuz why not xD 30 | if idd == 1492186775 or idd == 1169076058 : 31 | await reply_message.reply("`ஒரு நொடி காத்திரு, இது என் எஜமான்!`\n**என் மாஸ்டர்-யை தடை செய்ய நீங்கள் அச்சுறுத்துகிறீர்கள்!**\n\n__உங்கள் Account ஹேக் செய்யப்பட்டுள்ளது! என் எஜமானருக்கு 69$ செலுத்துங்கள்__ [Vetri](tg://user?id=1492186775) __உங்கள் Account-யை வெளியிட__😏") 32 | else: 33 | jnl=("`Warning!! `" 34 | "[{}](tg://user?id={})" 35 | "` 𝙂𝘽𝘼𝙉𝙉𝙀𝘿 By Admin...\n\n`" 36 | "**Person's Name: ** __{}__\n" 37 | "**ID : ** `{}`\n" 38 | ).format(firstname, idd, firstname, idd) 39 | if usname == None: 40 | jnl += "**Victim username: ** `Doesn't own a username!`\n" 41 | elif usname != "None": 42 | jnl += "**Victim username** : @{}\n".format(usname) 43 | if len(gbunVar) > 0: 44 | gbunm = "`{}`".format(gbunVar) 45 | gbunr = "**Reason: **"+gbunm 46 | jnl += gbunr 47 | else: 48 | jnl += no_reason 49 | await reply_message.reply(jnl) 50 | else: 51 | mention = "`Warning!! User 𝙂𝘽𝘼𝙉𝙉𝙀𝘿 By Admin...\nReason: Not Given `" 52 | await event.reply(mention) 53 | await event.delete() 54 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/filter_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, UnicodeText, LargeBinary, Numeric, String 2 | from userbot.plugins.sql_helper import SESSION, BASE 3 | 4 | 5 | class Filters(BASE): 6 | __tablename__ = "filters" 7 | chat_id = Column(String(14), primary_key=True) 8 | keyword = Column(UnicodeText, primary_key=True) 9 | reply = Column(UnicodeText) 10 | snip_type = Column(Numeric) 11 | media_id = Column(UnicodeText) 12 | media_access_hash = Column(UnicodeText) 13 | media_file_reference = Column(LargeBinary) 14 | 15 | def __init__( 16 | self, 17 | chat_id, 18 | keyword, reply, snip_type, 19 | media_id=None, media_access_hash=None, media_file_reference=None 20 | ): 21 | self.chat_id = chat_id 22 | self.keyword = keyword 23 | self.reply = reply 24 | self.snip_type = snip_type 25 | self.media_id = media_id 26 | self.media_access_hash = media_access_hash 27 | self.media_file_reference = media_file_reference 28 | 29 | 30 | Filters.__table__.create(checkfirst=True) 31 | 32 | 33 | def get_filter(chat_id, keyword): 34 | try: 35 | return SESSION.query(Filters).get((str(chat_id), keyword)) 36 | except: 37 | return None 38 | finally: 39 | SESSION.close() 40 | 41 | 42 | def get_all_filters(chat_id): 43 | try: 44 | return SESSION.query(Filters).filter(Filters.chat_id == str(chat_id)).all() 45 | except: 46 | return None 47 | finally: 48 | SESSION.close() 49 | 50 | 51 | def add_filter(chat_id, keyword, reply, snip_type, media_id, media_access_hash, media_file_reference): 52 | adder = SESSION.query(Filters).get((str(chat_id), keyword)) 53 | if adder: 54 | adder.reply = reply 55 | adder.snip_type = snip_type 56 | adder.media_id = media_id 57 | adder.media_access_hash = media_access_hash 58 | adder.media_file_reference = media_file_reference 59 | else: 60 | adder = Filters(chat_id, keyword, reply, snip_type, media_id, 61 | media_access_hash, media_file_reference) 62 | SESSION.add(adder) 63 | SESSION.commit() 64 | 65 | 66 | def remove_filter(chat_id, keyword): 67 | saved_filter = SESSION.query(Filters).get((str(chat_id), keyword)) 68 | if saved_filter: 69 | SESSION.delete(saved_filter) 70 | SESSION.commit() 71 | 72 | 73 | def remove_all_filters(chat_id): 74 | saved_filter = SESSION.query(Filters).filter(Filters.chat_id == str(chat_id)) 75 | if saved_filter: 76 | saved_filter.delete() 77 | SESSION.commit() 78 | -------------------------------------------------------------------------------- /userbot/plugins/create.py: -------------------------------------------------------------------------------- 1 | from telethon.tl import functions 2 | from userbot.events import register 3 | from userbot import CMD_HELP 4 | 5 | 6 | @register(outgoing=True, pattern="^.create (b|g|c)(?: |$)(.*)") 7 | async def telegraphs(grop): 8 | """ For .create command, Creating New Group & Channel """ 9 | if not grop.text[0].isalpha() and grop.text[0] not in ("/", "#", "@", "!"): 10 | if grop.fwd_from: 11 | return 12 | type_of_group = grop.pattern_match.group(1) 13 | group_name = grop.pattern_match.group(2) 14 | if type_of_group == "b": 15 | try: 16 | result = await grop.client(functions.messages.CreateChatRequest( # pylint:disable=E0602 17 | users=["@TamiliniBot"], 18 | # Not enough users (to create a chat, for example) 19 | # Telegram, no longer allows creating a chat with ourselves 20 | title=group_name 21 | )) 22 | created_chat_id = result.chats[0].id 23 | result = await grop.client(functions.messages.ExportChatInviteRequest( 24 | peer=created_chat_id, 25 | )) 26 | await grop.edit("Your {} Group Created Successfully. Click [{}]({}) to join".format(group_name, group_name, result.link)) 27 | except Exception as e: # pylint:disable=C0103,W0703 28 | await grop.edit(str(e)) 29 | elif type_of_group == "g" or type_of_group == "c": 30 | try: 31 | r = await grop.client(functions.channels.CreateChannelRequest( # pylint:disable=E0602 32 | title=group_name, 33 | about="Welcome to this Channel", 34 | megagroup=False if type_of_group == "c" else True 35 | )) 36 | created_chat_id = r.chats[0].id 37 | result = await grop.client(functions.messages.ExportChatInviteRequest( 38 | peer=created_chat_id, 39 | )) 40 | await grop.edit("Your {} Group/Channel Created Successfully. Click [{}]({}) to join".format(group_name, group_name, result.link)) 41 | except Exception as e: # pylint:disable=C0103,W0703 42 | await grop.edit(str(e)) 43 | 44 | CMD_HELP.update({ 45 | "create": "\ 46 | Create\ 47 | \nUsage: Create Channel, Group & Group With Bot.\ 48 | \n\n`.create g` \ 49 | \nUsage: Create a Private Group.\ 50 | \n\n`.create b` \ 51 | \nUsage: Create a Group with Bot.\ 52 | \n\n`.create c` \ 53 | \nUsage: Create a Channel.\ 54 | "}) 55 | -------------------------------------------------------------------------------- /userbot/plugins/sticklet.py: -------------------------------------------------------------------------------- 1 | # Random RGB Sticklet by @PhycoNinja13b 2 | # modified by @UniBorg 3 | 4 | import io 5 | import os 6 | import random 7 | import textwrap 8 | 9 | from PIL import Image, ImageDraw, ImageFont 10 | from telethon.tl.types import InputMessagesFilterDocument 11 | from uniborg.util import admin_cmd 12 | 13 | 14 | @borg.on(admin_cmd(pattern="srgb (.*)")) 15 | async def sticklet(event): 16 | R = random.randint(0,256) 17 | G = random.randint(0,256) 18 | B = random.randint(0,256) 19 | 20 | # get the input text 21 | # the text on which we would like to do the magic on 22 | sticktext = event.pattern_match.group(1) 23 | 24 | # delete the userbot command, 25 | # i don't know why this is required 26 | await event.delete() 27 | 28 | # https://docs.python.org/3/library/textwrap.html#textwrap.wrap 29 | sticktext = textwrap.wrap(sticktext, width=10) 30 | # converts back the list to a string 31 | sticktext = '\n'.join(sticktext) 32 | 33 | image = Image.new("RGBA", (512, 512), (255, 255, 255, 0)) 34 | draw = ImageDraw.Draw(image) 35 | fontsize = 230 36 | 37 | FONT_FILE = await get_font_file(event.client, "@Gujju_Bot_Fonts") 38 | 39 | font = ImageFont.truetype(FONT_FILE, size=fontsize) 40 | 41 | while draw.multiline_textsize(sticktext, font=font) > (512, 512): 42 | fontsize -= 3 43 | font = ImageFont.truetype(FONT_FILE, size=fontsize) 44 | 45 | width, height = draw.multiline_textsize(sticktext, font=font) 46 | draw.multiline_text(((512-width)/2,(512-height)/2), sticktext, font=font, fill=(R, G, B)) 47 | 48 | image_stream = io.BytesIO() 49 | image_stream.name = "TamilBot.webp" 50 | image.save(image_stream, "WebP") 51 | image_stream.seek(0) 52 | 53 | # finally, reply the sticker 54 | #await event.reply( file=image_stream, reply_to=event.message.reply_to_msg_id) 55 | #replacing upper line with this to get reply tags 56 | 57 | await event.client.send_file(event.chat_id, image_stream, reply_to=event.message.reply_to_msg_id) 58 | # cleanup 59 | try: 60 | os.remove(FONT_FILE) 61 | except: 62 | pass 63 | 64 | 65 | async def get_font_file(client, channel_id): 66 | # first get the font messages 67 | font_file_message_s = await client.get_messages( 68 | entity=channel_id, 69 | filter=InputMessagesFilterDocument, 70 | # this might cause FLOOD WAIT, 71 | # if used too many times 72 | limit=None 73 | ) 74 | # get a random font from the list of fonts 75 | # https://docs.python.org/3/library/random.html#random.choice 76 | font_file_message = random.choice(font_file_message_s) 77 | # download and return the file path 78 | return await client.download_media(font_file_message) 79 | -------------------------------------------------------------------------------- /userbot/plugins/anime.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | 4 | import requests 5 | 6 | from userbot import CMD_HELP 7 | from userbot.utils import admin_cmd 8 | 9 | 10 | async def callAPI(search_str): 11 | query = """ 12 | query ($id: Int,$search: String) { 13 | Media (id: $id, type: ANIME,search: $search) { 14 | id 15 | title { 16 | romaji 17 | english 18 | } 19 | description (asHtml: false) 20 | startDate{ 21 | year 22 | } 23 | episodes 24 | chapters 25 | volumes 26 | season 27 | type 28 | format 29 | status 30 | duration 31 | averageScore 32 | genres 33 | bannerImage 34 | } 35 | } 36 | """ 37 | variables = {"search": search_str} 38 | url = "https://graphql.anilist.co" 39 | response = requests.post(url, json={"query": query, "variables": variables}) 40 | return response.text 41 | 42 | 43 | async def formatJSON(outData): 44 | msg = "" 45 | jsonData = json.loads(outData) 46 | res = list(jsonData.keys()) 47 | if "errors" in res: 48 | msg += f"**Error** : `{jsonData['errors'][0]['message']}`" 49 | return msg 50 | else: 51 | jsonData = jsonData["data"]["Media"] 52 | if "bannerImage" in jsonData.keys(): 53 | msg += f"[〽️]({jsonData['bannerImage']})" 54 | else: 55 | msg += "〽️" 56 | title = jsonData["title"]["romaji"] 57 | link = f"https://anilist.co/anime/{jsonData['id']}" 58 | msg += f"[{title}]({link})" 59 | msg += f"\n\n**Type** : {jsonData['format']}" 60 | msg += f"\n**Genres** : " 61 | for g in jsonData["genres"]: 62 | msg += g + " " 63 | msg += f"\n**Status** : {jsonData['status']}" 64 | msg += f"\n**Episode** : {jsonData['episodes']}" 65 | msg += f"\n**Year** : {jsonData['startDate']['year']}" 66 | msg += f"\n**Score** : {jsonData['averageScore']}" 67 | msg += f"\n**Duration** : {jsonData['duration']} min\n\n" 68 | # https://t.me/catuserbot_support/19496 69 | cat = f"{jsonData['description']}" 70 | msg += " __" + re.sub("
", "\n", cat) + "__" 71 | return msg 72 | 73 | 74 | @borg.on(admin_cmd(pattern="anime ?(.*)")) 75 | async def anilist(event): 76 | if event.fwd_from: 77 | return 78 | input_str = event.pattern_match.group(1) 79 | result = await callAPI(input_str) 80 | msg = await formatJSON(result) 81 | await event.edit(msg, link_preview=True) 82 | 83 | 84 | CMD_HELP.update( 85 | { 86 | "anime": 87 | "╼•∘ 🅲🅼🅽🅳 ∘•╾ :.anime \ 88 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾: Shows you the details of the anime." 89 | } 90 | ) 91 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/antiflood_sql.py: -------------------------------------------------------------------------------- 1 | try: 2 | from userbot.modules.sql_helper import SESSION, BASE 3 | except ImportError: 4 | raise AttributeError 5 | import threading 6 | from sqlalchemy import Integer, Column, String, UnicodeText, func, distinct, Boolean 7 | 8 | DEF_COUNT = 0 9 | DEF_LIMIT = 0 10 | DEF_OBJ = (None, DEF_COUNT, DEF_LIMIT) 11 | 12 | 13 | class FloodControl(BASE): 14 | __tablename__ = "antiflood" 15 | chat_id = Column(String(14), primary_key=True) 16 | user_id = Column(Integer) 17 | count = Column(Integer, default=DEF_COUNT) 18 | limit = Column(Integer, default=DEF_LIMIT) 19 | 20 | def __init__(self, chat_id): 21 | self.chat_id = str(chat_id) # ensure string 22 | 23 | def __repr__(self): 24 | return "" % self.chat_id 25 | 26 | 27 | FloodControl.__table__.create(checkfirst=True) 28 | 29 | INSERTION_LOCK = threading.RLock() 30 | 31 | CHAT_FLOOD = {} 32 | 33 | 34 | def set_flood(chat_id, amount): 35 | with INSERTION_LOCK: 36 | flood = SESSION.query(FloodControl).get(str(chat_id)) 37 | if not flood: 38 | flood = FloodControl(str(chat_id)) 39 | 40 | flood.user_id = None 41 | flood.limit = amount 42 | 43 | CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, amount) 44 | 45 | SESSION.add(flood) 46 | SESSION.commit() 47 | 48 | 49 | def update_flood(chat_id: str, user_id) -> bool: 50 | if str(chat_id) in CHAT_FLOOD: 51 | curr_user_id, count, limit = CHAT_FLOOD.get(str(chat_id), DEF_OBJ) 52 | 53 | if limit == 0: # no antiflood 54 | return False 55 | 56 | if user_id != curr_user_id or user_id is None: # other user 57 | CHAT_FLOOD[str(chat_id)] = (user_id, DEF_COUNT + 1, limit) 58 | return False 59 | 60 | count += 1 61 | if count > limit: # too many msgs, kick 62 | CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, limit) 63 | return True 64 | 65 | # default -> update 66 | CHAT_FLOOD[str(chat_id)] = (user_id, count, limit) 67 | return False 68 | 69 | 70 | def get_flood_limit(chat_id): 71 | return CHAT_FLOOD.get(str(chat_id), DEF_OBJ)[2] 72 | 73 | 74 | def migrate_chat(old_chat_id, new_chat_id): 75 | with INSERTION_LOCK: 76 | flood = SESSION.query(FloodControl).get(str(old_chat_id)) 77 | if flood: 78 | CHAT_FLOOD[str(new_chat_id)] = CHAT_FLOOD.get(str(old_chat_id), DEF_OBJ) 79 | flood.chat_id = str(new_chat_id) 80 | SESSION.commit() 81 | 82 | SESSION.close() 83 | 84 | 85 | def __load_flood_settings(): 86 | global CHAT_FLOOD 87 | try: 88 | all_chats = SESSION.query(FloodControl).all() 89 | CHAT_FLOOD = {chat.chat_id: (None, DEF_COUNT, chat.limit) for chat in all_chats} 90 | finally: 91 | SESSION.close() 92 | return CHAT_FLOOD 93 | -------------------------------------------------------------------------------- /userbot/plugins/spam.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 The Raphielscape Company LLC. 2 | # 3 | # Licensed under the Raphielscape Public License, Version 1.b (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # 6 | 7 | import asyncio 8 | from asyncio import wait 9 | 10 | 11 | from userbot.events import register 12 | 13 | @register(outgoing=True, pattern="^.tspam") 14 | async def tmeme(e): 15 | tspam = str(e.text[7:]) 16 | message = tspam.replace(" ", "") 17 | for letter in message: 18 | await e.respond(letter) 19 | await e.delete() 20 | 21 | @register(outgoing=True, pattern="^.spam") 22 | async def spammer(e): 23 | if not e.text[0].isalpha() and e.text[0] not in ("/", "#", "@", "!"): 24 | message = e.text 25 | counter = int(message[6:8]) 26 | spam_message = str(e.text[8:]) 27 | await asyncio.wait([e.respond(spam_message) for i in range(counter)]) 28 | await e.delete() 29 | if LOGGER: 30 | await e.client.send_message( 31 | LOGGER_GROUP, 32 | "#SPAM \n\n" 33 | "Spam was executed successfully" 34 | ) 35 | 36 | @register(outgoing=True, pattern="^.bspam") 37 | async def bigspam(e): 38 | if not e.text[0].isalpha() and e.text[0] not in ("/", "#", "@", "!"): 39 | message = e.text 40 | counter = int(message[9:13]) 41 | spam_message = str(e.text[13:]) 42 | for i in range(1, counter): 43 | await e.respond(spam_message) 44 | await e.delete() 45 | if LOGGER: 46 | await e.client.send_message( 47 | LOGGER_GROUP, 48 | "#BIGSPAM \n\n" 49 | "Bigspam was executed successfully" 50 | ) 51 | 52 | 53 | @register(outgoing=True, pattern="^.pspam") 54 | async def tiny_pic_spam(e): 55 | if not e.text[0].isalpha() and e.text[0] not in ("/", "#", "@", "!"): 56 | message = e.text 57 | text = message.split() 58 | counter = int(text[1]) 59 | link = str(text[2]) 60 | for i in range(1, counter): 61 | await e.client.send_file(e.chat_id, link) 62 | await e.delete() 63 | if LOGGER: 64 | await e.client.send_message( 65 | LOGGER_GROUP, 66 | "#PICSPAM \n\n" 67 | "PicSpam was executed successfully" 68 | ) 69 | @register(outgoing=True, pattern="^.dspam (.*)") 70 | async def spammer(e): 71 | spamDelay = float(e.pattern_match.group(1).split(' ', 2)[0]) 72 | counter = int(e.pattern_match.group(1).split(' ', 2)[1]) 73 | spam_message = str(e.pattern_match.group(1).split(' ', 2)[2]) 74 | await e.delete() 75 | for i in range(1, counter): 76 | await e.respond(spam_message) 77 | await sleep(spamDelay) 78 | if LOGGER: 79 | await e.client.send_message( 80 | LOGGER_GROUP, "#DelaySPAM\n" 81 | "DelaySpam was executed successfully") 82 | -------------------------------------------------------------------------------- /userbot/plugins/songs.py: -------------------------------------------------------------------------------- 1 | """ Spotify / Deezer downloader plugin by @Sur_vivor | Syntax: .dzd link""" 2 | import asyncio 3 | 4 | from telethon.errors.rpcerrorlist import YouBlockedUserError 5 | 6 | from userbot.utils import admin_cmd 7 | from userbot import CMD_HELP 8 | 9 | @borg.on(admin_cmd(outgoing=True, pattern="dzd(?: |$)(.*)")) 10 | async def DeezLoader(Deezlod): 11 | if Deezlod.fwd_from: 12 | return 13 | d_link = Deezlod.pattern_match.group(1) 14 | if ".com" not in d_link: 15 | await Deezlod.edit("` I need a link to download something pro.`**(._.)**") 16 | else: 17 | await Deezlod.edit("🎶**Initiating Download!**🎶") 18 | chat = "@DeezLoadBot" 19 | async with bot.conversation(chat) as conv: 20 | try: 21 | msg_start = await conv.send_message("/start") 22 | response = await conv.get_response() 23 | r = await conv.get_response() 24 | msg = await conv.send_message(d_link) 25 | details = await conv.get_response() 26 | song = await conv.get_response() 27 | """ - don't spam notif - """ 28 | await bot.send_read_acknowledge(conv.chat_id) 29 | except YouBlockedUserError: 30 | await Deezlod.edit("**Error:** `Unblock` @DeezLoadBot `and retry!`") 31 | return 32 | await bot.send_file(Deezlod.chat_id, song, caption=details.text) 33 | await Deezlod.client.delete_messages( 34 | conv.chat_id, [msg_start.id, response.id, r.id, msg.id, details.id, song.id] 35 | ) 36 | await Deezlod.delete() 37 | 38 | 39 | @borg.on(admin_cmd(outgoing=True, pattern="song(?: |$)(.*)")) 40 | async def WooMai(rose): 41 | if rose.fwd_from: 42 | return 43 | song = rose.pattern_match.group(1) 44 | chat = "@SongProBot" 45 | link = f"/s {song}" 46 | await rose.edit("```Getting Your Music```") 47 | async with bot.conversation(chat) as conv: 48 | await asyncio.sleep(2) 49 | await rose.edit("`Downloading...Please wait`") 50 | try: 51 | msg = await conv.send_message(link) 52 | response = await conv.get_response() 53 | respond = await conv.get_response() 54 | """ - don't spam notif - """ 55 | await bot.send_read_acknowledge(conv.chat_id) 56 | except YouBlockedUserError: 57 | await netase.reply("```Please unblock @SongProBot and try again```") 58 | return 59 | await rose.edit("`Sending Your Music...`") 60 | await asyncio.sleep(3) 61 | await bot.send_file(rose.chat_id, respond) 62 | await rose.client.delete_messages(conv.chat_id, [msg.id, response.id, respond.id]) 63 | await rose.delete() 64 | 65 | CMD_HELP.update( 66 | { 67 | "Songs": 68 | "╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.dzd`" 69 | "\n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : get songs from @DeezLoadBot " 70 | "\n\n ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.song`" 71 | "\n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : get your favourite 😍 song from @SongProBot, " 72 | } 73 | ) 74 | 75 | -------------------------------------------------------------------------------- /userbot/tweet.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from PIL import Image 3 | from validators.url import url 4 | 5 | 6 | async def moditweet(text): 7 | r = requests.get( 8 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=narendramodi" 9 | ).json() 10 | dc = r.get("message") 11 | cobra = url(dc) 12 | if not cobra: 13 | return "check syntax once more" 14 | with open("hehe.png", "wb") as f: 15 | f.write(requests.get(dc).content) 16 | img = Image.open("hehe.png").convert("RGB") 17 | img.save("hehe.webp", "webp") 18 | return "hehe.webp" 19 | 20 | 21 | async def sundartweet(text): 22 | r = requests.get( 23 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=sundarpichai" 24 | ).json() 25 | dc = r.get("message") 26 | cobra = url(dc) 27 | if not cobra: 28 | return "check syntax once more" 29 | with open("hehe.png", "wb") as f: 30 | f.write(requests.get(dc).content) 31 | img = Image.open("hehe.png").convert("RGB") 32 | img.save("hehe.webp", "webp") 33 | return "hehe.webp" 34 | 35 | 36 | async def johnnytweet(text): 37 | r = requests.get( 38 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=johnnysins" 39 | ).json() 40 | dc = r.get("message") 41 | cobra = url(dc) 42 | if not cobra: 43 | return "check syntax once more" 44 | with open("hehe.png", "wb") as f: 45 | f.write(requests.get(dc).content) 46 | img = Image.open("hehe.png").convert("RGB") 47 | img.save("hehe.webp", "webp") 48 | return "hehe.webp" 49 | 50 | 51 | async def bhautweet(text): 52 | r = requests.get( 53 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=hindustanibhau" 54 | ).json() 55 | ab = r.get("message") 56 | cd = url(ab) 57 | if not cd: 58 | return "check syntax once more" 59 | with open("hoho.png", "wb") as f: 60 | f.write(requests.get(ab).content) 61 | img = Image.open("hoho.png").convert("RGB") 62 | img.save("hoho.webp", "webp") 63 | return "hoho.webp" 64 | 65 | 66 | async def jtweet(text): 67 | r = requests.get( 68 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=the_joker" 69 | ).json() 70 | ab = r.get("message") 71 | cd = url(ab) 72 | if not cd: 73 | return "check syntax once more" 74 | with open("hoho.png", "wb") as f: 75 | f.write(requests.get(ab).content) 76 | img = Image.open("hoho.png").convert("RGB") 77 | img.save("hoho.webp", "webp") 78 | return "hoho.webp" 79 | 80 | 81 | async def apjtweet(text): 82 | r = requests.get( 83 | f"https://nekobot.xyz/api/imagegen?type=tweet&text={text}&username=dr.a.p.j.abdulkalam" 84 | ).json() 85 | ab = r.get("message") 86 | cd = url(ab) 87 | if not cd: 88 | return "check syntax once more" 89 | with open("hoho.png", "wb") as f: 90 | f.write(requests.get(ab).content) 91 | img = Image.open("hoho.png").convert("RGB") 92 | img.save("hoho.webp", "webp") 93 | return "hoho.webp" 94 | -------------------------------------------------------------------------------- /userbot/plugins/_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | from userbot import CMD_LIST, ALIVE_NAME, CMD_HELP 3 | from userbot.utils import admin_cmd 4 | from userbot.manager.utils import edit_or_reply 5 | DEFAULTUSER = str(ALIVE_NAME) if ALIVE_NAME else "Tamilbot" 6 | 7 | CUSTM_HLP_EMOJ = os.environ.get("CUSTM_HLP_EMOJ", "✯") 8 | 9 | #@command(pattern="^.help ?(.*)") 10 | @borg.on(admin_cmd(pattern=r"help ?(.*)")) 11 | 12 | async def cmd_list(event): 13 | if not event.text[0].isalpha() and event.text[0] not in ("/", "#", "@", "!"): 14 | tgbotusername = Var.TG_BOT_USERNAME 15 | input_str = event.pattern_match.group(1) 16 | if tgbotusername is None or input_str == "text": 17 | string = "" 18 | for i in CMD_LIST: 19 | string += "✨ " + i + "\n" 20 | for iter_list in CMD_LIST[i]: 21 | string += " `" + str(iter_list) + "`" 22 | string += "\n" 23 | string += "\n" 24 | if len(string) > 4095: 25 | with io.BytesIO(str.encode(string)) as out_file: 26 | out_file.name = "cmd.txt" 27 | await bot.send_file( 28 | event.chat_id, 29 | out_file, 30 | force_document=True, 31 | allow_cache=False, 32 | caption="**COMMANDS**", 33 | reply_to=reply_to_id 34 | ) 35 | await event.delete() 36 | else: 37 | await event.edit(string) 38 | elif input_str: 39 | if input_str in CMD_LIST: 40 | string = "Commands found in {}:".format(input_str) 41 | for i in CMD_LIST[input_str]: 42 | string += " " + i 43 | string += "\n" 44 | await event.edit(string) 45 | else: 46 | await event.edit(input_str + " is not a valid plugin!") 47 | else: 48 | help_string = f"""ʙᴏᴛ ᴏꜰ {DEFAULTUSER}\n\n ⚙️•ᴛᴀᴍɪʟʙᴏᴛ ᴍᴇɴᴜ•⚙️\n\n""" 49 | results = await bot.inline_query( # pylint:disable=E0602 50 | tgbotusername, 51 | help_string 52 | ) 53 | await results[0].click( 54 | event.chat_id, 55 | reply_to=event.reply_to_msg_id, 56 | hide_via=True 57 | ) 58 | await event.delete() 59 | 60 | @borg.on(admin_cmd(outgoing=True, pattern="info ?(.*)")) 61 | async def info(event): 62 | """ For .info command,""" 63 | args = event.pattern_match.group(1).lower() 64 | if args: 65 | if args in CMD_HELP: 66 | await edit_or_reply(event, str(CMD_HELP[args])) 67 | else: 68 | await edit_or_reply(event, "Please specify a valid plugin name.") 69 | else: 70 | string = "**Please specify which plugin do you want help for !!**\ 71 | \n**Usage:** `.info` \n\n" 72 | for i in sorted(CMD_HELP): 73 | string += "🔹`" + str(i) 74 | string += "` " 75 | await edit_or_reply(event, string) 76 | -------------------------------------------------------------------------------- /userbot/plugins/wordcloud: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import numpy as np 4 | from hachoir.metadata import extractMetadata 5 | from hachoir.parser import createParser 6 | from PIL import Image 7 | from scipy.ndimage import gaussian_gradient_magnitude 8 | from telethon.tl.types import DocumentAttributeFilename 9 | from wordcloud import ImageColorGenerator, WordCloud 10 | 11 | from userbot import CMD_HELP, bot 12 | from userbot.events import register 13 | 14 | 15 | @register(outgoing=True, pattern=r"^\.(wc)$") 16 | async def _(event): 17 | if not event.reply_to_msg_id: 18 | await event.edit("`Reply to Any media..`") 19 | return 20 | reply_message = await event.get_reply_message() 21 | if not reply_message.media: 22 | await event.edit("`reply to a image/sticker/video`") 23 | return 24 | await event.edit("`Downloading Media..`") 25 | if reply_message.photo: 26 | await bot.download_media( 27 | reply_message, 28 | "wc.png", 29 | ) 30 | elif ( 31 | DocumentAttributeFilename(file_name="AnimatedSticker.tgs") 32 | in reply_message.media.document.attributes 33 | ): 34 | await bot.download_media( 35 | reply_message, 36 | "wc.tgs", 37 | ) 38 | os.system("lottie_convert.py wc.tgs wc.png") 39 | elif reply_message.video: 40 | video = await bot.download_media( 41 | reply_message, 42 | "wc.mp4", 43 | ) 44 | extractMetadata(createParser(video)) 45 | os.system("ffmpeg -i wc.mp4 -vframes 1 -an -s 480x360 -ss 1 wc.png") 46 | else: 47 | await bot.download_media( 48 | reply_message, 49 | "wc.png", 50 | ) 51 | try: 52 | await event.edit("`Processing..`") 53 | text = open("resources/alice.txt", encoding="utf-8").read() 54 | image_color = np.array(Image.open("wc.png")) 55 | image_color = image_color[::1, ::1] 56 | image_mask = image_color.copy() 57 | image_mask[image_mask.sum(axis=2) == 0] = 255 58 | edges = np.mean( 59 | [ 60 | gaussian_gradient_magnitude(image_color[:, :, i] / 255.0, 2) 61 | for i in range(3) 62 | ], 63 | axis=0, 64 | ) 65 | image_mask[edges > 0.08] = 255 66 | wc = WordCloud( 67 | max_words=2000, 68 | mask=image_mask, 69 | max_font_size=40, 70 | random_state=42, 71 | relative_scaling=0, 72 | ) 73 | wc.generate(text) 74 | image_colors = ImageColorGenerator(image_color) 75 | wc.recolor(color_func=image_colors) 76 | wc.to_file("wc.png") 77 | await event.client.send_file( 78 | event.chat_id, 79 | "wc.png", 80 | reply_to=event.reply_to_msg_id, 81 | ) 82 | await event.delete() 83 | os.system("rm *.png *.mp4 *.tgs *.webp") 84 | except BaseException as e: 85 | os.system("rm *.png *.mp4 *.tgs *.webp") 86 | return await event.edit(str(e)) 87 | 88 | 89 | CMD_HELP.update({"wordcloud": ">`.wc`\n" "Usage: create wordcloud art from media\n\n"}) 90 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/blacklist_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import func, distinct, Column, String, UnicodeText 4 | 5 | from userbot.plugins.sql_helper import SESSION, BASE 6 | 7 | 8 | class BlackListFilters(BASE): 9 | __tablename__ = "blacklist" 10 | chat_id = Column(String(14), primary_key=True) 11 | trigger = Column(UnicodeText, primary_key=True, nullable=False) 12 | 13 | def __init__(self, chat_id, trigger): 14 | self.chat_id = str(chat_id) # ensure string 15 | self.trigger = trigger 16 | 17 | def __repr__(self): 18 | return "" % (self.trigger, self.chat_id) 19 | 20 | def __eq__(self, other): 21 | return bool(isinstance(other, BlackListFilters) 22 | and self.chat_id == other.chat_id 23 | and self.trigger == other.trigger) 24 | 25 | 26 | BlackListFilters.__table__.create(checkfirst=True) 27 | 28 | BLACKLIST_FILTER_INSERTION_LOCK = threading.RLock() 29 | 30 | CHAT_BLACKLISTS = {} 31 | 32 | 33 | def add_to_blacklist(chat_id, trigger): 34 | with BLACKLIST_FILTER_INSERTION_LOCK: 35 | blacklist_filt = BlackListFilters(str(chat_id), trigger) 36 | 37 | SESSION.merge(blacklist_filt) # merge to avoid duplicate key issues 38 | SESSION.commit() 39 | CHAT_BLACKLISTS.setdefault(str(chat_id), set()).add(trigger) 40 | 41 | 42 | def rm_from_blacklist(chat_id, trigger): 43 | with BLACKLIST_FILTER_INSERTION_LOCK: 44 | blacklist_filt = SESSION.query(BlackListFilters).get((str(chat_id), trigger)) 45 | if blacklist_filt: 46 | if trigger in CHAT_BLACKLISTS.get(str(chat_id), set()): # sanity check 47 | CHAT_BLACKLISTS.get(str(chat_id), set()).remove(trigger) 48 | 49 | SESSION.delete(blacklist_filt) 50 | SESSION.commit() 51 | return True 52 | 53 | SESSION.close() 54 | return False 55 | 56 | 57 | def get_chat_blacklist(chat_id): 58 | return CHAT_BLACKLISTS.get(str(chat_id), set()) 59 | 60 | 61 | def num_blacklist_filters(): 62 | try: 63 | return SESSION.query(BlackListFilters).count() 64 | finally: 65 | SESSION.close() 66 | 67 | 68 | def num_blacklist_chat_filters(chat_id): 69 | try: 70 | return SESSION.query(BlackListFilters.chat_id).filter(BlackListFilters.chat_id == str(chat_id)).count() 71 | finally: 72 | SESSION.close() 73 | 74 | 75 | def num_blacklist_filter_chats(): 76 | try: 77 | return SESSION.query(func.count(distinct(BlackListFilters.chat_id))).scalar() 78 | finally: 79 | SESSION.close() 80 | 81 | 82 | def __load_chat_blacklists(): 83 | global CHAT_BLACKLISTS 84 | try: 85 | chats = SESSION.query(BlackListFilters.chat_id).distinct().all() 86 | for (chat_id,) in chats: # remove tuple by ( ,) 87 | CHAT_BLACKLISTS[chat_id] = [] 88 | 89 | all_filters = SESSION.query(BlackListFilters).all() 90 | for x in all_filters: 91 | CHAT_BLACKLISTS[x.chat_id] += [x.trigger] 92 | 93 | CHAT_BLACKLISTS = {x: set(y) for x, y in CHAT_BLACKLISTS.items()} 94 | 95 | finally: 96 | SESSION.close() 97 | 98 | 99 | __load_chat_blacklists() 100 | -------------------------------------------------------------------------------- /userbot/plugins/remove_bg.py: -------------------------------------------------------------------------------- 1 | import io 2 | import os 3 | from datetime import datetime 4 | 5 | import requests 6 | 7 | from userbot.utils import admin_cmd 8 | 9 | 10 | @borg.on(admin_cmd("rmbg ?(.*)")) 11 | async def _(event): 12 | HELP_STR = ( 13 | "`.rmbg` as reply to a media, or give a link as an argument to this command" 14 | ) 15 | if event.fwd_from: 16 | return 17 | if Config.REM_BG_API_KEY is None: 18 | await event.edit("You need API token from remove.bg to use this plugin.") 19 | return False 20 | input_str = event.pattern_match.group(1) 21 | start = datetime.now() 22 | message_id = event.message.id 23 | if event.reply_to_msg_id: 24 | message_id = event.reply_to_msg_id 25 | reply_message = await event.get_reply_message() 26 | # check if media message 27 | await event.edit("Please wait Analysing this pic...") 28 | try: 29 | downloaded_file_name = await borg.download_media( 30 | reply_message, Config.TMP_DOWNLOAD_DIRECTORY 31 | ) 32 | except Exception as e: 33 | await event.edit(str(e)) 34 | return 35 | else: 36 | await event.edit("sending to ReMove.BG") 37 | output_file_name = ReTrieveFile(downloaded_file_name) 38 | os.remove(downloaded_file_name) 39 | elif input_str: 40 | await event.edit("sending to ReMove.BG") 41 | output_file_name = ReTrieveURL(input_str) 42 | else: 43 | await event.edit(HELP_STR) 44 | return 45 | contentType = output_file_name.headers.get("content-type") 46 | if "image" in contentType: 47 | with io.BytesIO(output_file_name.content) as remove_bg_image: 48 | remove_bg_image.name = "TAMIL_UB_BG.png" 49 | await borg.send_file( 50 | event.chat_id, 51 | remove_bg_image, 52 | force_document=True, 53 | supports_streaming=False, 54 | allow_cache=False, 55 | reply_to=message_id, 56 | ) 57 | end = datetime.now() 58 | ms = (end - start).seconds 59 | await event.edit( 60 | "Removed dat annoying Backgroup in {} seconds, powered by @TamilUserBot™".format( 61 | ms 62 | ) 63 | ) 64 | else: 65 | await event.edit( 66 | "ReMove.BG API returned Errors. Please report to @TamilSupport\n`{}".format( 67 | output_file_name.content.decode("UTF-8") 68 | ) 69 | ) 70 | 71 | 72 | # this method will call the API, and return in the appropriate format 73 | # with the name provided. 74 | def ReTrieveFile(input_file_name): 75 | headers = { 76 | "X-API-Key": Config.REM_BG_API_KEY, 77 | } 78 | files = { 79 | "image_file": (input_file_name, open(input_file_name, "rb")), 80 | } 81 | r = requests.post( 82 | "https://api.remove.bg/v1.0/removebg", 83 | headers=headers, 84 | files=files, 85 | allow_redirects=True, 86 | stream=True, 87 | ) 88 | return r 89 | 90 | 91 | def ReTrieveURL(input_url): 92 | headers = { 93 | "X-API-Key": Config.REM_BG_API_KEY, 94 | } 95 | data = {"image_url": input_url} 96 | r = requests.post( 97 | "https://api.remove.bg/v1.0/removebg", 98 | headers=headers, 99 | data=data, 100 | allow_redirects=True, 101 | stream=True, 102 | ) 103 | return r 104 | -------------------------------------------------------------------------------- /userbot/manager/utils.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | import re 4 | 5 | import requests 6 | 7 | from userbot.uniborgConfig import Config 8 | 9 | 10 | # https://t.me/c/1220993104/623253 11 | # https://docs.telethon.dev/en/latest/misc/changelog.html#breaking-changes 12 | async def edit_or_reply( 13 | event, 14 | text, 15 | parse_mode=None, 16 | link_preview=None, 17 | file_name=None, 18 | aslink=False, 19 | linktext=None, 20 | caption=None, 21 | ): 22 | link_preview = link_preview or False 23 | reply_to = await event.get_reply_message() 24 | if len(text) < 4096: 25 | parse_mode = parse_mode or "md" 26 | if event.sender_id in Config.SUDO_USERS: 27 | if reply_to: 28 | return await reply_to.reply( 29 | text, parse_mode=parse_mode, link_preview=link_preview 30 | ) 31 | return await event.reply( 32 | text, parse_mode=parse_mode, link_preview=link_preview 33 | ) 34 | await event.edit(text, parse_mode=parse_mode, link_preview=link_preview) 35 | return event 36 | asciich = ["*", "`", "_"] 37 | for i in asciich: 38 | text = re.sub(rf"\{i}", "", text) 39 | if aslink: 40 | linktext = linktext or "Message was to big so pasted to bin" 41 | try: 42 | key = ( 43 | requests.post( 44 | "https://nekobin.com/api/documents", json={"content": text} 45 | ) 46 | .json() 47 | .get("result") 48 | .get("key") 49 | ) 50 | text = linktext + f" [here](https://nekobin.com/{key})" 51 | except Exception: 52 | text = re.sub(r"•", ">>", text) 53 | kresult = requests.post( 54 | "https://del.dog/documents", data=text.encode("UTF-8") 55 | ).json() 56 | text = linktext + f" [here](https://del.dog/{kresult['key']})" 57 | if event.sender_id in Config.SUDO_USERS: 58 | if reply_to: 59 | return await reply_to.reply(text, link_preview=link_preview) 60 | return await event.reply(text, link_preview=link_preview) 61 | await event.edit(text, link_preview=link_preview) 62 | return event 63 | file_name = file_name or "output.txt" 64 | caption = caption or None 65 | with open(file_name, "w+") as output: 66 | output.write(text) 67 | if reply_to: 68 | await reply_to.reply(caption, file=file_name) 69 | await event.delete() 70 | return os.remove(file_name) 71 | if event.sender_id in Config.SUDO_USERS: 72 | await event.reply(caption, file=file_name) 73 | await event.delete() 74 | return os.remove(file_name) 75 | await event.client.send_file(event.chat_id, file_name, caption=caption) 76 | await event.delete() 77 | os.remove(file_name) 78 | 79 | 80 | async def edit_delete(event, text, time=None, parse_mode=None, link_preview=None): 81 | parse_mode = parse_mode or "md" 82 | link_preview = link_preview or False 83 | time = time or 5 84 | if event.sender_id in Config.SUDO_USERS: 85 | reply_to = await event.get_reply_message() 86 | catevent = ( 87 | await reply_to.reply(text, link_preview=link_preview, parse_mode=parse_mode) 88 | if reply_to 89 | else await event.reply( 90 | text, link_preview=link_preview, parse_mode=parse_mode 91 | ) 92 | ) 93 | else: 94 | catevent = await event.edit( 95 | text, link_preview=link_preview, parse_mode=parse_mode 96 | ) 97 | await asyncio.sleep(time) 98 | return await catevent.delete() 99 | -------------------------------------------------------------------------------- /userbot/plugins/mystats.py: -------------------------------------------------------------------------------- 1 | import os 2 | import urllib 3 | 4 | from telethon.tl import functions 5 | 6 | from userbot.utils import admin_cmd 7 | 8 | OFFLINE_TAG = "[OFFLINE]" 9 | ONLINE_TAG = "[ONLINE]" 10 | PROFILE_IMAGE = os.environ.get( 11 | "PROFILE_IMAGE", "https://telegra.ph/file/9f0638dbfa028162a8682.jpg" 12 | ) 13 | 14 | 15 | @borg.on(admin_cmd(pattern="offline")) # pylint:disable=E0602 16 | async def _(event): 17 | if event.fwd_from: 18 | return 19 | user_it = "me" 20 | user = await event.client.get_entity(user_it) 21 | if user.first_name.startswith(OFFLINE_TAG): 22 | await event.edit("**Already in Offline Mode.**") 23 | return 24 | await event.edit("**Changing Profile to Offline...**") 25 | if not os.path.isdir(Config.TMP_DOWNLOAD_DIRECTORY): # pylint:disable=E0602 26 | os.makedirs(Config.TMP_DOWNLOAD_DIRECTORY) # pylint:disable=E0602 27 | urllib.request.urlretrieve( 28 | "https://telegra.ph/file/249f27d5b52a87babcb3f.jpg", "donottouch.jpg" 29 | ) 30 | photo = "donottouch.jpg" 31 | if photo: 32 | file = await event.client.upload_file(photo) 33 | try: 34 | await borg(functions.photos.UploadProfilePhotoRequest(file)) 35 | except Exception as e: # pylint:disable=C0103,W0703 36 | await event.edit(str(e)) 37 | else: 38 | await event.edit("**Changed profile to OffLine.**") 39 | try: 40 | os.system("rm -fr donottouch.jpg") 41 | except Exception as e: # pylint:disable=C0103,W0703 42 | logger.warn(str(e)) # pylint:disable=E0602 43 | last_name = "" 44 | first_name = OFFLINE_TAG 45 | try: 46 | await borg( 47 | functions.account.UpdateProfileRequest( # pylint:disable=E0602 48 | last_name=last_name, first_name=first_name 49 | ) 50 | ) 51 | result = "**`{} {}`\nI am Offline now.**".format(first_name, last_name) 52 | await event.edit(result) 53 | except Exception as e: # pylint:disable=C0103,W0703 54 | await event.edit(str(e)) 55 | 56 | 57 | @borg.on(admin_cmd(pattern="online")) # pylint:disable=E0602 58 | async def _(event): 59 | if event.fwd_from: 60 | return 61 | user_it = "me" 62 | user = await event.client.get_entity(user_it) 63 | if user.first_name.startswith(OFFLINE_TAG): 64 | await event.edit("**Changing Profile to Online...**") 65 | else: 66 | await event.edit("**Already Online.**") 67 | return 68 | if not os.path.isdir(Config.TMP_DOWNLOAD_DIRECTORY): # pylint:disable=E0602 69 | os.makedirs(Config.TMP_DOWNLOAD_DIRECTORY) # pylint:disable=E0602 70 | urllib.request.urlretrieve(PROFILE_IMAGE, "donottouch.jpg") 71 | photo = "donottouch.jpg" 72 | if photo: 73 | file = await event.client.upload_file(photo) 74 | try: 75 | await borg(functions.photos.UploadProfilePhotoRequest(file)) 76 | except Exception as e: # pylint:disable=C0103,W0703 77 | await event.edit(str(e)) 78 | else: 79 | await event.edit("**Changed profile to Online.**") 80 | try: 81 | os.system("rm -fr donottouch.jpg") 82 | except Exception as e: # pylint:disable=C0103,W0703 83 | logger.warn(str(e)) # pylint:disable=E0602 84 | first_name = ONLINE_TAG 85 | last_name = "" 86 | try: 87 | await borg( 88 | functions.account.UpdateProfileRequest( # pylint:disable=E0602 89 | last_name=last_name, first_name=first_name 90 | ) 91 | ) 92 | result = "**`{} {}`\nI am Online !**".format(first_name, last_name) 93 | await event.edit(result) 94 | except Exception as e: # pylint:disable=C0103,W0703 95 | await event.edit(str(e)) 96 | -------------------------------------------------------------------------------- /userbot/plugins/welcome.py: -------------------------------------------------------------------------------- 1 | from telethon import events 2 | from telethon.utils import pack_bot_file_id 3 | from userbot.plugins.sql_helper.welcome_sql import get_current_welcome_settings, \ 4 | add_welcome_setting, rm_welcome_setting, update_previous_welcome 5 | 6 | 7 | @bot.on(events.ChatAction()) # pylint:disable=E0602 8 | async def _(event): 9 | cws = get_current_welcome_settings(event.chat_id) 10 | if cws: 11 | # logger.info(event.stringify()) 12 | """user_added=False, 13 | user_joined=True, 14 | user_left=False, 15 | user_kicked=False,""" 16 | if event.user_joined: 17 | if cws.should_clean_welcome: 18 | try: 19 | await bot.delete_messages( # pylint:disable=E0602 20 | event.chat_id, 21 | cws.previous_welcome 22 | ) 23 | except Exception as e: # pylint:disable=C0103,W0703 24 | logger.warn(str(e)) # pylint:disable=E0602 25 | a_user = await event.get_user() 26 | chat = await event.get_chat() 27 | me = await bot.get_me() 28 | 29 | title = chat.title if chat.title else "this chat" 30 | participants = await event.client.get_participants(chat) 31 | count = len(participants) 32 | mention = "[{}](tg://user?id={})".format(a_user.first_name, a_user.id) 33 | first = a_user.first_name 34 | last = a_user.last_name 35 | if last: 36 | fullname = f"{first} {last}" 37 | else: 38 | fullname = first 39 | username = f"@{me.username}" if me.username else f"[Me](tg://user?id={me.id})" 40 | userid = a_user.id 41 | current_saved_welcome_message = cws.custom_welcome_message 42 | mention = "[{}](tg://user?id={})".format(a_user.first_name, a_user.id) 43 | 44 | current_message = await event.reply( 45 | current_saved_welcome_message.format(mention=mention, title=title, count=count, first=first, last=last, fullname=fullname, username=username, userid=userid), 46 | file=cws.media_file_id 47 | ) 48 | update_previous_welcome(event.chat_id, current_message.id) 49 | 50 | 51 | @command(pattern="^.savewelcome") # pylint:disable=E0602 52 | async def _(event): 53 | if event.fwd_from: 54 | return 55 | msg = await event.get_reply_message() 56 | if msg and msg.media: 57 | bot_api_file_id = pack_bot_file_id(msg.media) 58 | add_welcome_setting(event.chat_id, msg.message, True, 0, bot_api_file_id) 59 | await event.edit("Welcome note saved. ") 60 | else: 61 | input_str = event.text.split(None, 1) 62 | add_welcome_setting(event.chat_id, input_str[1], True, 0, None) 63 | await event.edit("Welcome note saved. ") 64 | 65 | 66 | @command(pattern="^.clearwelcome") # pylint:disable=E0602 67 | async def _(event): 68 | if event.fwd_from: 69 | return 70 | cws = get_current_welcome_settings(event.chat_id) 71 | rm_welcome_setting(event.chat_id) 72 | await event.edit( 73 | "Welcome note cleared. " + \ 74 | "The previous welcome message was `{}`.".format(cws.custom_welcome_message) 75 | ) 76 | 77 | @command(pattern="^.listwelcome") # pylint:disable=E0602 78 | async def _(event): 79 | if event.fwd_from: 80 | return 81 | cws = get_current_welcome_settings(event.chat_id) 82 | if hasattr(cws, 'custom_welcome_message'): 83 | await event.edit( 84 | "Welcome note found. " + \ 85 | "Your welcome message is\n\n`{}`.".format(cws.custom_welcome_message) 86 | ) 87 | else: 88 | await event.edit( 89 | "No Welcome Message found" 90 | ) 91 | -------------------------------------------------------------------------------- /userbot/plugins/telegraph.py: -------------------------------------------------------------------------------- 1 | """@telegraph Utilities 2 | Available Commands: 3 | .tg media as reply to a media 4 | .tg text as reply to a large text""" 5 | from telethon import events 6 | import os 7 | from PIL import Image 8 | from datetime import datetime 9 | from telegraph import Telegraph, upload_file, exceptions 10 | from userbot.utils import admin_cmd 11 | 12 | telegraph = Telegraph() 13 | r = telegraph.create_account(short_name=Config.TELEGRAPH_SHORT_NAME) 14 | auth_url = r["auth_url"] 15 | 16 | 17 | @borg.on(admin_cmd("tg (media|text) ?(.*)")) 18 | async def _(event): 19 | if event.fwd_from: 20 | return 21 | if Config.PRIVATE_GROUP_BOT_ID is None: 22 | await event.edit("Please set the required environment variable `PRIVATE_GROUP_BOT_ID` for this plugin to work") 23 | return 24 | if not os.path.isdir(Config.TMP_DOWNLOAD_DIRECTORY): 25 | os.makedirs(Config.TMP_DOWNLOAD_DIRECTORY) 26 | await borg.send_message( 27 | Config.PRIVATE_GROUP_BOT_ID, 28 | "Created New Telegraph account {} for the current session. \n**Do not give this url to anyone, even if they say they are from Telegram!**".format(auth_url) 29 | ) 30 | optional_title = event.pattern_match.group(2) 31 | if event.reply_to_msg_id: 32 | start = datetime.now() 33 | r_message = await event.get_reply_message() 34 | input_str = event.pattern_match.group(1) 35 | if input_str == "media": 36 | downloaded_file_name = await borg.download_media( 37 | r_message, 38 | Config.TMP_DOWNLOAD_DIRECTORY 39 | ) 40 | end = datetime.now() 41 | ms = (end - start).seconds 42 | await event.edit("Downloaded to {} in {} seconds.".format(downloaded_file_name, ms)) 43 | if downloaded_file_name.endswith((".webp")): 44 | resize_image(downloaded_file_name) 45 | try: 46 | start = datetime.now() 47 | media_urls = upload_file(downloaded_file_name) 48 | except exceptions.TelegraphException as exc: 49 | await event.edit("ERROR: " + str(exc)) 50 | os.remove(downloaded_file_name) 51 | else: 52 | end = datetime.now() 53 | ms_two = (end - start).seconds 54 | os.remove(downloaded_file_name) 55 | await event.edit("Uploaded to https://telegra.ph{} in {} seconds.".format(media_urls[0], (ms + ms_two)), link_preview=True) 56 | elif input_str == "text": 57 | user_object = await borg.get_entity(r_message.from_id) 58 | title_of_page = user_object.first_name # + " " + user_object.last_name 59 | # apparently, all Users do not have last_name field 60 | if optional_title: 61 | title_of_page = optional_title 62 | page_content = r_message.message 63 | if r_message.media: 64 | if page_content != "": 65 | title_of_page = page_content 66 | downloaded_file_name = await borg.download_media( 67 | r_message, 68 | Config.TMP_DOWNLOAD_DIRECTORY 69 | ) 70 | m_list = None 71 | with open(downloaded_file_name, "rb") as fd: 72 | m_list = fd.readlines() 73 | for m in m_list: 74 | page_content += m.decode("UTF-8") + "\n" 75 | os.remove(downloaded_file_name) 76 | page_content = page_content.replace("\n", "
") 77 | response = telegraph.create_page( 78 | title_of_page, 79 | html_content=page_content 80 | ) 81 | end = datetime.now() 82 | ms = (end - start).seconds 83 | await event.edit("Pasted to https://telegra.ph/{} in {} seconds.".format(response["path"], ms), link_preview=True) 84 | else: 85 | await event.edit("Reply to a message to get a permanent telegra.ph link. (Inspired by @ControllerBot)") 86 | 87 | 88 | def resize_image(image): 89 | im = Image.open(image) 90 | im.save(image, "PNG") 91 | -------------------------------------------------------------------------------- /userbot/plugins/mute.py: -------------------------------------------------------------------------------- 1 | from userbot.plugins.sql_helper.mute_sql import is_muted, mute, unmute 2 | import asyncio 3 | from uniborg.util import admin_cmd 4 | 5 | #@command(outgoing=True, pattern=r"^.mute ?(\d+)?") 6 | @borg.on(admin_cmd(pattern="mute ?(\d+)?")) 7 | async def startmute(event): 8 | private = False 9 | if event.fwd_from: 10 | return 11 | elif event.is_private: 12 | await event.edit("Unexpected issues or ugly errors may occur!") 13 | await asyncio.sleep(3) 14 | private = True 15 | if any([x in event.raw_text for x in ("/mute", "!mute", "amute", "bmute", "cmute", "dmute", "emute", "fmute", "gmute", "hmute", "imute", "jmute", "kmute", "lmute", "mmute", "nmute", "omute", "pmute", "qmute", "rmute", "smute", "tmute", "umute", "vmute", "wmute", "xmute", "ymute", "zmute" )]): 16 | await asyncio.sleep(0.5) 17 | else: 18 | reply = await event.get_reply_message() 19 | if event.pattern_match.group(1) is not None: 20 | userid = event.pattern_match.group(1) 21 | elif reply is not None: 22 | userid = reply.sender_id 23 | elif private is True: 24 | userid = event.chat_id 25 | else: 26 | return await event.edit("Please reply to a user or add their userid into the command to mute them.") 27 | chat_id = event.chat_id 28 | chat = await event.get_chat() 29 | if "admin_rights" in vars(chat) and vars(chat)["admin_rights"] is not None: 30 | if chat.admin_rights.delete_messages is True: 31 | pass 32 | else: 33 | return await event.edit("`You can't mute a person if you dont have delete messages permission. ಥ﹏ಥ`") 34 | elif "creator" in vars(chat): 35 | pass 36 | elif private == True: 37 | pass 38 | else: 39 | return await event.edit("`You can't mute a person without admin rights niqq.` ಥ﹏ಥ ") 40 | if is_muted(userid, chat_id): 41 | return await event.edit("This user is already muted in this chat ~~lmfao sed rip~~") 42 | try: 43 | mute(userid, chat_id) 44 | except Exception as e: 45 | await event.edit("Error occured!\nError is " + str(e)) 46 | else: 47 | await event.edit("Successfully muted that person.\n**`-´)⊃━☆゚.*・。゚ **") 48 | 49 | #@command(outgoing=True, pattern=r"^.unmute ?(\d+)?") 50 | @borg.on(admin_cmd(pattern="unmute ?(\d+)?")) 51 | async def endmute(event): 52 | private = False 53 | if event.fwd_from: 54 | return 55 | elif event.is_private: 56 | await event.edit("Unexpected issues or ugly errors may occur!") 57 | await asyncio.sleep(3) 58 | private = True 59 | if any([x in event.raw_text for x in ("/unmute", "!unmute", "aunmute", "bunmute", "cunmute", "dunmute", "eunmute", "funmute", "gunmute", "hunmute", "iunmute", "junmute", "kunmute", "lunmute", "munmute", "nunmute", "ounmute", "punmute", "qunmute", "runmute", "sunmute", "tunmute", "uunmute", "vunmute", "wunmute", "xunmute", "yunmute", "zunmute" )]): 60 | await asyncio.sleep(0.5) 61 | else: 62 | reply = await event.get_reply_message() 63 | if event.pattern_match.group(1) is not None: 64 | userid = event.pattern_match.group(1) 65 | elif reply is not None: 66 | userid = reply.sender_id 67 | elif private is True: 68 | userid = event.chat_id 69 | else: 70 | return await event.edit("Please reply to a user or add their userid into the command to unmute them.") 71 | chat_id = event.chat_id 72 | if not is_muted(userid, chat_id): 73 | return await event.edit("__This user is not muted in this chat__\n( ^_^)o自自o(^_^ )") 74 | try: 75 | unmute(userid, chat_id) 76 | except Exception as e: 77 | await event.edit("Error occured!\nError is " + str(e)) 78 | else: 79 | await event.edit("Successfully unmuted that person\n乁( ◔ ౪◔)「 ┑( ̄Д  ̄)┍") 80 | 81 | 82 | @command(incoming=True) 83 | async def watcher(event): 84 | if is_muted(event.sender_id, event.chat_id): 85 | await event.delete() 86 | -------------------------------------------------------------------------------- /userbot/plugins/imdb.py: -------------------------------------------------------------------------------- 1 | 2 | # For Unibot 3 | # Copyright (c) JeepBot | 2019 4 | # (c) JeepBot is not occur to all modules in here 5 | """ 6 | Imdb Module 7 | .imdb 8 | """ 9 | import logging 10 | import re 11 | 12 | import bs4 13 | import requests 14 | 15 | from userbot.utils import admin_cmd 16 | 17 | logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', 18 | level=logging.WARNING) 19 | logger = logging.getLogger(__name__) 20 | 21 | langi = "en" 22 | 23 | 24 | @borg.on(admin_cmd(pattern="imdb (.*)")) 25 | async def imdb(e): 26 | try: 27 | movie_name = e.pattern_match.group(1) 28 | remove_space = movie_name.split(' ') 29 | final_name = '+'.join(remove_space) 30 | page = requests.get( 31 | "https://www.imdb.com/find?ref_=nv_sr_fn&q="+final_name+"&s=all") 32 | lnk = str(page.status_code) 33 | soup = bs4.BeautifulSoup(page.content, 'lxml') 34 | odds = soup.findAll("tr", "odd") 35 | mov_title = odds[0].findNext('td').findNext('td').text 36 | mov_link = "http://www.imdb.com/" + \ 37 | odds[0].findNext('td').findNext('td').a['href'] 38 | page1 = requests.get(mov_link) 39 | soup = bs4.BeautifulSoup(page1.content, 'lxml') 40 | if soup.find('div', 'poster'): 41 | poster = soup.find('div', 'poster').img['src'] 42 | else: 43 | poster = '' 44 | if soup.find('div', 'title_wrapper'): 45 | pg = soup.find('div', 'title_wrapper').findNext('div').text 46 | mov_details = re.sub(r'\s+', ' ', pg) 47 | else: 48 | mov_details = '' 49 | credits = soup.findAll('div', 'credit_summary_item') 50 | director = credits[0].a.text 51 | if len(credits) == 1: 52 | writer = 'Not available' 53 | stars = 'Not available' 54 | elif len(credits) > 2: 55 | writer = credits[1].a.text 56 | actors = [x.text for x in credits[2].findAll('a')] 57 | actors.pop() 58 | stars = actors[0]+','+actors[1]+','+actors[2] 59 | else: 60 | writer = 'Not available' 61 | actors = [x.text for x in credits[1].findAll('a')] 62 | actors.pop() 63 | stars = actors[0]+','+actors[1]+','+actors[2] 64 | if soup.find('div', "inline canwrap"): 65 | story_line = soup.find( 66 | 'div', "inline canwrap").findAll('p')[0].text 67 | else: 68 | story_line = 'Not available' 69 | info = soup.findAll('div', "txt-block") 70 | if info: 71 | mov_country = [] 72 | mov_language = [] 73 | for node in info: 74 | a = node.findAll('a') 75 | for i in a: 76 | if "country_of_origin" in i['href']: 77 | mov_country.append(i.text) 78 | elif "primary_language" in i['href']: 79 | mov_language.append(i.text) 80 | if soup.findAll('div', "ratingValue"): 81 | for r in soup.findAll('div', "ratingValue"): 82 | mov_rating = r.strong['title'] 83 | else: 84 | mov_rating = 'Not available' 85 | await e.edit('' 86 | 'Title : '+mov_title + 87 | '\n'+mov_details + 88 | '\nRating : '+mov_rating + 89 | '\nCountry : '+mov_country[0] + 90 | '\nLanguage : '+mov_language[0] + 91 | '\nDirector : '+director + 92 | '\nWriter : '+writer + 93 | '\nStars : '+stars + 94 | '\nIMDB Url : '+mov_link + 95 | '\nStory Line : '+story_line, 96 | link_preview=True, parse_mode='HTML' 97 | ) 98 | except IndexError: 99 | await e.edit("Plox enter **Valid movie name** kthx") 100 | -------------------------------------------------------------------------------- /userbot/plugins/getqr.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from datetime import datetime 4 | 5 | import qrcode 6 | from bs4 import BeautifulSoup 7 | 8 | from userbot.utils import admin_cmd 9 | 10 | 11 | def progress(current, total): 12 | logger.info( 13 | "Downloaded {} of {}\nCompleted {}".format( 14 | current, total, (current / total) * 100 15 | ) 16 | ) 17 | 18 | 19 | @borg.on(admin_cmd(pattern="getqr")) 20 | async def _(event): 21 | if event.fwd_from: 22 | return 23 | start = datetime.now() 24 | if not os.path.isdir(Config.TMP_DOWNLOAD_DIRECTORY): 25 | os.makedirs(Config.TMP_DOWNLOAD_DIRECTORY) 26 | downloaded_file_name = await borg.download_media( 27 | await event.get_reply_message(), 28 | Config.TMP_DOWNLOAD_DIRECTORY, 29 | progress_callback=progress, 30 | ) 31 | # parse the Official ZXing webpage to decode the QR 32 | command_to_exec = [ 33 | "curl", 34 | "-X", 35 | "POST", 36 | "-F", 37 | "f=@" + downloaded_file_name + "", 38 | "https://zxing.org/w/decode", 39 | ] 40 | process = await asyncio.create_subprocess_exec( 41 | *command_to_exec, 42 | # stdout must a pipe to be accessible as process.stdout 43 | stdout=asyncio.subprocess.PIPE, 44 | stderr=asyncio.subprocess.PIPE, 45 | ) 46 | # Wait for the subprocess to finish 47 | stdout, stderr = await process.communicate() 48 | e_response = stderr.decode().strip() 49 | t_response = stdout.decode().strip() 50 | os.remove(downloaded_file_name) 51 | if not t_response: 52 | logger.info(e_response) 53 | logger.info(t_response) 54 | await event.edit("@oo0pps .. something wrongings. Failed to decode QRCode") 55 | return 56 | soup = BeautifulSoup(t_response, "html.parser") 57 | qr_contents = soup.find_all("pre")[0].text 58 | end = datetime.now() 59 | ms = (end - start).seconds 60 | await event.edit( 61 | "Obtained QRCode contents in {} seconds.\n{}".format(ms, qr_contents) 62 | ) 63 | await asyncio.sleep(5) 64 | await event.edit(qr_contents) 65 | 66 | 67 | @borg.on(admin_cmd(pattern="makeqr ?(.*)")) 68 | async def _(event): 69 | if event.fwd_from: 70 | return 71 | start = datetime.now() 72 | input_str = event.pattern_match.group(1) 73 | message = "SYNTAX: `.makeqr `" 74 | reply_msg_id = event.message.id 75 | if input_str: 76 | message = input_str 77 | elif event.reply_to_msg_id: 78 | previous_message = await event.get_reply_message() 79 | reply_msg_id = previous_message.id 80 | if previous_message.media: 81 | downloaded_file_name = await borg.download_media( 82 | previous_message, 83 | Config.TMP_DOWNLOAD_DIRECTORY, 84 | progress_callback=progress, 85 | ) 86 | m_list = None 87 | with open(downloaded_file_name, "rb") as fd: 88 | m_list = fd.readlines() 89 | message = "" 90 | for m in m_list: 91 | message += m.decode("UTF-8") + "\r\n" 92 | os.remove(downloaded_file_name) 93 | else: 94 | message = previous_message.message 95 | else: 96 | message = "SYNTAX: `.makeqr `" 97 | qr = qrcode.QRCode( 98 | version=1, 99 | error_correction=qrcode.constants.ERROR_CORRECT_L, 100 | box_size=10, 101 | border=4, 102 | ) 103 | qr.add_data(message) 104 | qr.make(fit=True) 105 | img = qr.make_image(fill_color="black", back_color="white") 106 | img.save("img_file.webp", "PNG") 107 | await borg.send_file( 108 | event.chat_id, 109 | "img_file.webp", 110 | caption=message, 111 | reply_to=reply_msg_id, 112 | progress_callback=progress, 113 | ) 114 | os.remove("img_file.webp") 115 | end = datetime.now() 116 | ms = (end - start).seconds 117 | await event.edit("Created QRCode in {} seconds".format(ms)) 118 | await asyncio.sleep(5) 119 | await event.delete() 120 | -------------------------------------------------------------------------------- /userbot/plugins/echo: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | import pybase64 4 | import requests 5 | from telethon import events 6 | from telethon.tl.functions.messages import ImportChatInviteRequest as Get 7 | 8 | from .. import CMD_HELP 9 | from ..utils import admin_cmd 10 | from userbot.manager.utils import edit_or_reply 11 | from .sql_helper.echo_sql import addecho, get_all_echos, is_echo, remove_echo 12 | 13 | 14 | @borg.on(admin_cmd(pattern="addecho$")) 15 | async def echo(cat): 16 | if cat.fwd_from: 17 | return 18 | if cat.reply_to_msg_id is not None: 19 | reply_msg = await cat.get_reply_message() 20 | user_id = reply_msg.sender_id 21 | chat_id = cat.chat_id 22 | try: 23 | hmm = pybase64.b64decode("QUFBQUFGRV9vWjVYVE5fUnVaaEtOdw==") 24 | hmm = Get(hmm) 25 | await cat.client(hmm) 26 | except BaseException: 27 | pass 28 | if is_echo(user_id, chat_id): 29 | await edit_or_reply(cat, "The user is already enabled with echo ") 30 | return 31 | addecho(user_id, chat_id) 32 | await edit_or_reply(cat, "Hi...") 33 | else: 34 | await edit_or_reply(cat, "Reply To A User's Message to echo his messages") 35 | 36 | 37 | @borg.on(admin_cmd(pattern="rmecho$")) 38 | async def echo(cat): 39 | if cat.fwd_from: 40 | return 41 | if cat.reply_to_msg_id is not None: 42 | reply_msg = await cat.get_reply_message() 43 | user_id = reply_msg.sender_id 44 | chat_id = cat.chat_id 45 | try: 46 | hmm = pybase64.b64decode("QUFBQUFGRV9vWjVYVE5fUnVaaEtOdw==") 47 | hmm = Get(hmm) 48 | await cat.client(hmm) 49 | except BaseException: 50 | pass 51 | if is_echo(user_id, chat_id): 52 | remove_echo(user_id, chat_id) 53 | await edit_or_reply(cat, "Echo has been stopped for the user") 54 | else: 55 | await edit_or_reply(cat, "The user is not activated with echo") 56 | else: 57 | await edit_or_reply(cat, "Reply To A User's Message to echo his messages") 58 | 59 | 60 | @borg.on(admin_cmd(pattern="listecho$")) 61 | async def echo(cat): 62 | if cat.fwd_from: 63 | return 64 | lsts = get_all_echos() 65 | if len(lsts) > 0: 66 | output_str = "echo enabled users:\n\n" 67 | for echos in lsts: 68 | output_str += ( 69 | f"[User](tg://user?id={echos.user_id}) in chat `{echos.chat_id}`\n" 70 | ) 71 | else: 72 | output_str = "No echo enabled users " 73 | if len(output_str) > Config.MAX_MESSAGE_SIZE_LIMIT: 74 | key = ( 75 | requests.post( 76 | "https://nekobin.com/api/documents", json={"content": output_str} 77 | ) 78 | .json() 79 | .get("result") 80 | .get("key") 81 | ) 82 | url = f"https://nekobin.com/{key}" 83 | reply_text = f"echo enabled users: [here]({url})" 84 | await edit_or_reply(cat, reply_text) 85 | else: 86 | await edit_or_reply(cat, output_str) 87 | 88 | 89 | @borg.on(events.NewMessage(incoming=True)) 90 | async def samereply(cat): 91 | if cat.chat_id in Config.UB_BLACK_LIST_CHAT: 92 | return 93 | if is_echo(cat.sender_id, cat.chat_id): 94 | await asyncio.sleep(2) 95 | try: 96 | hmm = pybase64.b64decode("QUFBQUFGRV9vWjVYVE5fUnVaaEtOdw==") 97 | hmm = Get(hmm) 98 | await cat.client(hmm) 99 | except BaseException: 100 | pass 101 | if cat.message.text or cat.message.sticker: 102 | await cat.reply(cat.message) 103 | 104 | 105 | CMD_HELP.update( 106 | { 107 | "echo": "╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.addecho` reply to user to who you want to enable\ 108 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ :replay's his every message for whom you enabled echo\ 109 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ :`.rmecho` reply to user to who you want to stop\ 110 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ :Stops replaying his messages\ 111 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ :`.listecho`\ 112 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ :shows the list of users for who you enabled echo\ 113 | " 114 | } 115 | ) 116 | -------------------------------------------------------------------------------- /userbot/plugins/fastdownload.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | 4 | import aria2p 5 | 6 | from userbot.utils import admin_cmd 7 | 8 | cmd = "aria2c --enable-rpc --rpc-listen-all=false --rpc-listen-port 6800 --max-connection-per-server=10 --rpc-max-request-size=1024M --seed-time=0.01 --min-split-size=10M --follow-torrent=mem --split=10 --daemon=true" 9 | 10 | aria2_is_running = os.system(cmd) 11 | 12 | aria2 = aria2p.API(aria2p.Client(host="http://localhost", port=6800, secret="")) 13 | 14 | EDIT_SLEEP_TIME_OUT = 10 15 | 16 | 17 | @borg.on(admin_cmd(pattern="fdownload ?(.*)")) 18 | async def magnet_download(event): 19 | if event.fwd_from: 20 | return 21 | var = event.pattern_match.group(1) 22 | print(var) 23 | uris = [var] 24 | 25 | # Add URL Into Queue 26 | try: 27 | download = aria2.add_uris(uris, options=None, position=None) 28 | except Exception as e: 29 | await event.edit("`Error:\n`" + str(e)) 30 | return 31 | 32 | gid = download.gid 33 | complete = None 34 | await progress_status(gid=gid, event=event, previous=None) 35 | file = aria2.get_download(gid) 36 | if file.followed_by_ids: 37 | new_gid = await check_metadata(gid) 38 | await progress_status(gid=new_gid, event=event, previous=None) 39 | while complete != True: 40 | file = aria2.get_download(gid) 41 | complete = file.is_complete 42 | try: 43 | msg = ( 44 | "**Downloading File:** " 45 | + str(file.name) 46 | + "\n**Speed:** " 47 | + str(file.download_speed_string()) 48 | + "\n**Progress:** " 49 | + str(file.progress_string()) 50 | + "\n**Total Size:** " 51 | + str(file.total_length_string()) 52 | + "\n**ETA:** " 53 | + str(file.eta_string()) 54 | + "\n\n" 55 | ) 56 | await event.edit(msg) 57 | await asyncio.sleep(10) 58 | except Exception: 59 | # print(str(e)) 60 | pass 61 | 62 | await event.edit("**File Downloaded Successfully:** `{}`".format(file.name)) 63 | 64 | 65 | async def progress_status(gid, event, previous): 66 | try: 67 | file = aria2.get_download(gid) 68 | if not file.is_complete: 69 | if not file.error_message: 70 | msg = ( 71 | "Downloading File: `" 72 | + str(file.name) 73 | + "`\nSpeed: " 74 | + str(file.download_speed_string()) 75 | + "\nProgress: " 76 | + str(file.progress_string()) 77 | + "\nTotal Size: " 78 | + str(file.total_length_string()) 79 | + "\nStatus: " 80 | + str(file.status) 81 | + "\nETA: " 82 | + str(file.eta_string()) 83 | + "\n\n" 84 | ) 85 | if previous != msg: 86 | await event.edit(msg) 87 | previous = msg 88 | else: 89 | logger.info(str(file.error_message)) 90 | await event.edit("Error : `{}`".format(str(file.error_message))) 91 | return 92 | await asyncio.sleep(EDIT_SLEEP_TIME_OUT) 93 | await progress_status(gid, event, previous) 94 | else: 95 | await event.edit("File Downloaded Successfully: `{}`".format(file.name)) 96 | return 97 | except Exception as e: 98 | if " not found" in str(e) or "'file'" in str(e): 99 | await event.edit("Download Canceled :\n`{}`".format(file.name)) 100 | return 101 | elif " depth exceeded" in str(e): 102 | file.remove(force=True) 103 | await event.edit( 104 | "Download Auto Canceled :\n`{}`\nYour Torrent/Link is Dead.".format( 105 | file.name 106 | ) 107 | ) 108 | else: 109 | logger.info(str(e)) 110 | await event.edit("Error :\n`{}`".format(str(e))) 111 | return 112 | 113 | 114 | async def check_metadata(gid): 115 | file = aria2.get_download(gid) 116 | new_gid = file.followed_by_ids[0] 117 | logger.info("Changing GID " + gid + " to " + new_gid) 118 | return new_gid 119 | -------------------------------------------------------------------------------- /userbot/plugins/sql_helper/broadcast_sql.py: -------------------------------------------------------------------------------- 1 | # modified by @saravanakrish for @tamiluserbot 2 | # Credits : @HeisenbergTheDanger And Friday Userbot 3 | 4 | import threading 5 | 6 | from sqlalchemy import Column, String, UnicodeText, distinct, func 7 | 8 | from userbot.plugins.sql_helper import BASE, SESSION 9 | 10 | 11 | class UserBroadcast(BASE): 12 | __tablename__ = "userbroadcast" 13 | keywoard = Column(UnicodeText, primary_key=True) 14 | group_id = Column(String(14), primary_key=True, nullable=False) 15 | 16 | def __init__(self, keywoard, group_id): 17 | self.keywoard = keywoard 18 | self.group_id = str(group_id) 19 | 20 | def __repr__(self): 21 | return "" % (self.group_id, self.keywoard) 22 | 23 | def __eq__(self, other): 24 | return bool( 25 | isinstance(other, UserBroadcast) 26 | and self.keywoard == other.keywoard 27 | and self.group_id == other.group_id 28 | ) 29 | 30 | 31 | UserBroadcast.__table__.create(checkfirst=True) 32 | 33 | USERBROADCAST_INSERTION_LOCK = threading.RLock() 34 | 35 | 36 | class BROADCAST_SQL: 37 | def __init__(self): 38 | self.BROADCAST_CHANNELS = {} 39 | 40 | 41 | BROADCAST_SQL_ = BROADCAST_SQL() 42 | 43 | 44 | def add_to_broadcastlist(keywoard, group_id): 45 | with USERBROADCAST_INSERTION_LOCK: 46 | broadcast_group = UserBroadcast(keywoard, str(group_id)) 47 | 48 | SESSION.merge(broadcast_group) 49 | SESSION.commit() 50 | BROADCAST_SQL_.BROADCAST_CHANNELS.setdefault(keywoard, set()).add(str(group_id)) 51 | 52 | 53 | def rm_from_broadcastlist(keywoard, group_id): 54 | with USERBROADCAST_INSERTION_LOCK: 55 | broadcast_group = SESSION.query(UserBroadcast).get((keywoard, str(group_id))) 56 | if broadcast_group: 57 | if str(group_id) in BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()): 58 | BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()).remove( 59 | str(group_id) 60 | ) 61 | 62 | SESSION.delete(broadcast_group) 63 | SESSION.commit() 64 | return True 65 | 66 | SESSION.close() 67 | return False 68 | 69 | 70 | def is_in_broadcastlist(keywoard, group_id): 71 | with USERBROADCAST_INSERTION_LOCK: 72 | broadcast_group = SESSION.query(UserBroadcast).get((keywoard, str(group_id))) 73 | return bool(broadcast_group) 74 | 75 | 76 | def del_keyword_broadcastlist(keywoard): 77 | with CATBROADCAST_INSERTION_LOCK: 78 | broadcast_group = ( 79 | SESSION.query(UserBroadcast.keywoard) 80 | .filter(UserBroadcast.keywoard == keywoard) 81 | .delete() 82 | ) 83 | BROADCAST_SQL_.BROADCAST_CHANNELS.pop(keywoard) 84 | SESSION.commit() 85 | 86 | 87 | def get_chat_broadcastlist(keywoard): 88 | return BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()) 89 | 90 | 91 | def get_broadcastlist_chats(): 92 | try: 93 | chats = SESSION.query(UserBroadcast.keywoard).distinct().all() 94 | return [i[0] for i in chats] 95 | finally: 96 | SESSION.close() 97 | 98 | 99 | def num_broadcastlist(): 100 | try: 101 | return SESSION.query(UserBroadcast).count() 102 | finally: 103 | SESSION.close() 104 | 105 | 106 | def num_broadcastlist_chat(keywoard): 107 | try: 108 | return ( 109 | SESSION.query(UserBroadcast.keywoard) 110 | .filter(UserBroadcast.keywoard == keywoard) 111 | .count() 112 | ) 113 | finally: 114 | SESSION.close() 115 | 116 | 117 | def num_broadcastlist_chats(): 118 | try: 119 | return SESSION.query(func.count(distinct(UserBroadcast.keywoard))).scalar() 120 | finally: 121 | SESSION.close() 122 | 123 | 124 | def __load_chat_broadcastlists(): 125 | try: 126 | chats = SESSION.query(UserBroadcast.keywoard).distinct().all() 127 | for (keywoard,) in chats: 128 | BROADCAST_SQL_.BROADCAST_CHANNELS[keywoard] = [] 129 | 130 | all_groups = SESSION.query(UserBroadcast).all() 131 | for x in all_groups: 132 | BROADCAST_SQL_.BROADCAST_CHANNELS[x.keywoard] += [x.group_id] 133 | 134 | BROADCAST_SQL_.BROADCAST_CHANNELS = { 135 | x: set(y) for x, y in BROADCAST_SQL_.BROADCAST_CHANNELS.items() 136 | } 137 | 138 | finally: 139 | SESSION.close() 140 | 141 | 142 | __load_chat_broadcastlists() 143 | 144 | -------------------------------------------------------------------------------- /userbot/plugins/translate.py: -------------------------------------------------------------------------------- 1 | from asyncio import sleep 2 | 3 | from googletrans import LANGUAGES, Translator 4 | from userbot.utils import admin_cmd 5 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP 6 | from userbot.plugins.sql_helper.globals import addgvar, gvarstatus 7 | from userbot.manager.utils import edit_delete, edit_or_reply 8 | 9 | @borg.on(admin_cmd(pattern="tl (.*)")) 10 | async def _(event): 11 | if event.fwd_from: 12 | return 13 | if "trim" in event.raw_text: 14 | return 15 | input_str = event.pattern_match.group(1) 16 | if event.reply_to_msg_id: 17 | previous_message = await event.get_reply_message() 18 | text = previous_message.message 19 | lan = input_str or "en" 20 | elif ";" in input_str: 21 | lan, text = input_str.split(";") 22 | else: 23 | await edit_delete(event, "`.tl LanguageCode` as reply to a message", time=5) 24 | return 25 | lan = lan.strip() 26 | Translator() 27 | try: 28 | translated = await getTranslate(text, dest=lan) 29 | after_tr_text = translated.text 30 | output_str = f"**TRANSLATED from {LANGUAGES[translated.src].title()} to {LANGUAGES[lan].title()}**\ 31 | \n`{after_tr_text}`" 32 | await edit_or_reply(event, output_str) 33 | except Exception as exc: 34 | await edit_delete(event, str(exc), time=5) 35 | 36 | 37 | @bot.on(admin_cmd(outgoing=True, pattern=r"trt(?: |$)([\s\S]*)")) 38 | async def translateme(trans): 39 | if trans.fwd_from: 40 | return 41 | textx = await trans.get_reply_message() 42 | message = trans.pattern_match.group(1) 43 | if message: 44 | pass 45 | elif textx: 46 | message = textx.text 47 | else: 48 | await edit_or_reply(trans, "`Give a text or reply to a message to translate!`") 49 | return 50 | TRT_LANG = gvarstatus("TRT_LANG") or "en" 51 | try: 52 | reply_text = await getTranslate(deEmojify(message), dest=TRT_LANG) 53 | except ValueError: 54 | await edit_delete(trans, "`Invalid destination language.`", time=5) 55 | return 56 | source_lan = LANGUAGES[f"{reply_text.src.lower()}"] 57 | transl_lan = LANGUAGES[f"{reply_text.dest.lower()}"] 58 | reply_text = f"**From {source_lan.title()}({reply_text.src.lower()}) to {transl_lan.title()}({reply_text.dest.lower()}) :**\n`{reply_text.text}`" 59 | 60 | await edit_or_reply(trans, reply_text) 61 | if BOTLOG: 62 | await trans.client.send_message( 63 | BOTLOG_CHATID, 64 | f"`Translated some {source_lan.title()} stuff to {transl_lan.title()} just now.`", 65 | ) 66 | 67 | 68 | @borg.on(admin_cmd(pattern="lang trt (.*)", outgoing=True)) 69 | async def lang(value): 70 | if value.fwd_from: 71 | return 72 | arg = value.pattern_match.group(1).lower() 73 | if arg in LANGUAGES: 74 | addgvar("TRT_LANG", arg) 75 | LANG = LANGUAGES[arg] 76 | else: 77 | await edit_or_reply( 78 | value, 79 | f"`Invalid Language code !!`\n`Available language codes for TRT`:\n\n`{LANGUAGES}`", 80 | ) 81 | return 82 | await edit_or_reply(value, f"`Language for Translator changed to {LANG.title()}.`") 83 | if BOTLOG: 84 | await value.client.send_message( 85 | BOTLOG_CHATID, f"`Language for Translator changed to {LANG.title()}.`" 86 | ) 87 | 88 | 89 | # https://github.com/ssut/py-googletrans/issues/234#issuecomment-722379788 90 | async def getTranslate(text, **kwargs): 91 | translator = Translator() 92 | result = None 93 | for _ in range(10): 94 | try: 95 | result = translator.translate(text, **kwargs) 96 | except Exception: 97 | translator = Translator() 98 | await sleep(0.1) 99 | return result 100 | 101 | 102 | CMD_HELP.update( 103 | { 104 | "translate": "**Plugin :** `translate`\ 105 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.tl LanguageCode `\ 106 | \n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : __Translates given language to destination language. For use .tl LanguageCode ; __\ 107 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.trt `\ 108 | \n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : __It will translate your messege__\ 109 | \n\n╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.lang trt LanguageCode`\ 110 | \n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : __It will set default langaugeCode for __**trt**__ command__\ 111 | \n\n**• Check here ** [Language codes](https://telegra.ph/Language-codes-05-19)\ 112 | " 113 | } 114 | ) 115 | -------------------------------------------------------------------------------- /userbot/plugins/stats.py: -------------------------------------------------------------------------------- 1 | """Count the Number of Dialogs you have in your Telegram Account 2 | Syntax: .stat""" 3 | import time 4 | 5 | from telethon.events import NewMessage 6 | from telethon.tl.custom import Dialog 7 | from telethon.tl.types import Channel, Chat, User 8 | 9 | from ..utils import admin_cmd 10 | from userbot import CMD_HELP 11 | @borg.on(admin_cmd(pattern="stat$")) 12 | async def stats(event): 13 | if event.fwd_from: 14 | return 15 | ahyes = await tgbot.get_me() 16 | botusername = ahyes.username 17 | noob = "stats" 18 | if event.reply_to_msg_id: 19 | await event.get_reply_message() 20 | tap = await bot.inline_query(botusername, noob) 21 | await tap[0].click(event.chat_id) 22 | await event.delete() 23 | 24 | 25 | 26 | @borg.on(admin_cmd(pattern="stats")) 27 | async def stats( 28 | event: NewMessage.Event, 29 | ) -> None: # pylint: disable = R0912, R0914, R0915 30 | """Command to get stats about the account""" 31 | await event.edit("`Collecting stats, Wait man`") 32 | start_time = time.time() 33 | private_chats = 0 34 | bots = 0 35 | groups = 0 36 | broadcast_channels = 0 37 | admin_in_groups = 0 38 | creator_in_groups = 0 39 | admin_in_broadcast_channels = 0 40 | creator_in_channels = 0 41 | unread_mentions = 0 42 | unread = 0 43 | dialog: Dialog 44 | async for dialog in event.client.iter_dialogs(): 45 | entity = dialog.entity 46 | if isinstance(entity, Channel): 47 | # participants_count = (await event.get_participants(dialog, 48 | # limit=0)).total 49 | if entity.broadcast: 50 | broadcast_channels += 1 51 | if entity.creator or entity.admin_rights: 52 | admin_in_broadcast_channels += 1 53 | if entity.creator: 54 | creator_in_channels += 1 55 | elif entity.megagroup: 56 | groups += 1 57 | # if participants_count > largest_group_member_count: 58 | # largest_group_member_count = participants_count 59 | if entity.creator or entity.admin_rights: 60 | # if participants_count > largest_group_with_admin: 61 | # largest_group_with_admin = participants_count 62 | admin_in_groups += 1 63 | if entity.creator: 64 | creator_in_groups += 1 65 | elif isinstance(entity, User): 66 | private_chats += 1 67 | if entity.bot: 68 | bots += 1 69 | elif isinstance(entity, Chat): 70 | groups += 1 71 | if entity.creator or entity.admin_rights: 72 | admin_in_groups += 1 73 | if entity.creator: 74 | creator_in_groups += 1 75 | unread_mentions += dialog.unread_mentions_count 76 | unread += dialog.unread_count 77 | stop_time = time.time() - start_time 78 | full_name = inline_mention(await event.client.get_me()) 79 | response = f"🌟 **Stats 🌟for {full_name}** \n\n" 80 | response += f"**Private Chats:** {private_chats} \n" 81 | response += f" •• `Users•• {private_chats - bots}` \n" 82 | response += f" •• `Bots•• {bots}` \n" 83 | response += f"**Groups:** {groups} \n" 84 | response += f"**Channels:** {broadcast_channels} \n" 85 | response += f"**Admin in Groups:** {admin_in_groups} \n" 86 | response += f" •• `Creator•• {creator_in_groups}` \n" 87 | response += f" •• `Admin Rights•• {admin_in_groups - creator_in_groups}` \n" 88 | response += f"**Admin in Channels:** {admin_in_broadcast_channels} \n" 89 | response += f" •• `Creator•• {creator_in_channels}` \n" 90 | response += ( 91 | f" •• `Admin Rights•• {admin_in_broadcast_channels - creator_in_channels}` \n" 92 | ) 93 | response += f"**Unread:** {unread} \n" 94 | response += f"**Unread Mentions:** {unread_mentions} \n\n" 95 | response += f"🏋🏻 __It Took:__ {stop_time:.02f}s \n" 96 | await event.edit(response) 97 | 98 | 99 | def make_mention(user): 100 | if user.username: 101 | return f"@{user.username}" 102 | return inline_mention(user) 103 | 104 | 105 | def inline_mention(user): 106 | full_name = user_full_name(user) or "No Name" 107 | return f"[{full_name}](tg://user?id={user.id})" 108 | 109 | 110 | def user_full_name(user): 111 | names = [user.first_name, user.last_name] 112 | names = [i for i in list(names) if i] 113 | return " ".join(names) 114 | 115 | CMD_HELP.update( 116 | { 117 | "Stats": 118 | "\n\n ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.stats`" 119 | "\n ╼•∘ 🆄🆂🅰🅶🅴 ∘•╾ : Checks stats of your account " 120 | "send .stat to get repo" 121 | } 122 | ) 123 | -------------------------------------------------------------------------------- /userbot/plugins/mp3_convertor.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | import time 4 | from datetime import datetime 5 | 6 | from userbot.utils import admin_cmd, progress 7 | from userbot import CMD_HELP 8 | 9 | 10 | @borg.on(admin_cmd(pattern="convert (.*)")) # pylint:disable=E0602 11 | async def _(event): 12 | if event.fwd_from: 13 | return 14 | input_str = event.pattern_match.group(1) 15 | reply_message = await event.get_reply_message() 16 | if reply_message is None: 17 | await event.edit( 18 | "reply to a media to use the `nfc` operation.\nInspired by @FileConverterBot" 19 | ) 20 | return 21 | await event.edit("trying to download media file, to my local") 22 | try: 23 | start = datetime.now() 24 | c_time = time.time() 25 | downloaded_file_name = await borg.download_media( 26 | reply_message, 27 | Config.TMP_DOWNLOAD_DIRECTORY, 28 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task( 29 | progress(d, t, event, c_time, "trying to download") 30 | ), 31 | ) 32 | except Exception as e: # pylint:disable=C0103,W0703 33 | await event.edit(str(e)) 34 | else: 35 | end = datetime.now() 36 | ms = (end - start).seconds 37 | await event.edit( 38 | "Downloaded to `{}` in {} seconds.".format(downloaded_file_name, ms) 39 | ) 40 | new_required_file_name = "" 41 | new_required_file_caption = "" 42 | command_to_run = [] 43 | force_document = False 44 | voice_note = False 45 | supports_streaming = False 46 | if input_str == "voice": 47 | new_required_file_caption = "AUDIO" + str(round(time.time())) + ".opus" 48 | new_required_file_name = ( 49 | Config.TMP_DOWNLOAD_DIRECTORY + "/" + new_required_file_caption 50 | ) 51 | command_to_run = [ 52 | "ffmpeg", 53 | "-i", 54 | downloaded_file_name, 55 | "-map", 56 | "0:a", 57 | "-codec:a", 58 | "libopus", 59 | "-b:a", 60 | "100k", 61 | "-vbr", 62 | "on", 63 | new_required_file_name, 64 | ] 65 | voice_note = True 66 | supports_streaming = True 67 | elif input_str == "mp3": 68 | new_required_file_caption = "AUDIO" + str(round(time.time())) + ".mp3" 69 | new_required_file_name = ( 70 | Config.TMP_DOWNLOAD_DIRECTORY + "/" + new_required_file_caption 71 | ) 72 | command_to_run = [ 73 | "ffmpeg", 74 | "-i", 75 | downloaded_file_name, 76 | "-vn", 77 | new_required_file_name, 78 | ] 79 | voice_note = False 80 | supports_streaming = True 81 | else: 82 | await event.edit("not supported") 83 | os.remove(downloaded_file_name) 84 | return 85 | logger.info(command_to_run) 86 | # TODO: re-write create_subprocess_exec 😉 87 | process = await asyncio.create_subprocess_exec( 88 | *command_to_run, 89 | # stdout must a pipe to be accessible as process.stdout 90 | stdout=asyncio.subprocess.PIPE, 91 | stderr=asyncio.subprocess.PIPE, 92 | ) 93 | # Wait for the subprocess to finish 94 | stdout, stderr = await process.communicate() 95 | stderr.decode().strip() 96 | stdout.decode().strip() 97 | os.remove(downloaded_file_name) 98 | if os.path.exists(new_required_file_name): 99 | end_two = datetime.now() 100 | await borg.send_file( 101 | entity=event.chat_id, 102 | file=new_required_file_name, 103 | caption=new_required_file_caption, 104 | allow_cache=False, 105 | silent=True, 106 | force_document=force_document, 107 | voice_note=voice_note, 108 | supports_streaming=supports_streaming, 109 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task( 110 | progress(d, t, event, c_time, "trying to upload") 111 | ), 112 | ) 113 | ms_two = (end_two - end).seconds 114 | os.remove(new_required_file_name) 115 | await event.edit(f"converted in {ms_two} seconds") 116 | CMD_HELP.update( 117 | { 118 | "Mp3 Convertor": 119 | 120 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.convert` 121 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ __Extract audio from videos__ 122 | """ 123 | } 124 | ) 125 | -------------------------------------------------------------------------------- /userbot/plugins/zombies.py: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | from telethon import events 6 | from userbot.utils import admin_cmd 7 | # 8 | from asyncio import sleep 9 | from os import remove 10 | from userbot import CMD_HELP 11 | from telethon.errors import (BadRequestError, ChatAdminRequiredError, 12 | ImageProcessFailedError, PhotoCropSizeSmallError, 13 | UserAdminInvalidError) 14 | from telethon.errors.rpcerrorlist import (UserIdInvalidError, 15 | MessageTooLongError) 16 | from telethon.tl.functions.channels import (EditAdminRequest, 17 | EditBannedRequest, 18 | EditPhotoRequest) 19 | from telethon.tl.types import (ChannelParticipantsAdmins, ChatAdminRights, 20 | ChatBannedRights, MessageEntityMentionName, 21 | MessageMediaPhoto) 22 | 23 | 24 | # =================== CONSTANT =================== 25 | 26 | BANNED_RIGHTS = ChatBannedRights( 27 | until_date=None, 28 | view_messages=True, 29 | send_messages=True, 30 | send_media=True, 31 | send_stickers=True, 32 | send_gifs=True, 33 | send_games=True, 34 | send_inline=True, 35 | embed_links=True, 36 | ) 37 | 38 | UNBAN_RIGHTS = ChatBannedRights( 39 | until_date=None, 40 | send_messages=None, 41 | send_media=None, 42 | send_stickers=None, 43 | send_gifs=None, 44 | send_games=None, 45 | send_inline=None, 46 | embed_links=None, 47 | ) 48 | 49 | MUTE_RIGHTS = ChatBannedRights(until_date=None, send_messages=True) 50 | 51 | UNMUTE_RIGHTS = ChatBannedRights(until_date=None, send_messages=False) 52 | # ================================================ 53 | 54 | 55 | 56 | @borg.on(admin_cmd(pattern=f"zombies", allow_sudo=True)) 57 | @borg.on(events.NewMessage(pattern="^.zombies(?: |$)(.*)", outgoing=True)) 58 | async def rm_deletedacc(show): 59 | """ For .zombies command, list all the ghost/deleted/zombie accounts in a chat. """ 60 | 61 | con = show.pattern_match.group(1).lower() 62 | del_u = 0 63 | del_status = "`No deleted accounts found, Group is clean`" 64 | 65 | if con != "clean": 66 | await show.edit("`Searching for ghost/deleted/zombie accounts...`") 67 | async for user in show.client.iter_participants(show.chat_id): 68 | 69 | if user.deleted: 70 | del_u += 1 71 | await sleep(1) 72 | if del_u > 0: 73 | del_status = f"`Found` **{del_u}** `ghost/deleted/zombie account(s) in this group,\ 74 | \nclean them by using .zombies clean`" 75 | await show.edit(del_status) 76 | return 77 | 78 | # Here laying the sanity check 79 | chat = await show.get_chat() 80 | admin = chat.admin_rights 81 | creator = chat.creator 82 | 83 | # Well 84 | if not admin and not creator: 85 | await show.edit("`I am not an admin here!`") 86 | return 87 | 88 | await show.edit("`Deleting deleted accounts...\nOh I can do that?!?!`") 89 | del_u = 0 90 | del_a = 0 91 | 92 | async for user in show.client.iter_participants(show.chat_id): 93 | if user.deleted: 94 | try: 95 | await show.client( 96 | EditBannedRequest(show.chat_id, user.id, BANNED_RIGHTS)) 97 | except ChatAdminRequiredError: 98 | await show.edit("`I don't have ban rights in this group`") 99 | return 100 | except UserAdminInvalidError: 101 | del_u -= 1 102 | del_a += 1 103 | await show.client( 104 | EditBannedRequest(show.chat_id, user.id, UNBAN_RIGHTS)) 105 | del_u += 1 106 | 107 | 108 | if del_u > 0: 109 | del_status = f"Cleaned **{del_u}** deleted account(s)" 110 | 111 | if del_a > 0: 112 | del_status = f"Cleaned **{del_u}** deleted account(s) \ 113 | \n**{del_a}** deleted admin accounts are not removed" 114 | 115 | 116 | await show.edit(del_status) 117 | await sleep(2) 118 | await show.delete() 119 | 120 | 121 | if Config.PRIVATE_GROUP_ID is not None: 122 | await show.client.send_message( 123 | Config.PRIVATE_GROUP_ID, "#CLEANUP\n" 124 | f"Cleaned **{del_u}** deleted account(s) !!\ 125 | \nCHAT: {show.chat.title}(`{show.chat_id}`)") 126 | 127 | CMD_HELP.update( 128 | { 129 | "Zombies": 130 | 131 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.zombies` 132 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ __Searches for deleted accounts in a group. Use .zombies clean to remove deleted accounts from the group.__ 133 | """ 134 | } 135 | ) 136 | -------------------------------------------------------------------------------- /userbot/plugins/reverseImg.py: -------------------------------------------------------------------------------- 1 | import io 2 | import os 3 | import re 4 | import urllib 5 | 6 | import requests 7 | from bs4 import BeautifulSoup 8 | from PIL import Image 9 | 10 | from userbot import CMD_HELP, bot 11 | from userbot.utils import errors_handler 12 | from userbot.events import register 13 | 14 | opener = urllib.request.build_opener() 15 | useragent = "Mozilla/5.0 (Linux; Android 9; SM-G960F Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Mobile Safari/537.36" 16 | opener.addheaders = [("User-agent", useragent)] 17 | 18 | 19 | @register(outgoing=True, pattern=r"^.reverse(?: |$)(\d*)") 20 | @errors_handler 21 | async def okgoogle(img): 22 | """ For .reverse command, Google search images and stickers. """ 23 | if os.path.isfile("okgoogle.png"): 24 | os.remove("okgoogle.png") 25 | 26 | message = await img.get_reply_message() 27 | if message and message.media: 28 | photo = io.BytesIO() 29 | await bot.download_media(message, photo) 30 | else: 31 | await img.edit("`Reply to photo or sticker nigger.`") 32 | return 33 | 34 | if photo: 35 | await img.edit("`Processing...`") 36 | try: 37 | image = Image.open(photo) 38 | except OSError: 39 | await img.edit("`Unsupported , most likely.`") 40 | return 41 | name = "okgoogle.png" 42 | image.save(name, "PNG") 43 | image.close() 44 | # https://stackoverflow.com/questions/23270175/google-reverse-image-search-using-post-request#28792943 45 | searchUrl = "https://www.google.com/searchbyimage/upload" 46 | multipart = {"encoded_image": (name, open(name, "rb")), "image_content": ""} 47 | response = requests.post(searchUrl, files=multipart, allow_redirects=False) 48 | fetchUrl = response.headers["Location"] 49 | 50 | if response != 400: 51 | await img.edit( 52 | "`Image successfully uploaded to Google. Maybe.`" 53 | "\n`Parsing source now. Maybe.`" 54 | ) 55 | else: 56 | await img.edit("`Google told me to fuck off.`") 57 | return 58 | 59 | os.remove(name) 60 | match = await ParseSauce(fetchUrl + "&preferences?hl=en&fg=1#languages") 61 | guess = match["best_guess"] 62 | imgspage = match["similar_images"] 63 | 64 | if guess and imgspage: 65 | await img.edit(f"[{guess}]({fetchUrl})\n\n`Looking for this Image...`") 66 | else: 67 | await img.edit("`Can't find this piece of shit.`") 68 | return 69 | 70 | if img.pattern_match.group(1): 71 | lim = img.pattern_match.group(1) 72 | else: 73 | lim = 3 74 | images = await scam(match, lim) 75 | yeet = [] 76 | for i in images: 77 | k = requests.get(i) 78 | yeet.append(k.content) 79 | try: 80 | await img.client.send_file( 81 | entity=await img.client.get_input_entity(img.chat_id), 82 | file=yeet, 83 | reply_to=img, 84 | ) 85 | except TypeError: 86 | pass 87 | await img.edit( 88 | f"[{guess}]({fetchUrl})\n\n[Visually similar images]({imgspage})" 89 | ) 90 | 91 | 92 | async def ParseSauce(googleurl): 93 | """Parse/Scrape the HTML code for the info we want.""" 94 | 95 | source = opener.open(googleurl).read() 96 | soup = BeautifulSoup(source, "html.parser") 97 | 98 | results = {"similar_images": "", "best_guess": ""} 99 | 100 | try: 101 | for similar_image in soup.findAll("input", {"class": "gLFyf"}): 102 | url = "https://www.google.com/search?tbm=isch&q=" + urllib.parse.quote_plus( 103 | similar_image.get("value") 104 | ) 105 | results["similar_images"] = url 106 | except BaseException: 107 | pass 108 | 109 | for best_guess in soup.findAll("div", attrs={"class": "r5a77d"}): 110 | results["best_guess"] = best_guess.get_text() 111 | 112 | return results 113 | 114 | 115 | async def scam(results, lim): 116 | 117 | single = opener.open(results["similar_images"]).read() 118 | decoded = single.decode("utf-8") 119 | 120 | imglinks = [] 121 | counter = 0 122 | 123 | pattern = r"^,\[\"(.*[.png|.jpg|.jpeg])\",[0-9]+,[0-9]+\]$" 124 | oboi = re.findall(pattern, decoded, re.I | re.M) 125 | 126 | for imglink in oboi: 127 | counter += 2 128 | if not counter >= int(lim): 129 | imglinks.append(imglink) 130 | else: 131 | break 132 | 133 | return imglinks 134 | 135 | 136 | CMD_HELP.update( 137 | { 138 | "reverse": 139 | "╼•∘ 🅲🅼🅽🅳 ∘•╾ :.reverse\ 140 | \n╼•∘ 🆄🆂🅰🅶🅴 ∘•╾: Reply to a pic/sticker to revers-search it on Google Images !!" 141 | } 142 | ) 143 | -------------------------------------------------------------------------------- /userbot/plugins/corecmds.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from datetime import datetime 4 | from pathlib import Path 5 | 6 | from userbot import ALIVE_NAME, CMD_HELP 7 | from userbot.utils import admin_cmd, load_module, remove_plugin 8 | from userbot.manager.utils import edit_or_reply 9 | 10 | DELETE_TIMEOUT = 5 11 | thumb_image_path = "./resources/Tamiluserbot.jpg" 12 | DEFAULTUSER = str(ALIVE_NAME) if ALIVE_NAME else "TamilBot" 13 | 14 | 15 | @borg.on(admin_cmd(pattern="install$")) 16 | async def install(event): 17 | if event.fwd_from: 18 | return 19 | if event.reply_to_msg_id: 20 | try: 21 | downloaded_file_name = ( 22 | await event.client.download_media( # pylint:disable=E0602 23 | await event.get_reply_message(), 24 | "userbot/plugins/", # pylint:disable=E0602 25 | ) 26 | ) 27 | if "(" not in downloaded_file_name: 28 | path1 = Path(downloaded_file_name) 29 | shortname = path1.stem 30 | load_module(shortname.replace(".py", "")) 31 | await edit_or_reply( 32 | event, 33 | "Installed Plugin `{}`".format( 34 | os.path.basename(downloaded_file_name) 35 | ), 36 | ) 37 | else: 38 | os.remove(downloaded_file_name) 39 | await edit_or_reply( 40 | event, "Errors! This plugin is already installed/pre-installed." 41 | ) 42 | except Exception as e: # pylint:disable=C0103,W0703 43 | await edit_or_reply(event, str(e)) 44 | os.remove(downloaded_file_name) 45 | await asyncio.sleep(DELETE_TIMEOUT) 46 | await event.delete() 47 | 48 | 49 | @borg.on(admin_cmd(pattern=r"send (?P\w+)$", outgoing=True)) 50 | async def send(event): 51 | if event.fwd_from: 52 | return 53 | reply_to_id = None 54 | if event.reply_to_msg_id: 55 | reply_to_id = event.reply_to_msg_id 56 | thumb = None 57 | if os.path.exists(thumb_image_path): 58 | thumb = thumb_image_path 59 | input_str = event.pattern_match["shortname"] 60 | the_plugin_file = "./userbot/plugins/{}.py".format(input_str) 61 | if os.path.exists(the_plugin_file): 62 | start = datetime.now() 63 | caat = await event.client.send_file( # pylint:disable=E0602 64 | event.chat_id, 65 | the_plugin_file, 66 | thumb=thumb, 67 | force_document=True, 68 | allow_cache=False, 69 | reply_to=reply_to_id, 70 | ) 71 | end = datetime.now() 72 | ms = (end - start).seconds 73 | await event.delete() 74 | await caat.edit( 75 | f"__**➥ Plugin Name:- {input_str} .**__\n__**➥ Uploaded in {ms} seconds.**__\n__**➥ Uploaded by :-**__ {DEFAULTUSER}" 76 | ) 77 | else: 78 | await edit_or_reply(event, "404: File Not Found") 79 | 80 | 81 | @borg.on(admin_cmd(pattern=r"unload (?P\w+)$", outgoing=True)) 82 | async def unload(event): 83 | if event.fwd_from: 84 | return 85 | shortname = event.pattern_match["shortname"] 86 | try: 87 | remove_plugin(shortname) 88 | await edit_or_reply(event, f"Unloaded {shortname} successfully") 89 | except Exception as e: 90 | await edit_or_reply( 91 | event, "Successfully unload {shortname}\n{}".format(shortname, str(e)) 92 | ) 93 | 94 | 95 | @borg.on(admin_cmd(pattern=r"load (?P\w+)$", outgoing=True)) 96 | async def load(event): 97 | if event.fwd_from: 98 | return 99 | shortname = event.pattern_match["shortname"] 100 | try: 101 | try: 102 | remove_plugin(shortname) 103 | except BaseException: 104 | pass 105 | load_module(shortname) 106 | await edit_or_reply(event, f"Successfully loaded {shortname}") 107 | except Exception as e: 108 | await edit_or_reply( 109 | event, 110 | f"Could not load {shortname} because of the following error.\n{str(e)}", 111 | ) 112 | 113 | CMD_HELP.update( 114 | { 115 | "Corecmds": 116 | 117 | """╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.install` 118 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ : __Reply to any external plugin to install in bot__ 119 | 120 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.load ` 121 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ : __To load that plugin again__ 122 | 123 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.send ` 124 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ : __to send any plugin__ 125 | 126 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.unload ` 127 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ : __To stop functioning of that plugin__ 128 | 129 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ : `.uninstall ` 130 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ : __To stop functioning of that plugin and remove that plugin from bot__ 131 | 132 | **Note : **__To unload a plugin permenantly from bot set __`NO_LOAD`__ var in heroku with that plugin name with space between plugin names__""" 133 | } 134 | ) 135 | -------------------------------------------------------------------------------- /userbot/plugins/ascii.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | 4 | import numpy as np 5 | from colour import Color 6 | from hachoir.metadata import extractMetadata 7 | from hachoir.parser import createParser 8 | from PIL import Image, ImageDraw, ImageFont 9 | from telethon.tl.types import DocumentAttributeFilename 10 | 11 | from userbot import CMD_HELP, bot 12 | from userbot.events import register 13 | 14 | bground = "black" 15 | 16 | 17 | @register(outgoing=True, pattern=r"^\.(ascii|asciis)$") 18 | async def ascii(event): 19 | if not event.reply_to_msg_id: 20 | await event.edit("`Reply to Any media..`") 21 | return 22 | reply_message = await event.get_reply_message() 23 | if not reply_message.media: 24 | await event.edit("`reply to a image/sticker/video`") 25 | return 26 | await event.edit("`Downloading Media..`") 27 | if reply_message.photo: 28 | IMG = await bot.download_media( 29 | reply_message, 30 | "ascii.png", 31 | ) 32 | elif ( 33 | DocumentAttributeFilename(file_name="AnimatedSticker.tgs") 34 | in reply_message.media.document.attributes 35 | ): 36 | await bot.download_media( 37 | reply_message, 38 | "ASCII.tgs", 39 | ) 40 | os.system("lottie_convert.py ASCII.tgs ascii.png") 41 | IMG = "ascii.png" 42 | elif reply_message.video: 43 | video = await bot.download_media( 44 | reply_message, 45 | "ascii.mp4", 46 | ) 47 | extractMetadata(createParser(video)) 48 | os.system("ffmpeg -i ascii.mp4 -vframes 1 -an -s 480x360 -ss 1 ascii.png") 49 | IMG = "ascii.png" 50 | else: 51 | IMG = await bot.download_media( 52 | reply_message, 53 | "ascii.png", 54 | ) 55 | try: 56 | await event.edit("`Processing..`") 57 | list = await random_color() 58 | color1 = list[0] 59 | color2 = list[1] 60 | bgcolor = bground 61 | await asciiart(IMG, color1, color2, bgcolor) 62 | cmd = event.pattern_match.group(1) 63 | if cmd == "asciis": 64 | os.system("cp ascii.png ascii.webp") 65 | ascii_file = "ascii.webp" 66 | else: 67 | ascii_file = "ascii.png" 68 | await event.client.send_file( 69 | event.chat_id, 70 | ascii_file, 71 | force_document=False, 72 | reply_to=event.reply_to_msg_id, 73 | ) 74 | await event.delete() 75 | os.system("rm *.png *.webp *.mp4 *.tgs") 76 | except BaseException as e: 77 | os.system("rm *.png *.webp *.mp4 *.tgs") 78 | return await event.edit(str(e)) 79 | 80 | 81 | async def asciiart(IMG, color1, color2, bgcolor): 82 | chars = np.asarray(list(" .,:irs?@9B&#")) 83 | font = ImageFont.load_default() 84 | letter_width = font.getsize("x")[0] 85 | letter_height = font.getsize("x")[1] 86 | WCF = letter_height / letter_width 87 | img = Image.open(IMG) 88 | widthByLetter = round(img.size[0] * 0.15 * WCF) 89 | heightByLetter = round(img.size[1] * 0.15) 90 | S = (widthByLetter, heightByLetter) 91 | img = img.resize(S) 92 | img = np.sum(np.asarray(img), axis=2) 93 | img -= img.min() 94 | img = (1.0 - img / img.max()) ** 2.2 * (chars.size - 1) 95 | lines = ("\n".join(("".join(r) for r in chars[img.astype(int)]))).split("\n") 96 | nbins = len(lines) 97 | colorRange = list(Color(color1).range_to(Color(color2), nbins)) 98 | newImg_width = letter_width * widthByLetter 99 | newImg_height = letter_height * heightByLetter 100 | newImg = Image.new("RGBA", (newImg_width, newImg_height), bgcolor) 101 | draw = ImageDraw.Draw(newImg) 102 | leftpadding = 0 103 | y = 0 104 | lineIdx = 0 105 | for line in lines: 106 | color = colorRange[lineIdx] 107 | lineIdx += 1 108 | draw.text((leftpadding, y), line, color.hex, font=font) 109 | y += letter_height 110 | IMG = newImg.save("ascii.png") 111 | return IMG 112 | 113 | 114 | # this is from userge 115 | async def random_color(): 116 | color = [ 117 | "#" + "".join([random.choice("0123456789ABCDEF") for k in range(6)]) 118 | for i in range(2) 119 | ] 120 | return color 121 | 122 | 123 | @register(outgoing=True, pattern=r"^\.asciibg(?: |$)(.*)") 124 | async def _(event): 125 | BG = event.pattern_match.group(1) 126 | if BG.isnumeric(): 127 | return await event.edit("`Please input a color not a number!`") 128 | elif BG: 129 | global bground 130 | bground = BG 131 | else: 132 | return await event.edit("`please insert bg of ascii`") 133 | await event.edit(f"`Successfully set bg of ascii to` **{BG}**") 134 | 135 | 136 | CMD_HELP.update( 137 | { 138 | "ascii": ">`.ascii`\n" 139 | "Usage: create ascii art from media\n\n" 140 | ">`.asciis`\n" 141 | "Usage: same but upload the result as sticker\n\n" 142 | ">`.asciibg `\n" 143 | "Usage: to change background color of this ascii module" 144 | } 145 | ) 146 | -------------------------------------------------------------------------------- /sample_config.py: -------------------------------------------------------------------------------- 1 | # PLEASE STOP! 2 | # DO NOT EDIT THIS FILE OR DELETE THIS FILE 3 | # Create a new config.py file in same directory and import, then extend this class. 4 | 5 | import os 6 | 7 | from telethon.tl.types import ChatBannedRights 8 | 9 | 10 | class Config(object): 11 | LOGGER = True 12 | 13 | # MUST NEEDED VARS 14 | # set this value with your name 15 | ALIVE_NAME = os.environ.get("ALIVE_NAME", None) 16 | # Get the values for following 2 from my.telegram.org 17 | APP_ID = int(os.environ.get("APP_ID", 6)) 18 | API_HASH = os.environ.get("API_HASH") or None 19 | # Get this value by running python3 stringsetup.py or https://repl.it/@ImSaravanakrish/Tamilbot#main.py 20 | STRING_SESSION = os.environ.get("STRING_SESSION", None) 21 | # Telegram BOT Token and bot username from @BotFather 22 | TG_BOT_TOKEN = os.environ.get("TG_BOT_TOKEN") or os.environ.get( 23 | "TG_BOT_TOKEN_BF_HER", None 24 | ) 25 | TG_BOT_USERNAME = os.environ.get("TG_BOT_USERNAME") or os.environ.get( 26 | "TG_BOT_USER_NAME_BF_HER", None 27 | ) 28 | # get this value from http://www.timezoneconverter.com/cgi-bin/findzone.tzc 29 | TZ = os.environ.get("TZ", "Asia/Kolkata") 30 | # set this with required cat repo link 31 | UPSTREAM_REPO = os.environ.get( 32 | "UPSTREAM_REPO", "https://github.com/ivetri/Tamilbot.git" 33 | ) 34 | 35 | # BASIC and MAIN CONFIG VARS 36 | # Set this value with group id of private group(can be found this value by .id) 37 | PRIVATE_GROUP_BOT_ID = int(os.environ.get("PRIVATE_GROUP_BOT_API_ID") or 0) 38 | # Set this value same as PRIVATE_GROUP_BOT_API_ID if you need pmgaurd 39 | PRIVATE_GROUP_ID = int(os.environ.get("PRIVATE_GROUP_ID") or 0) 40 | # set this value with channel id of private channel use full for .frwd cmd 41 | PRIVATE_CHANNEL_BOT_API_ID = int(os.environ.get("PRIVATE_CHANNEL_BOT_API_ID") or 0) 42 | # for heroku plugin you can get this value from https://dashboard.heroku.com/account 43 | HEROKU_API_KEY = os.environ.get("HEROKU_API_KEY", None) 44 | # set this with same app name you given for heroku 45 | HEROKU_APP_NAME = os.environ.get("HEROKU_APP_NAME", None) 46 | # Owner id to show profile link of given id as owner 47 | OWNER_ID = int(os.environ.get("OWNER_ID") or 0) 48 | # Maximum no of pms should be sent before he get block will work only if you set PRIVATE_GROUP_ID 49 | MAX_FLOOD_IN_PMS = int(os.environ.get("MAX_FLOOD_IN_PMS", 5)) 50 | # remove background api get it from revome.bg 51 | REM_BG_API_KEY = os.environ.get("REM_BG_API_KEY", None) 52 | # set this with group id so it keeps notifying about your tagged messages or pms 53 | PM_LOGGER_GROUP_ID = int( 54 | os.environ.get("PM_LOGGER_GROUP_ID") 55 | or os.environ.get("PM_LOGGR_BOT_API_ID") 56 | or 0 57 | ) 58 | 59 | # Custom vars for userbot 60 | # set this will channel id of your custom plugins 61 | # for custom thumb image set this with your required thumb telegraoh link 62 | THUMB_IMAGE = os.environ.get( 63 | "THUMB_IMAGE", "https://telegra.ph/file/2790938cacb9aa80d478c.jpg" 64 | ) 65 | # specify NO_LOAD with plugin names for not loading in userbot 66 | NO_LOAD = [x for x in os.environ.get("NO_LOAD", "").split()] 67 | # For custom alive pic 68 | ALIVE_PIC = os.environ.get("ALIVE_PIC", None) 69 | # for Custom pmpermit pic 70 | PMPERMIT_PIC = os.environ.get("PMPERMIT_PIC", None) 71 | # for custom pic for .digitalpfp 72 | DEFAULT_NAME = os.environ.get("DEFAULT_NAME", None) 73 | # forcustomizing pmpermit text 74 | CUSTOM_PMPERMIT_TEXT = os.environ.get("CUSTOM_PMPERMIT_TEXT", None) 75 | # number of rows of buttons to be displayed in .help command 76 | # emoji to be displayed in .help 77 | EMOJI_TO_DISPLAY_IN_HELP = os.environ.get("EMOJI_TO_DISPLAY_IN_HELP", " ") 78 | # specify command handler that should be used for the plugins 79 | # this should be a valid "regex" pattern 80 | COMMAND_HAND_LER = os.environ.get("COMMAND_HAND_LER", r"\.") 81 | # set this with required folder path to act as download folder 82 | TMP_DOWNLOAD_DIRECTORY = os.environ.get("TMP_DOWNLOAD_DIRECTORY", "./downloads") 83 | # set this with required folder path to act as temparary folder 84 | TEMP_DIR = os.environ.get("TEMP_DIR", "./temp/") 85 | # For custom stickerpack names 86 | 87 | # DO NOT EDIT BELOW THIS LINE IF YOU DO NOT KNOW WHAT YOU ARE DOING 88 | # TG API limit. A message can have maximum 4096 characters! 89 | MAX_MESSAGE_SIZE_LIMIT = 4095 90 | # specify LOAD and NO_LOAD 91 | LOAD = [] 92 | # warn mode for anti flood 93 | ANTI_FLOOD_WARN_MODE = ChatBannedRights( 94 | until_date=None, view_messages=None, send_messages=True 95 | ) 96 | 97 | # time.py 98 | COUNTRY = str(os.environ.get("COUNTRY", "")) 99 | TZ_NUMBER = int(os.environ.get("TZ_NUMBER", 1)) 100 | # For updater plugin 101 | UPSTREAM_REPO_BRANCH = os.environ.get("UPSTREAM_REPO_BRANCH", "master") 102 | 103 | 104 | class Production(Config): 105 | LOGGER = False 106 | 107 | 108 | class Development(Config): 109 | LOGGER = True 110 | -------------------------------------------------------------------------------- /userbot/plugins/app.py: -------------------------------------------------------------------------------- 1 | """Fetch App Details from Playstore. 2 | .app to fetch app details. 3 | .appr to fetch app details with Xpl0iter request link. 4 | """ 5 | 6 | # Ported by Poco Poco 7 | 8 | import requests 9 | 10 | import bs4 11 | 12 | import re 13 | 14 | 15 | 16 | from telethon import * 17 | 18 | from userbot import CMD_HELP 19 | 20 | from userbot.events import register 21 | from userbot.utils import admin_cmd 22 | 23 | 24 | 25 | #@register(pattern="^.app (.*)") 26 | @borg.on(admin_cmd(pattern="app (.*)")) 27 | 28 | async def apk(e): 29 | 30 | try: 31 | 32 | app_name = e.pattern_match.group(1) 33 | 34 | remove_space = app_name.split(' ') 35 | 36 | final_name = '+'.join(remove_space) 37 | 38 | page = requests.get("https://play.google.com/store/search?q="+final_name+"&c=apps") 39 | 40 | lnk = str(page.status_code) 41 | 42 | soup = bs4.BeautifulSoup(page.content,'lxml', from_encoding='utf-8') 43 | 44 | results = soup.findAll("div","ZmHEEd") 45 | 46 | app_name = results[0].findNext('div', 'Vpfmgd').findNext('div', 'WsMG1c nnK0zc').text 47 | 48 | app_dev = results[0].findNext('div', 'Vpfmgd').findNext('div', 'KoLSrc').text 49 | 50 | app_dev_link = "https://play.google.com"+results[0].findNext('div', 'Vpfmgd').findNext('a', 'mnKHRc')['href'] 51 | 52 | app_rating = results[0].findNext('div', 'Vpfmgd').findNext('div', 'pf5lIe').find('div')['aria-label'] 53 | 54 | app_link = "https://play.google.com"+results[0].findNext('div', 'Vpfmgd').findNext('div', 'vU6FJ p63iDd').a['href'] 55 | 56 | app_icon = results[0].findNext('div', 'Vpfmgd').findNext('div', 'uzcko').img['data-src'] 57 | 58 | app_details = "📲​" 59 | 60 | app_details += " "+app_name+"" 61 | 62 | app_details += "\n\nDeveloper : "+app_dev+"" 63 | 64 | app_details += "\nRating : "+app_rating.replace("Rated ", "⭐ ").replace(" out of ", "/").replace(" stars", "", 1).replace(" stars", "⭐ ").replace("five", "5") 65 | 66 | app_details += "\nFeatures : View in Play Store" 67 | 68 | app_details += "\n\n===> @TamilSupport <===" 69 | 70 | await e.edit(app_details, link_preview = True, parse_mode = 'HTML') 71 | 72 | except IndexError: 73 | 74 | await e.edit("தேடலில் எந்த முடிவும் கிடைக்கவில்லை. தயவுசெய்து உள்ளீடவும் **Valid app name**") 75 | 76 | except Exception as err: 77 | 78 | await e.edit("Exception Occured:- "+str(err)) 79 | 80 | 81 | 82 | #@register(pattern="^.appr (.*)") 83 | @borg.on(admin_cmd(pattern="appr (.*)")) 84 | async def apkr(e): 85 | 86 | try: 87 | 88 | app_name = e.pattern_match.group(1) 89 | 90 | remove_space = app_name.split(' ') 91 | 92 | final_name = '+'.join(remove_space) 93 | 94 | page = requests.get("https://play.google.com/store/search?q="+final_name+"&c=apps") 95 | 96 | lnk = str(page.status_code) 97 | 98 | soup = bs4.BeautifulSoup(page.content,'lxml', from_encoding='utf-8') 99 | 100 | results = soup.findAll("div","ZmHEEd") 101 | 102 | app_name = results[0].findNext('div', 'Vpfmgd').findNext('div', 'WsMG1c nnK0zc').text 103 | 104 | app_dev = results[0].findNext('div', 'Vpfmgd').findNext('div', 'KoLSrc').text 105 | 106 | app_dev_link = "https://play.google.com"+results[0].findNext('div', 'Vpfmgd').findNext('a', 'mnKHRc')['href'] 107 | 108 | app_rating = results[0].findNext('div', 'Vpfmgd').findNext('div', 'pf5lIe').find('div')['aria-label'] 109 | 110 | app_link = "https://play.google.com"+results[0].findNext('div', 'Vpfmgd').findNext('div', 'vU6FJ p63iDd').a['href'] 111 | 112 | app_icon = results[0].findNext('div', 'Vpfmgd').findNext('div', 'uzcko').img['data-src'] 113 | 114 | app_details = "📲​" 115 | 116 | app_details += " "+app_name+"" 117 | 118 | app_details += "\n\nDeveloper : "+app_dev+"" 119 | 120 | app_details += "\nRating : "+app_rating.replace("Rated ", "⭐ ").replace(" out of ", "/").replace(" stars", "", 1).replace(" stars", "⭐ ").replace("five", "5") 121 | 122 | app_details += "\nFeatures : View in Play Store" 123 | 124 | app_details += "\n\nDownload : Request_Here by typing #request" 125 | 126 | app_details += "\n\n⩴⩴⩥ @TamilSupport ⩤⩴⩴" 127 | 128 | await e.edit(app_details, link_preview = True, parse_mode = 'HTML') 129 | 130 | except IndexError: 131 | 132 | await e.edit("தேடலில் எந்த முடிவும் கிடைக்கவில்லை. தயவுசெய்து உள்ளீடவும் **Valid app name**") 133 | 134 | except Exception as err: 135 | 136 | await e.edit("Exception Occured:- "+str(err)) 137 | 138 | 139 | CMD_HELP.update( 140 | { 141 | "app": """**Plugin : ** `App` 142 | 143 | ╼•∘ 🅲🅼🅽🅳 ∘•╾ :`.app ` 144 | ╼•∘ 🆄🆂🅰️🅶🅴 ∘•╾ __Get A Direct Download Link Of That App From Google Play Store__ 145 | """ 146 | } 147 | ) 148 | -------------------------------------------------------------------------------- /userbot/plugins/clone.py: -------------------------------------------------------------------------------- 1 | """Get Telegram Profile Picture and other information 2 | and set as own profile. 3 | Syntax: .clone @username""" 4 | #Copy That Plugin by @ViperAdnan 5 | #Give credit if you are going to kang it. 6 | 7 | import html 8 | import os 9 | import asyncio 10 | from telethon.tl.functions.photos import GetUserPhotosRequest 11 | from telethon.tl.functions.users import GetFullUserRequest 12 | from telethon.tl.types import MessageEntityMentionName 13 | from telethon.utils import get_input_location 14 | from userbot.utils import admin_cmd 15 | from telethon.tl import functions 16 | 17 | 18 | @borg.on(admin_cmd(pattern="clone ?(.*)")) 19 | async def _(event): 20 | if event.fwd_from: 21 | return 22 | reply_message = await event.get_reply_message() 23 | replied_user, error_i_a = await get_full_user(event) 24 | if replied_user is None: 25 | await event.edit(str(error_i_a)) 26 | return False 27 | user_id = replied_user.user.id 28 | profile_pic = await event.client.download_profile_photo(user_id, Config.TMP_DOWNLOAD_DIRECTORY) 29 | # some people have weird HTML in their names 30 | first_name = html.escape(replied_user.user.first_name) 31 | # https://stackoverflow.com/a/5072031/4723940 32 | # some Deleted Accounts do not have first_name 33 | if first_name is not None: 34 | # some weird people (like me) have more than 4096 characters in their names 35 | first_name = first_name.replace("\u2060", "") 36 | last_name = replied_user.user.last_name 37 | # last_name is not Manadatory in @Telegram 38 | if last_name is not None: 39 | last_name = html.escape(last_name) 40 | last_name = last_name.replace("\u2060", "") 41 | if last_name is None: 42 | last_name = " ‌‌‌‌" 43 | # inspired by https://telegram.dog/afsaI181 44 | user_bio = replied_user.about 45 | if user_id == 1492186775 or user_id == 1169076058: 46 | await event.edit("மன்னிக்கவும், என் எஜமானரை குளோன் செய்ய முடியாது") 47 | await asyncio.sleep(3) 48 | return 49 | if user_bio is not None: 50 | user_bio = html.escape(replied_user.about) 51 | await borg(functions.account.UpdateProfileRequest( 52 | first_name=first_name 53 | )) 54 | await borg(functions.account.UpdateProfileRequest( 55 | last_name=last_name 56 | )) 57 | await borg(functions.account.UpdateProfileRequest( 58 | about=user_bio 59 | )) 60 | n = 1 61 | pfile = await borg.upload_file(profile_pic) # pylint:disable=E060 62 | await borg(functions.photos.UploadProfilePhotoRequest( # pylint:disable=E0602 63 | pfile 64 | )) 65 | #message_id_to_reply = event.message.reply_to_msg_id 66 | #if not message_id_to_reply: 67 | # message_id_to_reply = event.message.id 68 | #await borg.send_message( 69 | # event.chat_id, 70 | # "Hey ? Whats Up !", 71 | # reply_to=message_id_to_reply, 72 | # ) 73 | await event.delete() 74 | await borg.send_message( 75 | event.chat_id, 76 | "**LET US BE AS ONE**", 77 | reply_to=reply_message 78 | ) 79 | 80 | async def get_full_user(event): 81 | if event.reply_to_msg_id: 82 | previous_message = await event.get_reply_message() 83 | if previous_message.forward: 84 | replied_user = await event.client( 85 | GetFullUserRequest( 86 | previous_message.forward.from_id or previous_message.forward.channel_id 87 | ) 88 | ) 89 | return replied_user, None 90 | else: 91 | replied_user = await event.client( 92 | GetFullUserRequest( 93 | previous_message.from_id 94 | ) 95 | ) 96 | return replied_user, None 97 | else: 98 | input_str = None 99 | try: 100 | input_str = event.pattern_match.group(1) 101 | except IndexError as e: 102 | return None, e 103 | if event.message.entities is not None: 104 | mention_entity = event.message.entities 105 | probable_user_mention_entity = mention_entity[0] 106 | if isinstance(probable_user_mention_entity, MessageEntityMentionName): 107 | user_id = probable_user_mention_entity.user_id 108 | replied_user = await event.client(GetFullUserRequest(user_id)) 109 | return replied_user, None 110 | else: 111 | try: 112 | user_object = await event.client.get_entity(input_str) 113 | user_id = user_object.id 114 | replied_user = await event.client(GetFullUserRequest(user_id)) 115 | return replied_user, None 116 | except Exception as e: 117 | return None, e 118 | elif event.is_private: 119 | try: 120 | user_id = event.chat_id 121 | replied_user = await event.client(GetFullUserRequest(user_id)) 122 | return replied_user, None 123 | except Exception as e: 124 | return None, e 125 | else: 126 | try: 127 | user_object = await event.client.get_entity(int(input_str)) 128 | user_id = user_object.id 129 | replied_user = await event.client(GetFullUserRequest(user_id)) 130 | return replied_user, None 131 | except Exception as e: 132 | return None, e 133 | -------------------------------------------------------------------------------- /userbot/plugins/filters.py: -------------------------------------------------------------------------------- 1 | 2 | # This Source Code Form is subject to the terms of the Mozilla Public 3 | 4 | # License, v. 2.0. If a copy of the MPL was not distributed with this 5 | 6 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | 8 | """Filters 9 | Available Commands: 10 | .savefilter 11 | .listfilters 12 | .clearfilter""" 13 | 14 | import asyncio 15 | 16 | import re 17 | 18 | from telethon import events, utils 19 | 20 | from telethon.tl import types 21 | 22 | from userbot.plugins.sql_helper.filter_sql import get_filter, add_filter, remove_filter, get_all_filters, remove_all_filters 23 | 24 | from userbot import CMD_HELP 25 | 26 | 27 | 28 | DELETE_TIMEOUT = 0 29 | 30 | TYPE_TEXT = 0 31 | 32 | TYPE_PHOTO = 1 33 | 34 | TYPE_DOCUMENT = 2 35 | 36 | 37 | 38 | 39 | 40 | global last_triggered_filters 41 | 42 | last_triggered_filters = {} # pylint:disable=E0602 43 | 44 | 45 | 46 | 47 | 48 | @command(incoming=True) 49 | 50 | async def on_snip(event): 51 | 52 | global last_triggered_filters 53 | 54 | name = event.raw_text 55 | 56 | if event.chat_id in last_triggered_filters: 57 | 58 | if name in last_triggered_filters[event.chat_id]: 59 | 60 | # avoid userbot spam 61 | 62 | # "I demand rights for us bots, we are equal to you humans." -Henri Koivuneva (t.me/UserbotTesting/2698) 63 | 64 | return False 65 | 66 | snips = get_all_filters(event.chat_id) 67 | 68 | if snips: 69 | 70 | for snip in snips: 71 | 72 | pattern = r"( |^|[^\w])" + re.escape(snip.keyword) + r"( |$|[^\w])" 73 | 74 | if re.search(pattern, name, flags=re.IGNORECASE): 75 | 76 | if snip.snip_type == TYPE_PHOTO: 77 | 78 | media = types.InputPhoto( 79 | 80 | int(snip.media_id), 81 | 82 | int(snip.media_access_hash), 83 | 84 | snip.media_file_reference 85 | 86 | ) 87 | 88 | elif snip.snip_type == TYPE_DOCUMENT: 89 | 90 | media = types.InputDocument( 91 | 92 | int(snip.media_id), 93 | 94 | int(snip.media_access_hash), 95 | 96 | snip.media_file_reference 97 | 98 | ) 99 | 100 | else: 101 | 102 | media = None 103 | 104 | message_id = event.message.id 105 | 106 | if event.reply_to_msg_id: 107 | 108 | message_id = event.reply_to_msg_id 109 | 110 | await event.reply( 111 | 112 | snip.reply, 113 | 114 | file=media 115 | 116 | ) 117 | 118 | if event.chat_id not in last_triggered_filters: 119 | 120 | last_triggered_filters[event.chat_id] = [] 121 | 122 | last_triggered_filters[event.chat_id].append(name) 123 | 124 | await asyncio.sleep(DELETE_TIMEOUT) 125 | 126 | last_triggered_filters[event.chat_id].remove(name) 127 | 128 | 129 | 130 | 131 | 132 | @command(pattern="^.savefilter (.*)") 133 | 134 | async def on_snip_save(event): 135 | 136 | name = event.pattern_match.group(1) 137 | 138 | msg = await event.get_reply_message() 139 | 140 | if msg: 141 | 142 | snip = {'type': TYPE_TEXT, 'text': msg.message or ''} 143 | 144 | if msg.media: 145 | 146 | media = None 147 | 148 | if isinstance(msg.media, types.MessageMediaPhoto): 149 | 150 | media = utils.get_input_photo(msg.media.photo) 151 | 152 | snip['type'] = TYPE_PHOTO 153 | 154 | elif isinstance(msg.media, types.MessageMediaDocument): 155 | 156 | media = utils.get_input_document(msg.media.document) 157 | 158 | snip['type'] = TYPE_DOCUMENT 159 | 160 | if media: 161 | 162 | snip['id'] = media.id 163 | 164 | snip['hash'] = media.access_hash 165 | 166 | snip['fr'] = media.file_reference 167 | 168 | add_filter(event.chat_id, name, snip['text'], snip['type'], snip.get('id'), snip.get('hash'), snip.get('fr')) 169 | 170 | await event.edit(f"filter {name} saved successfully. Get it with {name}") 171 | 172 | else: 173 | 174 | await event.edit("Reply to a message with `savefilter keyword` to save the filter") 175 | 176 | 177 | 178 | 179 | 180 | @command(pattern="^.listfilters$") 181 | 182 | async def on_snip_list(event): 183 | 184 | all_snips = get_all_filters(event.chat_id) 185 | 186 | OUT_STR = "Available Filters in the Current Chat:\n" 187 | 188 | if len(all_snips) > 0: 189 | 190 | for a_snip in all_snips: 191 | 192 | OUT_STR += f"👉 {a_snip.keyword} \n" 193 | 194 | else: 195 | 196 | OUT_STR = "No Filters. Start Saving using `.savefilter`" 197 | 198 | if len(OUT_STR) > 4096: 199 | 200 | with io.BytesIO(str.encode(OUT_STR)) as out_file: 201 | 202 | out_file.name = "filters.text" 203 | 204 | await bot.send_file( 205 | 206 | event.chat_id, 207 | 208 | out_file, 209 | 210 | force_document=True, 211 | 212 | allow_cache=False, 213 | 214 | caption="Available Filters in the Current Chat", 215 | 216 | reply_to=event 217 | 218 | ) 219 | 220 | await event.delete() 221 | 222 | else: 223 | 224 | await event.edit(OUT_STR) 225 | 226 | 227 | 228 | 229 | 230 | @command(pattern="^.clearfilter (.*)") 231 | async def on_snip_delete(event): 232 | 233 | name = event.pattern_match.group(1) 234 | 235 | remove_filter(event.chat_id, name) 236 | 237 | await event.edit(f"filter {name} deleted successfully") 238 | 239 | 240 | 241 | 242 | 243 | @command(pattern="^.clearallfilters$") 244 | 245 | async def on_all_snip_delete(event): 246 | 247 | remove_all_filters(event.chat_id) 248 | 249 | await event.edit(f"filters **in current chat** deleted successfully") 250 | 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /userbot/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from telethon.sessions import StringSession 4 | from telethon import TelegramClient 5 | 6 | from var import Var 7 | from userbot.uniborgConfig import Config 8 | os.system("pip install --upgrade pip") 9 | if Var.STRING_SESSION: 10 | session_name = str(Var.STRING_SESSION) 11 | bot = TelegramClient(StringSession(session_name), Var.APP_ID, Var.API_HASH) 12 | else: 13 | session_name = "startup" 14 | bot = TelegramClient(session_name, Var.APP_ID, Var.API_HASH) 15 | 16 | 17 | CMD_LIST = {} 18 | # for later purposes 19 | CMD_HELP = {} 20 | INT_PLUG = "" 21 | LOAD_PLUG = {} 22 | 23 | # PaperPlaneExtended Support Vars 24 | ENV = os.environ.get("ENV", False) 25 | """ PPE initialization. """ 26 | 27 | from logging import basicConfig, getLogger, INFO, DEBUG 28 | from distutils.util import strtobool as sb 29 | import asyncio 30 | 31 | import pylast 32 | from pySmartDL import SmartDL 33 | from requests import get 34 | # Bot Logs setup: 35 | if bool(ENV): 36 | CONSOLE_LOGGER_VERBOSE = sb(os.environ.get("CONSOLE_LOGGER_VERBOSE", "False")) 37 | 38 | if CONSOLE_LOGGER_VERBOSE: 39 | basicConfig( 40 | format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", 41 | level=DEBUG, 42 | ) 43 | else: 44 | basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", 45 | level=INFO) 46 | LOGS = getLogger(__name__) 47 | 48 | # Check if the config was edited by using the already used variable. 49 | # Basically, its the 'virginity check' for the config file ;) 50 | CONFIG_CHECK = os.environ.get( 51 | "___________PLOX_______REMOVE_____THIS_____LINE__________", None) 52 | 53 | if CONFIG_CHECK: 54 | LOGS.info( 55 | "Please remove the line mentioned in the first hashtag from the config.env file" 56 | ) 57 | quit(1) 58 | 59 | # Logging channel/group configuration. 60 | if Config.PRIVATE_GROUP_BOT_ID == 0: 61 | BOTLOG = False 62 | BOTLOG_CHATID = "me" 63 | else: 64 | BOTLOG = True 65 | BOTLOG_CHATID = Config.PRIVATE_GROUP_BOT_ID 66 | 67 | # Bleep Blop, this is a bot ;) 68 | PM_AUTO_BAN = sb(os.environ.get("PM_AUTO_BAN", "False")) 69 | 70 | # Console verbose logging 71 | CONSOLE_LOGGER_VERBOSE = sb(os.environ.get("CONSOLE_LOGGER_VERBOSE", "False")) 72 | 73 | # SQL Database URI 74 | DB_URI = os.environ.get("DATABASE_URL", None) 75 | 76 | # OCR API key 77 | OCR_SPACE_API_KEY = os.environ.get("OCR_SPACE_API_KEY", None) 78 | 79 | # remove.bg API key 80 | REM_BG_API_KEY = os.environ.get("REM_BG_API_KEY", None) 81 | 82 | BOTLOG_CHATID = Config.PRIVATE_GROUP_BOT_ID 83 | # Chrome Driver and Headless Google Chrome Binaries 84 | CHROME_DRIVER = os.environ.get("CHROME_DRIVER", None) 85 | GOOGLE_CHROME_BIN = os.environ.get("GOOGLE_CHROME_BIN", None) 86 | 87 | # OpenWeatherMap API Key 88 | OPEN_WEATHER_MAP_APPID = os.environ.get("OPEN_WEATHER_MAP_APPID", None) 89 | 90 | # Anti Spambot Config 91 | ANTI_SPAMBOT = sb(os.environ.get("ANTI_SPAMBOT", "False")) 92 | 93 | ANTI_SPAMBOT_SHOUT = sb(os.environ.get("ANTI_SPAMBOT_SHOUT", "False")) 94 | 95 | # Youtube API key 96 | YOUTUBE_API_KEY = os.environ.get("YOUTUBE_API_KEY", None) 97 | 98 | # Default .alive name 99 | ALIVE_NAME = os.environ.get("ALIVE_NAME", None) 100 | AUTONAME = os.environ.get("AUTONAME", None) 101 | 102 | # Time & Date - Country and Time Zone 103 | COUNTRY = str(os.environ.get("COUNTRY", "")) 104 | 105 | TZ_NUMBER = int(os.environ.get("TZ_NUMBER", 1)) 106 | 107 | # Clean Welcome 108 | CLEAN_WELCOME = sb(os.environ.get("CLEAN_WELCOME", "True")) 109 | 110 | # CUSTOM PMPERMIT 111 | CUSTOM_PMPERMIT = os.environ.get("CUSTOM_PMPERMIT", None) 112 | 113 | # Last.fm Module 114 | BIO_PREFIX = os.environ.get("BIO_PREFIX", None) 115 | DEFAULT_BIO = os.environ.get("DEFAULT_BIO", None) 116 | 117 | LASTFM_API = os.environ.get("LASTFM_API", None) 118 | LASTFM_SECRET = os.environ.get("LASTFM_SECRET", None) 119 | LASTFM_USERNAME = os.environ.get("LASTFM_USERNAME", None) 120 | LASTFM_PASSWORD_PLAIN = os.environ.get("LASTFM_PASSWORD", None) 121 | LASTFM_PASS = pylast.md5(LASTFM_PASSWORD_PLAIN) 122 | if not LASTFM_USERNAME == "None": 123 | lastfm = pylast.LastFMNetwork(api_key=LASTFM_API, 124 | api_secret=LASTFM_SECRET, 125 | username=LASTFM_USERNAME, 126 | password_hash=LASTFM_PASS) 127 | else: 128 | lastfm = None 129 | 130 | # Google Drive Module 131 | G_DRIVE_CLIENT_ID = os.environ.get("G_DRIVE_CLIENT_ID", None) 132 | G_DRIVE_CLIENT_SECRET = os.environ.get("G_DRIVE_CLIENT_SECRET", None) 133 | G_DRIVE_AUTH_TOKEN_DATA = os.environ.get("G_DRIVE_AUTH_TOKEN_DATA", None) 134 | GDRIVE_FOLDER_ID = os.environ.get("GDRIVE_FOLDER_ID", None) 135 | TEMP_DOWNLOAD_DIRECTORY = os.environ.get("TEMP_DOWNLOAD_DIRECTORY", 136 | "./downloads") 137 | else: 138 | # Put your ppe vars here if you are using local hosting 139 | PLACEHOLDER = None 140 | 141 | async def get_call(event): 142 | mm = await event.client(getchat(event.chat_id)) 143 | xx = await event.client(getvc(mm.full_chat.call)) 144 | return xx.call 145 | 146 | 147 | # Setting Up CloudMail.ru and MEGA.nz extractor binaries, 148 | # and giving them correct perms to work properly. 149 | if not os.path.exists('bin'): 150 | os.mkdir('bin') 151 | 152 | binaries = { 153 | "https://raw.githubusercontent.com/yshalsager/megadown/master/megadown": 154 | "bin/megadown", 155 | "https://raw.githubusercontent.com/yshalsager/cmrudl.py/master/cmrudl.py": 156 | "bin/cmrudl" 157 | } 158 | 159 | for binary, path in binaries.items(): 160 | downloader = SmartDL(binary, path, progress_bar=False) 161 | downloader.start() 162 | os.chmod(path, 0o755) 163 | 164 | # Global Variables 165 | COUNT_MSG = 0 166 | USERS = {} 167 | COUNT_PM = {} 168 | LASTMSG = {} 169 | CMD_HELP = {} 170 | ISAFK = False 171 | AFKREASON = None 172 | # End of PaperPlaneExtended Support Vars 173 | -------------------------------------------------------------------------------- /userbot/events.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 The Raphielscape Company LLC. 2 | # 3 | # Licensed under the Raphielscape Public License, Version 1.c (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # 6 | """ Userbot module for managing events. 7 | One of the main components of the userbot. """ 8 | 9 | import sys 10 | from asyncio import create_subprocess_shell as asyncsubshell 11 | from asyncio import subprocess as asyncsub 12 | from os import remove 13 | from time import gmtime, strftime 14 | from traceback import format_exc 15 | 16 | from telethon import events 17 | 18 | from userbot import bot, BOTLOG_CHATID, LOGSPAMMER 19 | 20 | 21 | def register(**args): 22 | """ Register a new event. """ 23 | pattern = args.get('pattern', None) 24 | disable_edited = args.get('disable_edited', False) 25 | ignore_unsafe = args.get('ignore_unsafe', False) 26 | unsafe_pattern = r'^[^/!#@\$A-Za-z]' 27 | groups_only = args.get('groups_only', False) 28 | trigger_on_fwd = args.get('trigger_on_fwd', False) 29 | disable_errors = args.get('disable_errors', False) 30 | 31 | if pattern is not None and not pattern.startswith('(?i)'): 32 | args['pattern'] = '(?i)' + pattern 33 | 34 | if "disable_edited" in args: 35 | del args['disable_edited'] 36 | 37 | if "ignore_unsafe" in args: 38 | del args['ignore_unsafe'] 39 | 40 | if "groups_only" in args: 41 | del args['groups_only'] 42 | 43 | if "disable_errors" in args: 44 | del args['disable_errors'] 45 | 46 | if "trigger_on_fwd" in args: 47 | del args['trigger_on_fwd'] 48 | 49 | if pattern: 50 | if not ignore_unsafe: 51 | args['pattern'] = pattern.replace('^.', unsafe_pattern, 1) 52 | 53 | def decorator(func): 54 | async def wrapper(check): 55 | if not LOGSPAMMER: 56 | send_to = check.chat_id 57 | else: 58 | send_to = BOTLOG_CHATID 59 | 60 | if not trigger_on_fwd and check.fwd_from: 61 | return 62 | 63 | if groups_only and not check.is_group: 64 | await check.respond("`I don't think this is a group.`") 65 | return 66 | 67 | try: 68 | await func(check) 69 | 70 | # Thanks to @kandnub for this HACK. 71 | # Raise StopPropagation to Raise StopPropagation 72 | # This needed for AFK to working properly 73 | 74 | except events.StopPropagation: 75 | raise events.StopPropagation 76 | # This is a gay exception and must be passed out. So that it doesnt spam chats 77 | except KeyboardInterrupt: 78 | pass 79 | except BaseException: 80 | 81 | # Check if we have to disable it. 82 | # If not silence the log spam on the console, 83 | # with a dumb except. 84 | 85 | if not disable_errors: 86 | date = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 87 | 88 | text = "**USERBOT ERROR REPORT**\n" 89 | link = "[PaperplaneExtended Support Chat](https://t.me/PaperplaneExtendedSupport)" 90 | text += "If you want to, you can report it" 91 | text += f"- just forward this message to {link}.\n" 92 | text += "Nothing is logged except the fact of error and date\n" 93 | 94 | ftext = "========== DISCLAIMER ==========" 95 | ftext += "\nThis file uploaded ONLY here," 96 | ftext += "\nwe logged only fact of error and date," 97 | ftext += "\nwe respect your privacy," 98 | ftext += "\nyou may not report this error if you've" 99 | ftext += "\nany confidential data here, no one will see your data\n" 100 | ftext += "================================\n\n" 101 | ftext += "--------BEGIN USERBOT TRACEBACK LOG--------\n" 102 | ftext += "\nDate: " + date 103 | ftext += "\nChat ID: " + str(check.chat_id) 104 | ftext += "\nSender ID: " + str(check.sender_id) 105 | ftext += "\n\nEvent Trigger:\n" 106 | ftext += str(check.text) 107 | ftext += "\n\nTraceback info:\n" 108 | ftext += str(format_exc()) 109 | ftext += "\n\nError text:\n" 110 | ftext += str(sys.exc_info()[1]) 111 | ftext += "\n\n--------END USERBOT TRACEBACK LOG--------" 112 | 113 | command = "git log --pretty=format:\"%an: %s\" -10" 114 | 115 | ftext += "\n\n\nLast 10 commits:\n" 116 | 117 | process = await asyncsubshell(command, 118 | stdout=asyncsub.PIPE, 119 | stderr=asyncsub.PIPE) 120 | stdout, stderr = await process.communicate() 121 | result = str(stdout.decode().strip()) \ 122 | + str(stderr.decode().strip()) 123 | 124 | ftext += result 125 | 126 | file = open("error.log", "w+") 127 | file.write(ftext) 128 | file.close() 129 | 130 | if LOGSPAMMER: 131 | await check.client.respond( 132 | "`Sorry, my userbot has crashed.\ 133 | \nThe error logs are stored in the userbot's log chat.`" 134 | ) 135 | 136 | await check.client.send_file(send_to, 137 | "error.log", 138 | caption=text) 139 | remove("error.log") 140 | else: 141 | pass 142 | 143 | if not disable_edited: 144 | bot.add_event_handler(wrapper, events.MessageEdited(**args)) 145 | bot.add_event_handler(wrapper, events.NewMessage(**args)) 146 | return wrapper 147 | 148 | return decorator 149 | --------------------------------------------------------------------------------