├── .gitattributes ├── .gitignore ├── README.md ├── psm ├── __init__.py ├── __main__.py ├── plugins │ ├── __init__.py │ ├── helpers.py │ ├── session_maker.py │ ├── start.py │ └── texts.py ├── psm.py └── strings.py ├── requirements.txt └── sample.psm.ini /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.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 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # celery beat schedule file 95 | celerybeat-schedule 96 | 97 | # SageMath parsed files 98 | *.sage.py 99 | 100 | # Environments 101 | .env 102 | .venv 103 | env/ 104 | venv/ 105 | ENV/ 106 | env.bak/ 107 | venv.bak/ 108 | 109 | # Spyder project settings 110 | .spyderproject 111 | .spyproject 112 | 113 | # Rope project settings 114 | .ropeproject 115 | 116 | # mkdocs documentation 117 | /site 118 | 119 | # mypy 120 | .mypy_cache/ 121 | .dmypy.json 122 | dmypy.json 123 | 124 | # Pyre type checker 125 | .pyre/ 126 | *.session 127 | psm.ini 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pyrogram Session Maker (TelegramBot) 2 | 3 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/01a4ef83e3a64a92b24d855aaed05c3a)](https://www.codacy.com/gh/pokurt/Pyrogram-SessionMaker-Bot/dashboard?utm_source=github.com&utm_medium=referral&utm_content=pokurt/Pyrogram-SessionMaker-Bot&utm_campaign=Badge_Grade) [![>~<](https://img.shields.io/badge/%3E~%3C-nyaaa~-purple)](https://naipofo.com) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/pokurt/Pyrogram-SessionMaker-Bot) ![Repo Size](https://img.shields.io/github/repo-size/pokurt/Pyrogram-SessionMaker-Bot) 4 | 5 | ## Disclaimer 6 | - I will not be responsible if your Voip account gets deleted/banned in the process. 7 | - However in previous occasion this never happened to anyone. 8 | - I suggest you to check the Source of this Project before continuing to use it. 9 | - There will be forks of [@PyrogramSessionBot](https://t.me/PyrogramSessionBot) therefore be careful while giving your Confidential Details to random forks of this Source. 10 | 11 | ### Evil Actions 12 | This project is free to use for Creating Sessions. If you Intend to use this project for Spam/Scam and other evil purposes, 13 | You are not welcome to be here or use the Project. 14 | 15 | ### Requirments 16 | - See `requirements.txt` in root directory of the Project 17 | - We do not need much of requirements other than `Pyrogram` and `TgCrypto` 18 | 19 | ### Setup 20 | - Install requirements in `requirements.txt` 21 | - Example of `psm.ini` is in `sample.psm.ini` 22 | - Run the bot: `python3 -m psm` 23 | -------------------------------------------------------------------------------- /psm/__init__.py: -------------------------------------------------------------------------------- 1 | """Client Initial.""" 2 | import pyromod.listen 3 | import logging 4 | from configparser import ConfigParser 5 | from datetime import datetime 6 | 7 | from psm.psm import psm 8 | 9 | # Logging at the start to catch everything 10 | logging.basicConfig( 11 | format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", 12 | level=logging.WARNING, 13 | handlers=[logging.StreamHandler()], 14 | ) 15 | LOGS = logging.getLogger(__name__) 16 | 17 | name = "psm" 18 | 19 | # Read from config file 20 | config_file = f"{name}.ini" 21 | config = ConfigParser() 22 | config.read(config_file) 23 | 24 | # Extra details 25 | __version__ = "1.1" 26 | __author__ = "pokurt" 27 | 28 | # Global Variables 29 | CMD_HELP = {} 30 | client = None 31 | START_TIME = datetime.now() 32 | 33 | psm = psm(name) 34 | -------------------------------------------------------------------------------- /psm/__main__.py: -------------------------------------------------------------------------------- 1 | from psm import psm 2 | 3 | if __name__ == "__main__": 4 | psm.client = psm 5 | psm.run() 6 | -------------------------------------------------------------------------------- /psm/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | """Plugins Directory.""" 2 | -------------------------------------------------------------------------------- /psm/plugins/helpers.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | 3 | 4 | def dynamic_data_filter(data): 5 | async def func(flt, _, query): 6 | return flt.data == query.data 7 | 8 | return filters.create(func, data=data) 9 | -------------------------------------------------------------------------------- /psm/plugins/session_maker.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters, Client, errors 2 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton 3 | from pyromod import listen 4 | 5 | import asyncio 6 | 7 | from psm import psm 8 | from psm.strings import strings 9 | 10 | 11 | async def client_session(message, api_id, api_hash): 12 | return Client(":memory:", api_id=int(api_id), api_hash=str(api_hash)) 13 | 14 | 15 | @psm.on_message(filters.command("proceed") | ~filters.command("start")) 16 | async def sessions_make(client, message): 17 | apid = await client.ask(message.chat.id, strings.APIID) 18 | if apid.text.startswith('/'): 19 | await message.reply(strings.CANCEL) 20 | return 21 | aphash = await client.ask(message.chat.id, strings.APIHASH) 22 | if aphash.text.startswith('/'): 23 | await message.reply(strings.CANCEL) 24 | return 25 | phone_token = await client.ask(message.chat.id, strings.PHONETOKEN) 26 | if phone_token.text.startswith('/'): 27 | await message.reply(strings.CANCEL) 28 | return 29 | if str(phone_token.text).startswith("+"): 30 | try: 31 | app = await client_session(message, api_id=apid.text, api_hash=aphash.text) 32 | except Exception as err: 33 | await message.reply(strings.ERROR.format(err=err)) 34 | return 35 | try: 36 | await app.connect() 37 | except ConnectionError: 38 | await app.disconnect() 39 | await app.connect() 40 | try: 41 | sent_code = await app.send_code(phone_token.text) 42 | except errors.FloodWait as e: 43 | await message.reply( 44 | f"I cannot create session for you.\nYou have a floodwait of: `{e.x} seconds`" 45 | ) 46 | return 47 | except errors.exceptions.bad_request_400.PhoneNumberInvalid: 48 | await message.reply(strings.INVALIDNUMBER) 49 | return 50 | except errors.exceptions.bad_request_400.ApiIdInvalid: 51 | await message.reply(strings.APIINVALID) 52 | return 53 | ans = await client.ask(message.chat.id, strings.PHONECODE) 54 | if ans.text.startswith('/'): 55 | await message.reply(strings.CANCEL) 56 | return 57 | try: 58 | await app.sign_in(phone_token.text, sent_code.phone_code_hash, ans.text) 59 | except errors.SessionPasswordNeeded: 60 | pas = await client.ask(message.chat.id, strings.PASSWORD) 61 | if pas.text.startswith('/'): 62 | await message.reply(strings.CANCEL) 63 | return 64 | try: 65 | await app.check_password(pas.text) 66 | except Exception as err: 67 | await message.reply(strings.ERROR.format(err=err)) 68 | return 69 | except errors.PhoneCodeInvalid: 70 | await message.reply(strings.PHONECODEINVALID) 71 | return 72 | except errors.PhoneCodeExpired: 73 | await message.reply(strings.PHONECODEINVALID) 74 | return 75 | await app.send_message("me", f"```{(await app.export_session_string())}```") 76 | button = InlineKeyboardMarkup( 77 | [ 78 | [ 79 | InlineKeyboardButton( 80 | "Go to Saved Messages", 81 | url=f"tg://user?id={message.from_user.id}", 82 | ) 83 | ] 84 | ] 85 | ) 86 | await message.reply( 87 | strings.DONEPHONE, 88 | reply_markup=button, 89 | ) 90 | else: 91 | try: 92 | app = await client_session(message, api_id=apid.text, api_hash=aphash.text) 93 | except Exception as err: 94 | await message.reply(strings.ERROR.format(err=err)) 95 | return 96 | try: 97 | await app.connect() 98 | except ConnectionError: 99 | await app.disconnect() 100 | await app.connect() 101 | try: 102 | await app.sign_in_bot(phone_token.text) 103 | except errors.exceptions.bad_request_400.AccessTokenInvalid: 104 | await message.reply(strings.BOTTOKENINVALID) 105 | return 106 | await message.reply( 107 | f"**Here is your Bot Session:**\n```{(await app.export_session_string())}```\n\nHappy pyrogramming" 108 | ) 109 | -------------------------------------------------------------------------------- /psm/plugins/start.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton 3 | 4 | from psm import psm 5 | from psm.plugins.helpers import dynamic_data_filter 6 | from psm.plugins.texts import helptext, helptext1, helptext2, helptext3, tiptext1 7 | 8 | 9 | @psm.on_message(filters.command("start")) 10 | async def alive(_, message): 11 | buttons = [[InlineKeyboardButton("How it works", callback_data="help_1")]] 12 | await message.reply(helptext, reply_markup=InlineKeyboardMarkup(buttons)) 13 | 14 | 15 | @psm.on_callback_query(dynamic_data_filter("help_1")) 16 | async def help_button(_, query): 17 | buttons = [[InlineKeyboardButton("Next", callback_data="help_2")]] 18 | await query.message.edit( 19 | helptext1, 20 | disable_web_page_preview=True, 21 | reply_markup=InlineKeyboardMarkup(buttons), 22 | ) 23 | await query.answer() 24 | 25 | 26 | @psm.on_callback_query(dynamic_data_filter("help_2")) 27 | async def help_button1(_, query): 28 | buttons = [ 29 | [ 30 | InlineKeyboardButton("Previous", callback_data="help_1"), 31 | InlineKeyboardButton("Next", callback_data="help_3"), 32 | ] 33 | ] 34 | await query.message.edit(helptext2, reply_markup=InlineKeyboardMarkup(buttons)) 35 | await query.answer() 36 | 37 | 38 | @psm.on_callback_query(dynamic_data_filter("help_3")) 39 | async def help_button2(_, query): 40 | buttons = [ 41 | [ 42 | InlineKeyboardButton("Previous", callback_data="help_2"), 43 | InlineKeyboardButton("Tip", callback_data="tip_1"), 44 | ] 45 | ] 46 | await query.message.edit(helptext3, reply_markup=InlineKeyboardMarkup(buttons)) 47 | await query.answer() 48 | 49 | 50 | @psm.on_callback_query(dynamic_data_filter("tip_1")) 51 | async def tip_button1(_, query): 52 | buttons = [ 53 | [ 54 | InlineKeyboardButton("Previous", callback_data="help_3"), 55 | InlineKeyboardButton( 56 | "Source", url="https://github.com/pokurt/Pyrogram-SessionMaker-Bot" 57 | ), 58 | ] 59 | ] 60 | await query.message.edit( 61 | tiptext1, 62 | reply_markup=InlineKeyboardMarkup(buttons), 63 | disable_web_page_preview=True, 64 | ) 65 | await query.answer() 66 | -------------------------------------------------------------------------------- /psm/plugins/texts.py: -------------------------------------------------------------------------------- 1 | helptext = """ 2 | I am Pyrogram Session maker, 3 | 4 | I can make session strings for you on the go 5 | """ 6 | 7 | helptext1 = """ 8 | **📖 Help (1 of 3)** 9 | you can get API_ID and API_HASH value by visiting https://my.telegram.org or @usetgxbot 10 | """ 11 | 12 | helptext2 = """ 13 | **📖 Help (2 of 3)** 14 | Telegram will send validation to you, 15 | 16 | **MAKE SURE** to type validation code in this format: `1-2-3-4-5` and not `12345` 17 | """ 18 | helptext3 = """ 19 | **📖 Help (3 of 3)** 20 | 21 | When you are ready you can start with /proceed 22 | You can also cancel current operation with /start 23 | """ 24 | 25 | tiptext1 = """ 26 | **💡 Tip (1 of 1)** 27 | 28 | Follow [Pokurt](https://github.com/pokurt) for more awesome projects like this! 29 | Make sure you give a star to [PSM](https://github.com/pokurt/Pyrogram-SessionMaker-Bot) 30 | 31 | **Note**: 32 | Since there will be Forks of this bot I suggest you to make your own one from Source. 33 | I (Pokurt) Personally made this for experimental purposes only, therefore the source is open. 34 | Your phone number and other confidential details are not saved in anyway anymore. 35 | Make sure you clear the chat history of this bot if you do not trust and take a look at the Source itself. 36 | """ 37 | -------------------------------------------------------------------------------- /psm/psm.py: -------------------------------------------------------------------------------- 1 | from os import environ 2 | from configparser import ConfigParser 3 | from pyrogram import Client 4 | 5 | 6 | API_ID = environ.get("API_ID", None) 7 | API_HASH = environ.get("API_HASH", None) 8 | TOKEN = environ.get("TOKEN", None) 9 | 10 | 11 | class psm(Client): 12 | def __init__(self, name): 13 | """Custom Pyrogram Client.""" 14 | name = name.lower() 15 | config_file = f"{name}.ini" 16 | config = ConfigParser() 17 | config.read(config_file) 18 | plugins = dict( 19 | root=f"{name}.plugins", 20 | ) 21 | super().__init__( 22 | name, 23 | api_id=API_ID, 24 | api_hash=API_HASH, 25 | bot_token=TOKEN or config.get("pyrogram", "token"), 26 | config_file=config_file, 27 | workers=16, 28 | plugins=plugins, 29 | workdir="./", 30 | app_version="psm v1.1", 31 | ) 32 | 33 | async def start(self): 34 | await super().start() 35 | print("Bot started. Hi.") 36 | async def stop(self, *args): 37 | await super().stop() 38 | print("Bot stopped. Bye.") 39 | -------------------------------------------------------------------------------- /psm/strings.py: -------------------------------------------------------------------------------- 1 | class strings(object): 2 | APIID = "Send me your `API_ID` you can find it on my.telegram.org after you logged in." 3 | APIHASH = "Send me your `API_HASH` you can find it on my.telegram.org after you logged in." 4 | PHONETOKEN = "Now send me your `phone number` in international format or your `bot_token`" 5 | ERROR = "**Something went wrong:** ```{err}```" 6 | FLOODWAIT = "I cannot create session for you.\nYou have a floodwait of: `{e.x} seconds`" 7 | INVALIDNUMBER = "Phone number is invalid, Make sure you double check before sending." 8 | APIINVALID = "Your `API_ID` or `API_HASH` given is Invalid. Try again" 9 | PHONECODE = "send me your code in the format `1-2-3-4-5` and not `12345`" 10 | PASSWORD = "The entered Telegram Number is protected with 2FA. Please enter your second factor authentication code.\n__This message will only be used for generating your string session, and will never be used for any other purposes than for which it is asked.__" 11 | PHONECODEINVALID = "The code you sent seems Invalid, Try again." 12 | PHONECODE_EXPIRED = "The Code you sent seems Expired. Try again." 13 | DONEPHONE = "All Done! Check your Saved Messages for your Session String." 14 | BOTTOKENINVALID = "BotToken Invalid: make sure you are sending a valid BotToken from @BotFather" 15 | CANCEL = 'Cancelling Current operation. if you want to start again try /proceed ^_^' 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyrogram 2 | tgcrypto 3 | pyromod -------------------------------------------------------------------------------- /sample.psm.ini: -------------------------------------------------------------------------------- 1 | [pyrogram] 2 | api_id = API_ID 3 | api_hash = API_HASH 4 | token = BOT_TOKEN --------------------------------------------------------------------------------