├── .dockerignore ├── .github ├── CODEOWNERS └── README.md ├── .gitignore ├── Dockerfile ├── LICENSE ├── Procfile ├── StringGen ├── __init__.py ├── __main__.py ├── modules │ ├── __init__.py │ ├── callbacks.py │ ├── eval.py │ ├── gen.py │ ├── start.py │ └── stats.py └── utils │ ├── __init__.py │ ├── inline.py │ └── users.py ├── app.json ├── config.py ├── heroku.yml ├── requirements.txt ├── runtime.txt ├── sample.env └── start /.dockerignore: -------------------------------------------------------------------------------- 1 | .env 2 | *.log 3 | .git/ 4 | Procfile 5 | README.md 6 | .gitignore 7 | runtime.txt 8 | __pycache__/ 9 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @AnonymousX1025 2 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | ━━━━━━━━━━━━━━━━━━━━ 2 | 3 |

4 | ──「 Sᴛʀɪɴɢ Gᴇɴ Bᴏᴛ 」── 5 |

6 | 7 |

8 | 9 |

10 | 11 | _**ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ ᴀs [sᴛʀɪɴɢ ғᴀᴛʜᴇʀ](https://t.me/StringFatherBot)**_ 12 | ━━━━━━━━━━━━━━━━━━━━ 13 | 14 |

15 | Stars 16 | 17 | License 18 | Python 19 | 20 |

21 | 22 | ━━━━━━━━━━━━━━━━━━━━ 23 | 24 |

25 | 26 |

27 | 28 |

29 | 𝗗𝗘𝗣𝗟𝗢𝗬𝗠𝗘𝗡𝗧 𝗠𝗘𝗧𝗛𝗢𝗗𝗦 30 |

31 | 32 |

33 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ʜᴇʀᴏᴋᴜ 」─ 34 |

35 | 36 |

37 | 38 |
39 |

40 | - ᴠᴘs/ʟᴏᴄᴀʟ ᴅᴇᴘʟᴏʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ 41 |

42 | 43 | - Get your [Necessary Variables](https://github.com/AnonymousX1025/StringGenBot/blob/master/sample.env) 44 | - Upgrade and Update by : 45 | `sudo apt-get update && sudo apt-get upgrade -y` 46 | - Install required packages by : 47 | `sudo apt-get install python3-pip` 48 | - Install pip by : 49 | `sudo pip3 install -U pip` 50 | - Clone the repository by : 51 | `git clone https://github.com/AnonymousX1025/StringGenBot && cd StringGenBot` 52 | - Install requirements by : 53 | `pip3 install -U -r requirements.txt` 54 | - Fill your variables in the env by : 55 | `vi sample.env`
56 | Press `I` on the keyboard for editing env
57 | Press `Ctrl+C` when you're done with editing env and `:wq` to save the env
58 | - Rename the env file by : 59 | `mv sample.env .env` 60 | - Install tmux to keep running your bot when you close the terminal by : 61 | `sudo apt install tmux && tmux` 62 | - Finally run the bot by : 63 | `bash start` 64 | - For getting out from tmux session
65 | Press `Ctrl+b` and then `d` 66 | 67 |

68 | 69 |

70 | 71 |
72 | 73 | ━━━━━━━━━━━━━━━━━━━━ 74 |

75 | ─「 sᴜᴩᴩᴏʀᴛ 」─ 76 |

77 | 78 |

79 | 80 |

81 |

82 | 83 |

84 | 85 | ━━━━━━━━━━━━━━━━━━━━ 86 | 87 |

88 | ─「 ᴄʀᴇᴅɪᴛs 」─ 89 |

90 | 91 | - [ᴀɴᴏɴʏᴍᴏᴜs](https://github.com/AnonymousX1025) ғᴏʀ [ғᴀʟʟᴇɴ ᴍᴜsɪᴄ](https://github.com/AnonymousX1025/FallenMusic) 92 | - [ᴅᴀɴ](https://github.com/delivrance) ғᴏʀ [ᴘʏʀᴏɢʀᴀᴍ](https://github.com/pyrogram/pyrogram) 93 | - [ʟᴏɴᴀᴍɪ](https://github.com/Lonami) ғᴏʀ [ᴛᴇʟᴇᴛʜᴏɴ](https://github.com/LonamiWebs/Telethon) 94 | 95 | ᴀɴᴅ ᴀʟʟ [ᴛʜᴇ ᴄᴏɴᴛʀɪʙᴜᴛᴏʀs](https://github.com/AnonymousX1025/StringGenBot/graphs/contributors) ᴡʜᴏ ʜᴇʟᴩᴇᴅ ɪɴ ᴍᴀᴋɪɴɢ sᴛʀɪɴɢ ɢᴇɴ ʙᴏᴛ ᴜsᴇғᴜʟ 🖤 96 | 97 | ━━━━━━━━━━━━━━━━━━━━ 98 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | *.log 3 | venv/ 4 | *.session 5 | __pycache__/ 6 | *.session-journal 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:latest 2 | 3 | RUN apt-get update -y && apt-get upgrade -y 4 | 5 | RUN pip3 install -U pip 6 | 7 | COPY . /app/ 8 | WORKDIR /app/ 9 | RUN pip3 install -U -r requirements.txt 10 | 11 | CMD bash start 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ˹ᴧɴσɴʏᴍσᴜs ꭙ˼ 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 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: bash start 2 | -------------------------------------------------------------------------------- /StringGen/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import pyromod 3 | 4 | from motor.motor_asyncio import AsyncIOMotorClient as MongoCli 5 | from pyrogram import Client 6 | from pyrogram.enums import ParseMode 7 | 8 | import config 9 | 10 | logging.basicConfig( 11 | format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s", 12 | datefmt="%d-%b-%y %H:%M:%S", 13 | handlers=[logging.FileHandler("log.txt"), logging.StreamHandler()], 14 | level=logging.INFO, 15 | ) 16 | logging.getLogger("pyrogram").setLevel(logging.ERROR) 17 | logging.getLogger("oldpyro").setLevel(logging.ERROR) 18 | logging.getLogger("telethon").setLevel(logging.ERROR) 19 | LOGGER = logging.getLogger(__name__) 20 | 21 | mongo = MongoCli(config.MONGO_DB_URI) 22 | db = mongo.StringGen 23 | 24 | 25 | class Anony(Client): 26 | def __init__(self): 27 | super().__init__( 28 | name="Anonymous", 29 | api_id=config.API_ID, 30 | api_hash=config.API_HASH, 31 | lang_code="en", 32 | bot_token=config.BOT_TOKEN, 33 | in_memory=True, 34 | parse_mode=ParseMode.HTML, 35 | ) 36 | 37 | async def start(self): 38 | await super().start() 39 | self.id = self.me.id 40 | self.name = self.me.first_name + " " + (self.me.last_name or "") 41 | self.username = self.me.username 42 | self.mention = self.me.mention 43 | 44 | async def stop(self): 45 | await super().stop() 46 | 47 | 48 | Anony = Anony() 49 | -------------------------------------------------------------------------------- /StringGen/__main__.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import importlib 3 | 4 | from pyrogram import idle 5 | 6 | from StringGen import LOGGER, Anony 7 | from StringGen.modules import ALL_MODULES 8 | 9 | 10 | async def anony_boot(): 11 | try: 12 | await Anony.start() 13 | except Exception as ex: 14 | LOGGER.error(ex) 15 | quit(1) 16 | 17 | for all_module in ALL_MODULES: 18 | importlib.import_module("StringGen.modules." + all_module) 19 | 20 | LOGGER.info(f"@{Anony.username} Started.") 21 | await idle() 22 | 23 | 24 | if __name__ == "__main__": 25 | asyncio.get_event_loop().run_until_complete(anony_boot()) 26 | LOGGER.info("Stopping String Gen Bot...") 27 | -------------------------------------------------------------------------------- /StringGen/modules/__init__.py: -------------------------------------------------------------------------------- 1 | import glob 2 | from os.path import basename, dirname, isfile 3 | 4 | 5 | def __list_all_modules(): 6 | mod_paths = glob.glob(dirname(__file__) + "/*.py") 7 | 8 | all_modules = [ 9 | basename(f)[:-3] 10 | for f in mod_paths 11 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") 12 | ] 13 | 14 | return all_modules 15 | 16 | 17 | ALL_MODULES = sorted(__list_all_modules()) 18 | __all__ = ALL_MODULES + ["ALL_MODULES"] 19 | -------------------------------------------------------------------------------- /StringGen/modules/callbacks.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import CallbackQuery 3 | 4 | from StringGen import Anony 5 | from StringGen.utils import gen_key 6 | from StringGen.modules.gen import gen_session 7 | 8 | 9 | @Anony.on_callback_query( 10 | filters.regex(pattern=r"^(gensession|pyrogram|pyrogram1|telethon)$") 11 | ) 12 | async def cb_choose(_, cq: CallbackQuery): 13 | await cq.answer() 14 | query = cq.matches[0].group(1) 15 | if query == "gensession": 16 | return await cq.message.reply_text( 17 | text="» ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴜᴛᴛᴏɴs ʙᴇʟᴏᴡ ғᴏʀ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ :", 18 | reply_markup=gen_key, 19 | ) 20 | elif query.startswith("pyrogram") or query.startswith("telethon"): 21 | try: 22 | if query == "pyrogram": 23 | await gen_session(cq.message, cq.from_user.id) 24 | elif query == "pyrogram1": 25 | await gen_session(cq.message, cq.from_user.id, old_pyro=True) 26 | elif query == "telethon": 27 | await gen_session(cq.message, cq.from_user.id, telethon=True) 28 | except Exception as e: 29 | await cq.edit_message_text(e, disable_web_page_preview=True) 30 | -------------------------------------------------------------------------------- /StringGen/modules/eval.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import subprocess 4 | import sys 5 | import traceback 6 | from inspect import getfullargspec 7 | from io import StringIO 8 | from time import time 9 | 10 | from pyrogram import filters 11 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message 12 | 13 | from config import OWNER_ID 14 | from StringGen import Anony 15 | 16 | 17 | async def aexec(code, client, message): 18 | exec( 19 | "async def __aexec(client, message): " 20 | + "".join(f"\n {a}" for a in code.split("\n")) 21 | ) 22 | return await locals()["__aexec"](client, message) 23 | 24 | 25 | async def edit_or_reply(msg: Message, **kwargs): 26 | func = msg.edit_text if msg.from_user.is_self else msg.reply 27 | spec = getfullargspec(func.__wrapped__).args 28 | await func(**{k: v for k, v in kwargs.items() if k in spec}) 29 | 30 | 31 | @Anony.on_edited_message( 32 | filters.command("eval") 33 | & filters.user(OWNER_ID) 34 | & ~filters.forwarded 35 | & ~filters.via_bot 36 | ) 37 | @Anony.on_message( 38 | filters.command("eval") 39 | & filters.user(OWNER_ID) 40 | & ~filters.forwarded 41 | & ~filters.via_bot 42 | ) 43 | async def executor(client: Anony, message: Message): 44 | if len(message.command) < 2: 45 | return await edit_or_reply(message, text="ᴡʜᴀᴛ ʏᴏᴜ ᴡᴀɴɴᴀ ᴇxᴇᴄᴜᴛᴇ ʙᴀʙʏ ?") 46 | try: 47 | cmd = message.text.split(" ", maxsplit=1)[1] 48 | except IndexError: 49 | return await message.delete() 50 | t1 = time() 51 | old_stderr = sys.stderr 52 | old_stdout = sys.stdout 53 | redirected_output = sys.stdout = StringIO() 54 | redirected_error = sys.stderr = StringIO() 55 | stdout, stderr, exc = None, None, None 56 | try: 57 | await aexec(cmd, client, message) 58 | except Exception: 59 | exc = traceback.format_exc() 60 | stdout = redirected_output.getvalue() 61 | stderr = redirected_error.getvalue() 62 | sys.stdout = old_stdout 63 | sys.stderr = old_stderr 64 | evaluation = "\n" 65 | if exc: 66 | evaluation += exc 67 | elif stderr: 68 | evaluation += stderr 69 | elif stdout: 70 | evaluation += stdout 71 | else: 72 | evaluation += "Success" 73 | final_output = f"⥤ ʀᴇsᴜʟᴛ :\n
{evaluation}
" 74 | if len(final_output) > 4096: 75 | filename = "output.txt" 76 | with open(filename, "w+", encoding="utf8") as out_file: 77 | out_file.write(str(evaluation)) 78 | t2 = time() 79 | keyboard = InlineKeyboardMarkup( 80 | [ 81 | [ 82 | InlineKeyboardButton( 83 | text="⏳", 84 | callback_data=f"runtime {t2-t1} Seconds", 85 | ) 86 | ] 87 | ] 88 | ) 89 | await message.reply_document( 90 | document=filename, 91 | caption=f"⥤ ᴇᴠᴀʟ :\n{cmd[0:980]}\n\n⥤ ʀᴇsᴜʟᴛ :\nAttached Document", 92 | quote=False, 93 | reply_markup=keyboard, 94 | ) 95 | await message.delete() 96 | os.remove(filename) 97 | else: 98 | t2 = time() 99 | keyboard = InlineKeyboardMarkup( 100 | [ 101 | [ 102 | InlineKeyboardButton( 103 | text="⏳", 104 | callback_data=f"runtime {round(t2-t1, 3)} Seconds", 105 | ), 106 | InlineKeyboardButton( 107 | text="🗑", 108 | callback_data=f"forceclose abc|{message.from_user.id}", 109 | ), 110 | ] 111 | ] 112 | ) 113 | await edit_or_reply(message, text=final_output, reply_markup=keyboard) 114 | 115 | 116 | @Anony.on_callback_query(filters.regex(r"runtime")) 117 | async def runtime_func_cq(_, cq): 118 | runtime = cq.data.split(None, 1)[1] 119 | await cq.answer(runtime, show_alert=True) 120 | 121 | 122 | @Anony.on_callback_query(filters.regex("forceclose")) 123 | async def forceclose_command(_, CallbackQuery): 124 | callback_data = CallbackQuery.data.strip() 125 | callback_request = callback_data.split(None, 1)[1] 126 | query, user_id = callback_request.split("|") 127 | if CallbackQuery.from_user.id != int(user_id): 128 | try: 129 | return await CallbackQuery.answer( 130 | "» ɪᴛ'ʟʟ ʙᴇ ʙᴇᴛᴛᴇʀ ɪғ ʏᴏᴜ sᴛᴀʏ ɪɴ ʏᴏᴜʀ ʟɪᴍɪᴛs ʙᴀʙʏ.", show_alert=True 131 | ) 132 | except: 133 | return 134 | await CallbackQuery.message.delete() 135 | try: 136 | await CallbackQuery.answer() 137 | except: 138 | return 139 | 140 | 141 | @Anony.on_edited_message( 142 | filters.command("sh") 143 | & filters.user(OWNER_ID) 144 | & ~filters.forwarded 145 | & ~filters.via_bot 146 | ) 147 | @Anony.on_message( 148 | filters.command("sh") 149 | & filters.user(OWNER_ID) 150 | & ~filters.forwarded 151 | & ~filters.via_bot 152 | ) 153 | async def shellrunner(_, message: Message): 154 | if len(message.command) < 2: 155 | return await edit_or_reply(message, text="ᴇxᴀᴍᴩʟᴇ :\n/sh git pull") 156 | text = message.text.split(None, 1)[1] 157 | if "\n" in text: 158 | code = text.split("\n") 159 | output = "" 160 | for x in code: 161 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x) 162 | try: 163 | process = subprocess.Popen( 164 | shell, 165 | stdout=subprocess.PIPE, 166 | stderr=subprocess.PIPE, 167 | ) 168 | except Exception as err: 169 | await edit_or_reply(message, text=f"ERROR :\n
{err}
") 170 | output += f"{code}\n" 171 | output += process.stdout.read()[:-1].decode("utf-8") 172 | output += "\n" 173 | else: 174 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text) 175 | for a in range(len(shell)): 176 | shell[a] = shell[a].replace('"', "") 177 | try: 178 | process = subprocess.Popen( 179 | shell, 180 | stdout=subprocess.PIPE, 181 | stderr=subprocess.PIPE, 182 | ) 183 | except Exception as err: 184 | print(err) 185 | exc_type, exc_obj, exc_tb = sys.exc_info() 186 | errors = traceback.format_exception( 187 | etype=exc_type, 188 | value=exc_obj, 189 | tb=exc_tb, 190 | ) 191 | return await edit_or_reply( 192 | message, text=f"ERROR :\n
{''.join(errors)}
" 193 | ) 194 | output = process.stdout.read()[:-1].decode("utf-8") 195 | if str(output) == "\n": 196 | output = None 197 | if output: 198 | if len(output) > 4096: 199 | with open("output.txt", "w+") as file: 200 | file.write(output) 201 | await Anony.send_document( 202 | message.chat.id, 203 | "output.txt", 204 | reply_to_message_id=message.id, 205 | caption="Output", 206 | ) 207 | return os.remove("output.txt") 208 | await edit_or_reply(message, text=f"OUTPUT :\n
{output}
") 209 | else: 210 | await edit_or_reply(message, text="OUTPUT :\nNone") 211 | -------------------------------------------------------------------------------- /StringGen/modules/gen.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram import Client, filters 4 | from oldpyro import Client as Client1 5 | from oldpyro.errors import ApiIdInvalid as ApiIdInvalid1 6 | from oldpyro.errors import PasswordHashInvalid as PasswordHashInvalid1 7 | from oldpyro.errors import PhoneCodeExpired as PhoneCodeExpired1 8 | from oldpyro.errors import PhoneCodeInvalid as PhoneCodeInvalid1 9 | from oldpyro.errors import PhoneNumberInvalid as PhoneNumberInvalid1 10 | from oldpyro.errors import SessionPasswordNeeded as SessionPasswordNeeded1 11 | from pyrogram.errors import ( 12 | ApiIdInvalid, 13 | FloodWait, 14 | PasswordHashInvalid, 15 | PhoneCodeExpired, 16 | PhoneCodeInvalid, 17 | PhoneNumberInvalid, 18 | SessionPasswordNeeded, 19 | ) 20 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 21 | from telethon import TelegramClient 22 | from telethon.errors import ( 23 | ApiIdInvalidError, 24 | PasswordHashInvalidError, 25 | PhoneCodeExpiredError, 26 | PhoneCodeInvalidError, 27 | PhoneNumberInvalidError, 28 | SessionPasswordNeededError, 29 | ) 30 | from telethon.sessions import StringSession 31 | from telethon.tl.functions.channels import JoinChannelRequest 32 | from pyromod.listen.listen import ListenerTimeout 33 | 34 | from config import SUPPORT_CHAT 35 | from StringGen import Anony 36 | from StringGen.utils import retry_key 37 | 38 | 39 | async def gen_session( 40 | message, user_id: int, telethon: bool = False, old_pyro: bool = False 41 | ): 42 | if telethon: 43 | ty = f"ᴛᴇʟᴇᴛʜᴏɴ" 44 | elif old_pyro: 45 | ty = f"ᴩʏʀᴏɢʀᴀᴍ v1" 46 | else: 47 | ty = f"ᴩʏʀᴏɢʀᴀᴍ v2" 48 | 49 | await message.reply_text(f"» ᴛʀʏɪɴɢ ᴛᴏ sᴛᴀʀᴛ {ty} sᴇssɪᴏɴ ɢᴇɴᴇʀᴀᴛᴏʀ...") 50 | 51 | try: 52 | api_id = await Anony.ask( 53 | identifier=(message.chat.id, user_id, None), 54 | text="» ᴘʟᴇᴀsᴇ ᴇɴᴛᴇʀ ʏᴏᴜʀ ᴀᴘɪ ɪᴅ ᴛᴏ ᴘʀᴏᴄᴇᴇᴅ :", 55 | filters=filters.text, 56 | timeout=300, 57 | ) 58 | except ListenerTimeout: 59 | return await Anony.send_message( 60 | user_id, 61 | "» ᴛɪᴍᴇᴅ ʟɪᴍɪᴛ ʀᴇᴀᴄʜᴇᴅ ᴏғ 5 ᴍɪɴᴜᴛᴇs.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 62 | reply_markup=retry_key, 63 | ) 64 | 65 | if await cancelled(api_id): 66 | return 67 | 68 | try: 69 | api_id = int(api_id.text) 70 | except ValueError: 71 | return await Anony.send_message( 72 | user_id, 73 | "» ᴛʜᴇ ᴀᴘɪ ɪᴅ ʏᴏᴜ'ᴠᴇ sᴇɴᴛ ɪs ɪɴᴠᴀʟɪᴅ.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 74 | reply_markup=retry_key, 75 | ) 76 | 77 | try: 78 | api_hash = await Anony.ask( 79 | identifier=(message.chat.id, user_id, None), 80 | text="» ᴘʟᴇᴀsᴇ ᴇɴᴛᴇʀ ʏᴏᴜʀ ᴀᴘɪ ʜᴀsʜ ᴛᴏ ᴘʀᴏᴄᴇᴇᴅ :", 81 | filters=filters.text, 82 | timeout=300, 83 | ) 84 | except ListenerTimeout: 85 | return await Anony.send_message( 86 | user_id, 87 | "» ᴛɪᴍᴇᴅ ʟɪᴍɪᴛ ʀᴇᴀᴄʜᴇᴅ ᴏғ 5 ᴍɪɴᴜᴛᴇs.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 88 | reply_markup=retry_key, 89 | ) 90 | 91 | if await cancelled(api_hash): 92 | return 93 | 94 | api_hash = api_hash.text 95 | 96 | if len(api_hash) < 30: 97 | return await Anony.send_message( 98 | user_id, 99 | "» ᴛʜᴇ ᴀᴘɪ ʜᴀsʜ ʏᴏᴜ'ᴠᴇ sᴇɴᴛ ɪs ɪɴᴠᴀʟɪᴅ.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 100 | reply_markup=retry_key, 101 | ) 102 | 103 | try: 104 | phone_number = await Anony.ask( 105 | identifier=(message.chat.id, user_id, None), 106 | text="» ᴘʟᴇᴀsᴇ ᴇɴᴛᴇʀ ʏᴏᴜʀ ᴘʜᴏɴᴇ ɴᴜᴍʙᴇʀ ᴛᴏ ᴘʀᴏᴄᴇᴇᴅ :", 107 | filters=filters.text, 108 | timeout=300, 109 | ) 110 | except ListenerTimeout: 111 | return await Anony.send_message( 112 | user_id, 113 | "» ᴛɪᴍᴇᴅ ʟɪᴍɪᴛ ʀᴇᴀᴄʜᴇᴅ ᴏғ 5 ᴍɪɴᴜᴛᴇs.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 114 | reply_markup=retry_key, 115 | ) 116 | 117 | if await cancelled(phone_number): 118 | return 119 | phone_number = phone_number.text 120 | 121 | await Anony.send_message(user_id, "» ᴛʀʏɪɴɢ ᴛᴏ sᴇɴᴅ ᴏᴛᴩ ᴀᴛ ᴛʜᴇ ɢɪᴠᴇɴ ɴᴜᴍʙᴇʀ...") 122 | if telethon: 123 | client = TelegramClient(StringSession(), api_id, api_hash) 124 | elif old_pyro: 125 | client = Client1(":memory:", api_id=api_id, api_hash=api_hash) 126 | else: 127 | client = Client(name="Anony", api_id=api_id, api_hash=api_hash, in_memory=True) 128 | await client.connect() 129 | 130 | try: 131 | if telethon: 132 | code = await client.send_code_request(phone_number) 133 | else: 134 | code = await client.send_code(phone_number) 135 | await asyncio.sleep(1) 136 | 137 | except FloodWait as f: 138 | return await Anony.send_message( 139 | user_id, 140 | f"» ғᴀɪʟᴇᴅ ᴛᴏ sᴇɴᴅ ᴄᴏᴅᴇ ғᴏʀ ʟᴏɢɪɴ.\n\nᴘʟᴇᴀsᴇ ᴡᴀɪᴛ ғᴏʀ {f.value or f.x} sᴇᴄᴏɴᴅs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.", 141 | reply_markup=retry_key, 142 | ) 143 | except (ApiIdInvalid, ApiIdInvalidError, ApiIdInvalid1): 144 | return await Anony.send_message( 145 | user_id, 146 | "» ᴀᴘɪ ɪᴅ ᴏʀ ᴀᴘɪ ʜᴀsʜ ɪs ɪɴᴠᴀʟɪᴅ.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 147 | reply_markup=retry_key, 148 | ) 149 | except (PhoneNumberInvalid, PhoneNumberInvalidError, PhoneNumberInvalid1): 150 | return await Anony.send_message( 151 | user_id, 152 | "» ᴘʜᴏɴᴇ ɴᴜᴍʙᴇʀ ɪɴᴠᴀʟɪᴅ.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 153 | reply_markup=retry_key, 154 | ) 155 | 156 | try: 157 | otp = await Anony.ask( 158 | identifier=(message.chat.id, user_id, None), 159 | text=f"ᴘʟᴇᴀsᴇ ᴇɴᴛᴇʀ ᴛʜᴇ ᴏᴛᴘ sᴇɴᴛ ᴛᴏ {phone_number}.\n\nɪғ ᴏᴛᴩ ɪs 12345, ᴩʟᴇᴀsᴇ sᴇɴᴅ ɪᴛ ᴀs 1 2 3 4 5.", 160 | filters=filters.text, 161 | timeout=600, 162 | ) 163 | if await cancelled(otp): 164 | return 165 | except ListenerTimeout: 166 | return await Anony.send_message( 167 | user_id, 168 | "» ᴛɪᴍᴇ ʟɪᴍɪᴛ ʀᴇᴀᴄʜᴇᴅ ᴏғ 10 ᴍɪɴᴜᴛᴇs.\n\nᴩʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 169 | reply_markup=retry_key, 170 | ) 171 | 172 | otp = otp.text.replace(" ", "") 173 | try: 174 | if telethon: 175 | await client.sign_in(phone_number, otp, password=None) 176 | else: 177 | await client.sign_in(phone_number, code.phone_code_hash, otp) 178 | except (PhoneCodeInvalid, PhoneCodeInvalidError, PhoneCodeInvalid1): 179 | return await Anony.send_message( 180 | user_id, 181 | "» ᴛʜᴇ ᴏᴛᴩ ʏᴏᴜ'ᴠᴇ sᴇɴᴛ ɪs ᴡʀᴏɴɢ.\n\nᴩʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 182 | reply_markup=retry_key, 183 | ) 184 | except (PhoneCodeExpired, PhoneCodeExpiredError, PhoneCodeExpired1): 185 | return await Anony.send_message( 186 | user_id, 187 | "» ᴛʜᴇ ᴏᴛᴩ ʏᴏᴜ'ᴠᴇ sᴇɴᴛ ɪs ᴇxᴩɪʀᴇᴅ.\n\nᴩʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 188 | reply_markup=retry_key, 189 | ) 190 | except (SessionPasswordNeeded, SessionPasswordNeededError, SessionPasswordNeeded1): 191 | try: 192 | pwd = await Anony.ask( 193 | identifier=(message.chat.id, user_id, None), 194 | text="» ᴘʟᴇᴀsᴇ ᴇɴᴛᴇʀ ʏᴏᴜʀ ᴛᴡᴏ sᴛᴇᴘ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ᴘᴀssᴡᴏʀᴅ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ :", 195 | filters=filters.text, 196 | timeout=300, 197 | ) 198 | except ListenerTimeout: 199 | return Anony.send_message( 200 | user_id, 201 | "» ᴛɪᴍᴇᴅ ʟɪᴍɪᴛ ʀᴇᴀᴄʜᴇᴅ ᴏғ 5 ᴍɪɴᴜᴛᴇs.\n\nᴘʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 202 | reply_markup=retry_key, 203 | ) 204 | 205 | if await cancelled(pwd): 206 | return 207 | pwd = pwd.text 208 | 209 | try: 210 | if telethon: 211 | await client.sign_in(password=pwd) 212 | else: 213 | await client.check_password(password=pwd) 214 | except (PasswordHashInvalid, PasswordHashInvalidError, PasswordHashInvalid1): 215 | return await Anony.send_message( 216 | user_id, 217 | "» ᴛʜᴇ ᴩᴀssᴡᴏʀᴅ ʏᴏᴜ'ᴠᴇ sᴇɴᴛ ɪs ᴡʀᴏɴɢ.\n\nᴩʟᴇᴀsᴇ sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ ʏᴏᴜʀ sᴇssɪᴏɴ ᴀɢᴀɪɴ.", 218 | reply_markup=retry_key, 219 | ) 220 | 221 | except Exception as ex: 222 | return await Anony.send_message(user_id, f"ᴇʀʀᴏʀ : {str(ex)}") 223 | 224 | try: 225 | txt = "ʜᴇʀᴇ ɪs ʏᴏᴜʀ {0} sᴛʀɪɴɢ sᴇssɪᴏɴ\n\n{1}\n\nᴀ sᴛʀɪɴɢ ɢᴇɴᴇʀᴀᴛᴏʀ ʙᴏᴛ ʙʏ ғᴀʟʟᴇɴ ᴀssᴏᴄɪᴀᴛɪᴏɴ\n☠ ɴᴏᴛᴇ : ᴅᴏɴ'ᴛ sʜᴀʀᴇ ɪᴛ ᴡɪᴛʜ ʏᴏᴜʀ ɢɪʀʟғʀɪᴇɴᴅ." 226 | if telethon: 227 | string_session = client.session.save() 228 | await client.send_message( 229 | "me", 230 | txt.format(ty, string_session, SUPPORT_CHAT), 231 | link_preview=False, 232 | parse_mode="html", 233 | ) 234 | await client(JoinChannelRequest("@FallenAssociation")) 235 | else: 236 | string_session = await client.export_session_string() 237 | await client.send_message( 238 | "me", 239 | txt.format(ty, string_session, SUPPORT_CHAT), 240 | disable_web_page_preview=True, 241 | ) 242 | await client.join_chat("FallenAssociation") 243 | except KeyError: 244 | pass 245 | try: 246 | await client.disconnect() 247 | await Anony.send_message( 248 | chat_id=user_id, 249 | text=f"sᴜᴄᴄᴇssғᴜʟʟʏ ɢᴇɴᴇʀᴀᴛᴇᴅ ʏᴏᴜʀ {ty} sᴛʀɪɴɢ sᴇssɪᴏɴ.\n\nᴘʟᴇᴀsᴇ ᴄʜᴇᴄᴋ ʏᴏᴜʀ sᴀᴠᴇᴅ ᴍᴇssᴀɢᴇs ғᴏʀ ɢᴇᴛᴛɪɴɢ ɪᴛ.\n\nᴀ sᴛʀɪɴɢ ɢᴇɴᴇʀᴀᴛᴏʀ ʙᴏᴛ ʙʏ ғᴀʟʟᴇɴ ᴀssᴏᴄɪᴀᴛɪᴏɴ.", 250 | reply_markup=InlineKeyboardMarkup( 251 | [ 252 | [ 253 | InlineKeyboardButton( 254 | text="sᴀᴠᴇᴅ ᴍᴇssᴀɢᴇs", 255 | url=f"tg://openmessage?user_id={user_id}", 256 | ) 257 | ] 258 | ] 259 | ), 260 | disable_web_page_preview=True, 261 | ) 262 | except: 263 | pass 264 | 265 | 266 | async def cancelled(message): 267 | if "/cancel" in message.text: 268 | await message.reply_text( 269 | "» ᴄᴀɴᴄᴇʟʟᴇᴅ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀɪɴɢ ɢᴇɴᴇʀᴀᴛɪᴏɴ ᴩʀᴏᴄᴇss.", reply_markup=retry_key 270 | ) 271 | return True 272 | elif "/restart" in message.text: 273 | await message.reply_text( 274 | "» sᴜᴄᴄᴇssғᴜʟʟʏ ʀᴇsᴛᴀʀᴛᴇᴅ ᴛʜɪs ʙᴏᴛ.", reply_markup=retry_key 275 | ) 276 | return True 277 | elif message.text.startswith("/"): 278 | await message.reply_text( 279 | "» ᴄᴀɴᴄᴇʟʟᴇᴅ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀɪɴɢ ɢᴇɴᴇʀᴀᴛɪᴏɴ ᴩʀᴏᴄᴇss.", reply_markup=retry_key 280 | ) 281 | return True 282 | else: 283 | return False 284 | -------------------------------------------------------------------------------- /StringGen/modules/start.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import Message 3 | 4 | from StringGen import Anony 5 | from StringGen.utils import add_served_user, keyboard 6 | 7 | 8 | @Anony.on_message(filters.command("start") & filters.private & filters.incoming) 9 | async def f_start(_, message: Message): 10 | await message.reply_text( 11 | text=f"ʜᴇʏ {message.from_user.first_name},\n\n๏ ᴛʜɪs ɪs {Anony.mention},\nAɴ ᴏᴘᴇɴ sᴏᴜʀᴄᴇ sᴛʀɪɴɢ sᴇssɪᴏɴ ɢᴇɴᴇʀᴀᴛᴏʀ ʙᴏᴛ, ᴡʀɪᴛᴛᴇɴ ɪɴ ᴩʏᴛʜᴏɴ ᴡɪᴛʜ ᴛʜᴇ ʜᴇʟᴩ ᴏғ ᴩʏʀᴏɢʀᴀᴍ.", 12 | reply_markup=keyboard, 13 | disable_web_page_preview=True, 14 | ) 15 | await add_served_user(message.from_user.id) 16 | -------------------------------------------------------------------------------- /StringGen/modules/stats.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import Message 3 | 4 | from config import OWNER_ID 5 | from StringGen import Anony 6 | from StringGen.utils import get_served_users 7 | 8 | 9 | @Anony.on_message(filters.command(["stats", "users"]) & filters.user(OWNER_ID)) 10 | async def get_stats(_, message: Message): 11 | users = len(await get_served_users()) 12 | await message.reply_text(f"» ᴄᴜʀʀᴇɴᴛ sᴛᴀᴛs ᴏғ {Anony.name} :\n\n {users} ᴜsᴇʀs") 13 | -------------------------------------------------------------------------------- /StringGen/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .inline import * 2 | from .users import * 3 | -------------------------------------------------------------------------------- /StringGen/utils/inline.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 2 | 3 | from config import SUPPORT_CHAT 4 | 5 | 6 | keyboard = InlineKeyboardMarkup( 7 | [ 8 | [InlineKeyboardButton(text="ɢᴇɴᴇʀᴀᴛᴇ sᴇssɪᴏɴ", callback_data="gensession")], 9 | [ 10 | InlineKeyboardButton(text="sᴜᴘᴘᴏʀᴛ", url=SUPPORT_CHAT), 11 | InlineKeyboardButton( 12 | text="sᴏᴜʀᴄᴇ", url="https://github.com/AnonymousX1025/StringGenBot" 13 | ), 14 | ], 15 | ] 16 | ) 17 | 18 | gen_key = InlineKeyboardMarkup( 19 | [ 20 | [ 21 | InlineKeyboardButton(text="ᴩʏʀᴏɢʀᴀᴍ v1", callback_data="pyrogram1"), 22 | InlineKeyboardButton(text="ᴩʏʀᴏɢʀᴀᴍ v2", callback_data="pyrogram"), 23 | ], 24 | [InlineKeyboardButton(text="ᴛᴇʟᴇᴛʜᴏɴ", callback_data="telethon")], 25 | ] 26 | ) 27 | 28 | retry_key = InlineKeyboardMarkup( 29 | [[InlineKeyboardButton(text="ᴛʀʏ ᴀɢᴀɪɴ", callback_data="gensession")]] 30 | ) 31 | -------------------------------------------------------------------------------- /StringGen/utils/users.py: -------------------------------------------------------------------------------- 1 | from StringGen import db 2 | 3 | usersdb = db.users 4 | 5 | 6 | async def is_served_user(user_id: int) -> bool: 7 | user = await usersdb.find_one({"user_id": user_id}) 8 | if not user: 9 | return False 10 | return True 11 | 12 | 13 | async def get_served_users() -> list: 14 | users_list = [] 15 | async for user in usersdb.find({"user_id": {"$gt": 0}}): 16 | users_list.append(user) 17 | return users_list 18 | 19 | 20 | async def add_served_user(user_id: int): 21 | is_served = await is_served_user(user_id) 22 | if is_served: 23 | return 24 | return await usersdb.insert_one({"user_id": user_id}) 25 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "String Gen Bot", 3 | "description": "A Telegram Bot to generate Telethon and Pyrogram String Session.", 4 | "logo": "https://telegra.ph/file/654ddaf472f18b799600b.jpg", 5 | "keywords": [ 6 | "python3", 7 | "telegram", 8 | "session", 9 | "stringbot", 10 | "telegram-bot", 11 | "pyrogram", 12 | "telethon" 13 | ], 14 | "repository": "https://github.com/AnonymousX1025/StringGenBot", 15 | "env": { 16 | "API_ID": { 17 | "description": "Get this value from https://my.telegram.org", 18 | "value": "", 19 | "required": true 20 | }, 21 | "API_HASH": { 22 | "description": "Get this value from https://my.telegram.org", 23 | "value": "", 24 | "required": true 25 | }, 26 | "BOT_TOKEN": { 27 | "description": "A Bot's token from Botfather", 28 | "value": "", 29 | "required": true 30 | }, 31 | "OWNER_ID": { 32 | "description": "Fill your user id here. (Must be integer)", 33 | "value": "", 34 | "required": true 35 | }, 36 | "MONGO_DB_URI": { 37 | "description": "Get this value from cloud.mongodb.com", 38 | "value": "", 39 | "required": true 40 | } 41 | }, 42 | "buildpacks": [ 43 | { 44 | "url": "heroku/python" 45 | } 46 | ], 47 | "stack": "container" 48 | } 49 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | from os import getenv 2 | 3 | from dotenv import load_dotenv 4 | 5 | load_dotenv() 6 | 7 | 8 | API_ID = int(getenv("API_ID")) 9 | API_HASH = getenv("API_HASH") 10 | 11 | BOT_TOKEN = getenv("BOT_TOKEN") 12 | MONGO_DB_URI = getenv("MONGO_DB_URI", None) 13 | 14 | OWNER_ID = int(getenv("OWNER_ID", 1356469075)) 15 | SUPPORT_CHAT = getenv("SUPPORT_CHAT", "https://t.me/FallenAssociation") 16 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | run: 5 | worker: bash start 6 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | motor==3.6.0 2 | pyromod==2.0.0 3 | oldpyro==0.1.0 4 | pyrogram==2.0.106 5 | python-dotenv==1.0.1 6 | telethon==1.37.0 7 | tgcrypto==1.2.5 8 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.11.4 2 | -------------------------------------------------------------------------------- /sample.env: -------------------------------------------------------------------------------- 1 | API_ID= 2 | API_HASH= 3 | BOT_TOKEN= 4 | OWNER_ID= 5 | MONGO_DB_URI= 6 | -------------------------------------------------------------------------------- /start: -------------------------------------------------------------------------------- 1 | python3 -m StringGen 2 | --------------------------------------------------------------------------------