├── blacklist.txt ├── runtime.txt ├── Procfile ├── requirements.txt ├── README.md ├── Livegram ├── mod │ ├── sql │ │ ├── __init__.py │ │ └── blacklist_sql.py │ ├── __init__.py │ ├── forward.py │ ├── bans.py │ └── reply.py ├── __init__.py └── __main__.py └── app.json /blacklist.txt: -------------------------------------------------------------------------------- 1 | 952220695 2 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.8.5 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python -m Livegram 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | python-telegram-bot 2 | telethon 3 | sqlalchemy 4 | psycopg2-binary 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Livegram 2 | 3 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/okay-retard/Livegram) 4 | -------------------------------------------------------------------------------- /Livegram/mod/sql/__init__.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import create_engine 2 | from sqlalchemy.ext.declarative import declarative_base 3 | from sqlalchemy.orm import sessionmaker, scoped_session 4 | from Livegram import Config 5 | 6 | 7 | def start() -> scoped_session: 8 | """ returns SQLAlchemy ScopedSession """ 9 | engine = create_engine(Config.DB_URI) 10 | BASE.metadata.bind = engine 11 | BASE.metadata.create_all(engine) 12 | return scoped_session( 13 | sessionmaker( 14 | bind=engine, 15 | autoflush=False 16 | ) 17 | ) 18 | 19 | 20 | BASE = declarative_base() 21 | SESSION = start() 22 | -------------------------------------------------------------------------------- /Livegram/mod/__init__.py: -------------------------------------------------------------------------------- 1 | from Livegram import LOGGER 2 | import glob 3 | 4 | def __list_all_modules(): 5 | from os.path import dirname, basename, isfile 6 | import glob 7 | # This generates a list of modules in this folder for the * in __main__ to work. 8 | mod_paths = glob.glob(dirname(__file__) + "/*.py") 9 | all_modules = [basename(f)[:-3] for f in mod_paths if isfile(f) 10 | and f.endswith(".py") 11 | and not f.endswith('__init__.py')] 12 | return all_modules 13 | 14 | 15 | ALL_MODULES = __list_all_modules() 16 | LOGGER.info("Modules to load: %s", str(ALL_MODULES)) 17 | __all__ = ALL_MODULES + ["ALL_MODULES"] 18 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Livegram", 3 | "description": "Nothing", 4 | "env": { 5 | "API_ID": { 6 | "description": "Get this value from my.telegram.org.", 7 | "required": true 8 | }, 9 | "API_HASH": { 10 | "description": "Get this value from my.telegram.org.", 11 | "required": true 12 | }, 13 | "TOKEN": { 14 | "description": "", 15 | "required": true 16 | }, 17 | "SUDO_USERS": { 18 | "description": "", 19 | "value": true 20 | }, 21 | "CHAT_ID": { 22 | "description": "", 23 | "value": true 24 | } 25 | }, 26 | "buildpacks": [ 27 | { 28 | "url": "heroku/python" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /Livegram/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from telethon import TelegramClient 3 | import logging 4 | from telegram.ext import Updater, CommandHandler, Dispatcher 5 | 6 | logging.basicConfig( 7 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 8 | handlers=[logging.FileHandler('log.txt'), 9 | logging.StreamHandler()], 10 | level=logging.INFO) 11 | 12 | LOGGER = logging.getLogger(__name__) 13 | 14 | class Config(object): 15 | LOGGER = True 16 | # Get this value from my.telegram.org! Please do not steal 17 | API_ID = int(os.environ.get("API_ID", None)) 18 | API_HASH = os.environ.get("API_HASH", "") 19 | TOKEN = os.environ.get("TOKEN", "") 20 | SUDO_USERS = SUDO_USERS = set(int(x) for x in os.environ.get("SUDO_USERS", "").split()) 21 | CHAT_ID = os.environ.get("CHAT_ID", "") 22 | DB_URI = os.environ.get("DATABASE_URL", None) 23 | class Production(Config): 24 | LOGGER = False 25 | 26 | class Development(Config): 27 | LOGGER = True 28 | 29 | bot = TelegramClient('for', Config.API_ID, Config.API_HASH).start(bot_token=Config.TOKEN) 30 | updater = Updater(Config.TOKEN, use_context=True) 31 | dispatcher = updater.dispatcher 32 | -------------------------------------------------------------------------------- /Livegram/mod/sql/blacklist_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | Column, 3 | String, 4 | UnicodeText 5 | ) 6 | from Livegram.mod.sql import SESSION, BASE 7 | 8 | 9 | class BlackList(BASE): 10 | """ table to store BANned users """ 11 | __tablename__ = "blacklist" 12 | chat_id = Column(String(14), primary_key=True) 13 | reason = Column(UnicodeText) 14 | 15 | def __init__(self, chat_id, reason): 16 | self.chat_id = str(chat_id) # ensure string 17 | self.reason = reason 18 | 19 | def __repr__(self): 20 | return "" % self.chat_id 21 | 22 | 23 | BlackList.__table__.create(checkfirst=True) 24 | 25 | 26 | def add_user_to_bl(chat_id, reason): 27 | """ add the user to the blacklist """ 28 | __user = BlackList(str(chat_id), reason) 29 | SESSION.add(__user) 30 | SESSION.commit() 31 | 32 | 33 | def check_is_black_list(chat_id): 34 | """ get the user_id from the message_id """ 35 | try: 36 | s__ = SESSION.query(BlackList).get(str(chat_id)) 37 | return s__ 38 | finally: 39 | SESSION.close() 40 | 41 | 42 | def rem_user_from_bl(chat_id): 43 | s__ = SESSION.query(BlackList).get(str(chat_id)) 44 | if s__: 45 | SESSION.delete(s__) 46 | SESSION.commit() 47 | return True 48 | SESSION.close() 49 | return False 50 | -------------------------------------------------------------------------------- /Livegram/mod/forward.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from Livegram import updater, dispatcher, Config 4 | from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext 5 | from telegram import ParseMode 6 | from Livegram.mod.sql.blacklist_sql import check_is_black_list 7 | 8 | # Enable logging 9 | logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 10 | level=logging.INFO) 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | to_c = Config.CHAT_ID 15 | 16 | 17 | def forward(update, context): 18 | user = update.message.from_user 19 | check_ban = check_is_black_list(user['id']) 20 | if check_ban: 21 | context.bot.send_message(chat_id=user['id'], text="You have been banned.") 22 | return 23 | message = update.message 24 | if not update.effective_message.chat.type == "private": 25 | return 26 | context.bot.forward_message(chat_id=to_c, 27 | from_chat_id=update.message.chat_id, 28 | message_id=update.message.message_id) 29 | context.bot.send_message(chat_id=to_c, text=f"{user['first_name']} id is `{user['id']}`", parse_mode=ParseMode.MARKDOWN_V2) 30 | 31 | dispatcher.add_handler(MessageHandler(Filters.all & ~Filters.command, forward)) 32 | -------------------------------------------------------------------------------- /Livegram/mod/bans.py: -------------------------------------------------------------------------------- 1 | from telethon import events 2 | from Livegram.mod.sql.blacklist_sql import add_user_to_bl, rem_user_from_bl 3 | import shlex 4 | from Livegram import bot 5 | from Livegram import Config 6 | 7 | SU = Config.SUDO_USERS 8 | 9 | def get_args(message): 10 | """Get arguments from message (str or Message), return list of arguments""" 11 | try: 12 | message = message.message.message 13 | except AttributeError: 14 | pass 15 | if not message: 16 | return False 17 | message = message.split(maxsplit=1) 18 | if len(message) <= 1: 19 | return [] 20 | message = message[1] 21 | try: 22 | split = shlex.split(message) 23 | except ValueError: 24 | return message # Cannot split, let's assume that it's just one long message 25 | return list(filter(lambda x: len(x) > 0, split)) 26 | 27 | @bot.on(events.NewMessage(pattern='/b')) 28 | async def _(event): 29 | if not event.from_id in SU: 30 | return 31 | args = get_args(event) 32 | r = False 33 | user_id = args[0] 34 | if not user_id: 35 | await message.reply("/ban user_id") 36 | return 37 | reason = "You are banned." 38 | 39 | add_user_to_bl(user_id, reason) 40 | await event.reply("Banned") 41 | 42 | @bot.on(events.NewMessage(pattern='/ub')) 43 | async def _(event): 44 | if not event.from_id in SU: 45 | return 46 | args = get_args(event) 47 | r = False 48 | user_id = args[0] 49 | if not user_id: 50 | await message.reply("/ub user_id") 51 | return 52 | 53 | rem_user_from_bl(user_id) 54 | await event.reply("Unbanned") 55 | -------------------------------------------------------------------------------- /Livegram/mod/reply.py: -------------------------------------------------------------------------------- 1 | from Livegram import bot 2 | from telethon import events 3 | from Livegram import Config 4 | 5 | SU = Config.SUDO_USERS 6 | 7 | def get_arg(event): 8 | msg = event.raw_text 9 | msg = msg.replace(" ", "", 1) if msg[1] == " " else msg 10 | split = msg[1:].replace("\n", " \n").split(" ") 11 | if " ".join(split[1:]).strip() == "": 12 | return "" 13 | return " ".join(split[1:]) 14 | 15 | def arg_split_with(event, char): 16 | args = get_arg(event).split(char) 17 | for space in args: 18 | if space.strip() == "": 19 | args.remove(space) 20 | return args 21 | 22 | @bot.on(events.NewMessage(pattern='/r')) 23 | async def _(event): 24 | if not event.from_id in SU: 25 | 26 | return 27 | reply = await event.get_reply_message() 28 | if not reply: 29 | await event.reply("Reply to a forwarded message.") 30 | x = 0 31 | args = arg_split_with(event, "*") 32 | if not args: 33 | await event.reply("Enter message to send.") 34 | return 35 | argu = get_arg(event) 36 | try: 37 | to_send = reply.forward.sender.id 38 | except AttributeError: 39 | x += 1 40 | if x != 1: 41 | id = int(to_send) 42 | msg = argu 43 | await event.client.send_message(id, msg) 44 | else: 45 | try: 46 | id = int(args[0]) 47 | except ValueError: 48 | await event.reply("Failed to extract user id. Use /r *") 49 | return 50 | msg = args[1] 51 | if not msg: 52 | await event.reply("Enter a message to send") 53 | return 54 | await event.client.send_message(id, msg) 55 | 56 | -------------------------------------------------------------------------------- /Livegram/__main__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | from Livegram import dispatcher, updater, Config, bot, dispatcher, LOGGER 3 | from Livegram.mod import ALL_MODULES 4 | from telegram import Message, Update, Bot, User 5 | from telegram.ext import (CallbackContext, CallbackQueryHandler, CommandHandler, 6 | Filters, MessageHandler, run_async) 7 | from telegram import ParseMode 8 | 9 | IMPORTED = {} 10 | MIGRATEABLE = [] 11 | HELPABLE = {} 12 | STATS = [] 13 | USER_INFO = [] 14 | DATA_IMPORT = [] 15 | DATA_EXPORT = [] 16 | 17 | CHAT_SETTINGS = {} 18 | USER_SETTINGS = {} 19 | 20 | for module_name in ALL_MODULES: 21 | imported_module = importlib.import_module("Livegram.mod." + module_name) 22 | if not hasattr(imported_module, "__mod_name__"): 23 | imported_module.__mod_name__ = imported_module.__name__ 24 | 25 | if not imported_module.__mod_name__.lower() in IMPORTED: 26 | IMPORTED[imported_module.__mod_name__.lower()] = imported_module 27 | else: 28 | raise Exception("Can't have two modules with the same name! Please change one") 29 | 30 | if hasattr(imported_module, "__help__") and imported_module.__help__: 31 | HELPABLE[imported_module.__mod_name__.lower()] = imported_module 32 | 33 | # Chats to migrate on chat_migrated events 34 | if hasattr(imported_module, "__migrate__"): 35 | MIGRATEABLE.append(imported_module) 36 | 37 | if hasattr(imported_module, "__stats__"): 38 | STATS.append(imported_module) 39 | 40 | if hasattr(imported_module, "__user_info__"): 41 | USER_INFO.append(imported_module) 42 | 43 | if hasattr(imported_module, "__import_data__"): 44 | DATA_IMPORT.append(imported_module) 45 | 46 | if hasattr(imported_module, "__export_data__"): 47 | DATA_EXPORT.append(imported_module) 48 | 49 | if hasattr(imported_module, "__chat_settings__"): 50 | CHAT_SETTINGS[imported_module.__mod_name__.lower()] = imported_module 51 | 52 | if hasattr(imported_module, "__user_settings__"): 53 | USER_SETTINGS[imported_module.__mod_name__.lower()] = imported_module 54 | 55 | @run_async 56 | def start(update, context): 57 | user = update.message.from_user 58 | if update.effective_message.chat.type == "private": 59 | text = "Official Bot for @BruteForcers Send it feedbacks or any config requests here to be done.ԅ( ͒ ۝ ͒ )ᕤ." 60 | else: 61 | text = "What bsdk?" 62 | update.effective_message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True) 63 | 64 | def main(): 65 | test_handler = CommandHandler("start", start) 66 | dispatcher.add_handler(test_handler) 67 | updater.start_polling() 68 | bot.run_until_disconnected() 69 | 70 | if __name__ == '__main__': 71 | LOGGER.info("Successfully loaded modules: " + str(ALL_MODULES)) 72 | bot 73 | main() 74 | --------------------------------------------------------------------------------