├── bot ├── core │ ├── __init__.py │ ├── headers.py │ ├── registrator.py │ ├── agents.py │ └── tapper.py ├── __init__.py ├── config │ ├── __init__.py │ ├── proxies.txt │ └── config.py ├── exceptions │ └── __init__.py └── utils │ ├── __init__.py │ ├── logger.py │ └── launcher.py ├── .env-example ├── docker-compose.yml ├── main.py ├── Dockerfile ├── requirements.txt ├── run.bat ├── run.sh ├── .gitignore ├── README-EN.md └── README.md /bot/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bot/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.0' 2 | -------------------------------------------------------------------------------- /bot/config/__init__.py: -------------------------------------------------------------------------------- 1 | from .config import settings 2 | -------------------------------------------------------------------------------- /bot/exceptions/__init__.py: -------------------------------------------------------------------------------- 1 | class InvalidSession(BaseException): 2 | ... 3 | -------------------------------------------------------------------------------- /bot/config/proxies.txt: -------------------------------------------------------------------------------- 1 | type://user:pass@ip:port 2 | type://user:pass:ip:port 3 | type://ip:port:user:pass 4 | type://ip:port@user:pass 5 | type://ip:port -------------------------------------------------------------------------------- /.env-example: -------------------------------------------------------------------------------- 1 | API_ID= 2 | API_HASH= 3 | 4 | SLEEP_BETWEEN_CLAIM= 5 | TAPS_COUNT= 6 | MOON_BONUS= 7 | BUY_BOOST= 8 | CLAIM_MOON= 9 | DEFAULT_BOOST= 10 | USE_PROXY_FROM_FILE= -------------------------------------------------------------------------------- /bot/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .logger import logger 2 | from . import launcher 3 | 4 | 5 | import os 6 | 7 | if not os.path.exists(path="sessions"): 8 | os.mkdir(path="sessions") 9 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | bot: 4 | container_name: 'MMProBumpBot' 5 | build: 6 | context: . 7 | stop_signal: SIGINT 8 | restart: unless-stopped 9 | command: "python3 main.py -a 2" 10 | volumes: 11 | - .:/app -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from contextlib import suppress 3 | 4 | from bot.utils.launcher import process 5 | 6 | 7 | async def main(): 8 | await process() 9 | 10 | 11 | if __name__ == '__main__': 12 | with suppress(KeyboardInterrupt): 13 | asyncio.run(main()) 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10.11-alpine3.18 2 | 3 | WORKDIR app/ 4 | 5 | COPY requirements.txt requirements.txt 6 | 7 | RUN pip3 install --upgrade pip setuptools wheel 8 | RUN pip3 install --no-warn-script-location --no-cache-dir -r requirements.txt 9 | 10 | COPY . . 11 | 12 | CMD ["python3", "main.py", "-a", "2"] -------------------------------------------------------------------------------- /bot/utils/logger.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from loguru import logger 3 | 4 | 5 | logger.remove() 6 | logger.add(sink=sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss}" 7 | " | {level: <8}" 8 | " | {line}" 9 | " - {message}") 10 | logger = logger.opt(colors=True) 11 | -------------------------------------------------------------------------------- /bot/core/headers.py: -------------------------------------------------------------------------------- 1 | headers = { 2 | 'Accept': '*/*', 3 | 'Accept-Language': 'ru-RU,ru;q=0.9', 4 | 'Connection': 'keep-alive', 5 | 'Content-Type': 'application/json; charset=utf-8', 6 | 'Origin': 'https://mmbump.pro', 7 | 'Referer': 'https://mmbump.pro/', 8 | 'Sec-Fetch-Dest': 'empty', 9 | 'Sec-Fetch-Mode': 'cors', 10 | 'Sec-Fetch-Site': 'cross-site', 11 | 'Sec-Ch-Ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"', 12 | 'Sec-Ch-Ua-Mobile': '?1', 13 | 'Sec-Ch-Ua-Platform': 'Android', 14 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiocfscrape==1.0.0 2 | aiohttp==3.9.3 3 | aiohttp-proxy==0.1.2 4 | aiosignal==1.3.1 5 | annotated-types==0.6.0 6 | async-timeout==4.0.3 7 | attrs==23.2.0 8 | beautifulsoup4==4.12.3 9 | better-proxy==1.1.5 10 | colorama==0.4.6 11 | DateTime==5.5 12 | frozenlist==1.4.1 13 | idna==3.6 14 | Js2Py==0.74 15 | loguru==0.7.2 16 | multidict==6.0.5 17 | pyaes==1.6.1 18 | pydantic==2.6.4 19 | pydantic-settings==2.2.1 20 | pydantic_core==2.16.3 21 | pyjsparser==2.7.1 22 | Pyrogram==2.0.106 23 | PySocks==1.7.1 24 | python-dotenv==1.0.1 25 | pytz==2024.1 26 | six==1.16.0 27 | soupsieve==2.5 28 | TgCrypto==1.2.5 29 | typing_extensions==4.11.0 30 | tzdata==2024.1 31 | tzlocal==5.2 32 | websockets==12.0 33 | win32-setctime==1.1.0 34 | yarl==1.9.4 35 | zope.interface==6.4.post2 36 | -------------------------------------------------------------------------------- /bot/config/config.py: -------------------------------------------------------------------------------- 1 | from pydantic_settings import BaseSettings, SettingsConfigDict 2 | 3 | 4 | class Settings(BaseSettings): 5 | model_config = SettingsConfigDict(env_file=".env", env_ignore_empty=True) 6 | 7 | API_ID: int 8 | API_HASH: str 9 | 10 | FARM_TIME: int = 21600 # 6 hours 11 | TAPS_COUNT: list[int] = [50000, 100000] 12 | SLEEP_BETWEEN_CLAIM: list[int] = [3600, 5600] 13 | MOON_BONUS: int = 1000000 14 | BUY_BOOST: bool = True 15 | # AUTO_TASK: bool = True 16 | CLAIM_MOON: bool = True 17 | DEFAULT_BOOST: str = "x3" 18 | BOOSTERS: dict = { 19 | "x2": 4000000, 20 | "x3": 30000000, 21 | "x5": 200000000 22 | } 23 | USE_PROXY_FROM_FILE: bool = False 24 | 25 | 26 | settings = Settings() 27 | 28 | 29 | -------------------------------------------------------------------------------- /bot/core/registrator.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client 2 | 3 | from bot.config import settings 4 | from bot.utils import logger 5 | 6 | 7 | async def register_sessions() -> None: 8 | API_ID = settings.API_ID 9 | API_HASH = settings.API_HASH 10 | 11 | if not API_ID or not API_HASH: 12 | raise ValueError("API_ID and API_HASH not found in the .env file.") 13 | 14 | session_name = input('\nEnter the session name (press Enter to exit): ') 15 | 16 | if not session_name: 17 | return None 18 | 19 | session = Client( 20 | name=session_name, 21 | api_id=API_ID, 22 | api_hash=API_HASH, 23 | workdir="sessions/" 24 | ) 25 | 26 | async with session: 27 | user_data = await session.get_me() 28 | 29 | logger.success(f'Session added successfully @{user_data.username} | {user_data.first_name} {user_data.last_name}') 30 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist venv ( 4 | echo Creating virtual environment... 5 | python -m venv venv 6 | ) 7 | 8 | echo Activating virtual environment... 9 | call venv\Scripts\activate 10 | 11 | if not exist venv\Lib\site-packages\installed ( 12 | if exist requirements.txt ( 13 | echo installing wheel for faster installing 14 | pip install wheel 15 | echo Installing dependencies... 16 | pip install -r requirements.txt 17 | echo. > venv\Lib\site-packages\installed 18 | ) else ( 19 | echo requirements.txt not found, skipping dependency installation. 20 | ) 21 | ) else ( 22 | echo Dependencies already installed, skipping installation. 23 | ) 24 | 25 | if not exist .env ( 26 | echo Copying configuration file 27 | copy .env-example .env 28 | ) else ( 29 | echo Skipping .env copying 30 | ) 31 | 32 | echo Starting the bot... 33 | python main.py 34 | 35 | echo done 36 | echo PLEASE EDIT .ENV FILE 37 | pause 38 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Проверка на наличие папки venv 4 | if [ ! -d "venv" ]; then 5 | echo "Creating virtual environment..." 6 | python3 -m venv venv 7 | fi 8 | 9 | echo "Activating virtual environment..." 10 | source venv/bin/activate 11 | 12 | # Проверка на наличие установленного флага в виртуальном окружении 13 | if [ ! -f "venv/installed" ]; then 14 | if [ -f "requirements.txt" ]; then 15 | echo "Installing wheel for faster installing" 16 | pip3 install wheel 17 | echo "Installing dependencies..." 18 | pip3 install -r requirements.txt 19 | touch venv/installed 20 | else 21 | echo "requirements.txt not found, skipping dependency installation." 22 | fi 23 | else 24 | echo "Dependencies already installed, skipping installation." 25 | fi 26 | 27 | if [ ! -f ".env" ]; then 28 | echo "Copying configuration file" 29 | cp .env-example .env 30 | else 31 | echo "Skipping .env copying" 32 | fi 33 | 34 | echo "Starting the bot..." 35 | python3 main.py 36 | 37 | echo "done" 38 | echo "PLEASE EDIT .ENV FILE" 39 | -------------------------------------------------------------------------------- /bot/utils/launcher.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import asyncio 4 | import argparse 5 | from itertools import cycle 6 | 7 | from pyrogram import Client 8 | from better_proxy import Proxy 9 | 10 | from bot.config import settings 11 | from bot.utils import logger 12 | from bot.core.tapper import run_tapper 13 | from bot.core.registrator import register_sessions 14 | 15 | 16 | start_text = """ 17 | 18 | 19 | +-------------------------------------+ 20 | | | 21 | | MMProBumpBot | 22 | | by scriptron | 23 | | https://t.me/scriptron | 24 | | | 25 | +-------------------------------------+ 26 | 27 | Select an action: 28 | 29 | 1. Run clicker 30 | 2. Create session 31 | """ 32 | 33 | global tg_clients 34 | 35 | def get_session_names() -> list[str]: 36 | session_names = glob.glob("sessions/*.session") 37 | session_names = [ 38 | os.path.splitext(os.path.basename(file))[0] for file in session_names 39 | ] 40 | 41 | return session_names 42 | 43 | 44 | def get_proxies() -> list[Proxy]: 45 | if settings.USE_PROXY_FROM_FILE: 46 | with open(file="bot/config/proxies.txt", encoding="utf-8-sig") as file: 47 | proxies = [Proxy.from_str(proxy=row.strip()).as_url for row in file] 48 | else: 49 | proxies = [] 50 | 51 | return proxies 52 | 53 | 54 | async def get_tg_clients() -> list[Client]: 55 | global tg_clients 56 | 57 | session_names = get_session_names() 58 | 59 | if not session_names: 60 | raise FileNotFoundError("Not found session files") 61 | 62 | if not settings.API_ID or not settings.API_HASH: 63 | raise ValueError("API_ID and API_HASH not found in the .env file.") 64 | 65 | tg_clients = [ 66 | Client( 67 | name=session_name, 68 | api_id=settings.API_ID, 69 | api_hash=settings.API_HASH, 70 | workdir="sessions/", 71 | plugins=dict(root="bot/plugins"), 72 | ) 73 | for session_name in session_names 74 | ] 75 | 76 | return tg_clients 77 | 78 | 79 | async def process() -> None: 80 | parser = argparse.ArgumentParser() 81 | parser.add_argument("-a", "--action", type=int, help="Action to perform") 82 | 83 | logger.info(f"Detected {len(get_session_names())} sessions | {len(get_proxies())} proxies") 84 | 85 | action = parser.parse_args().action 86 | 87 | if not action: 88 | print(start_text) 89 | 90 | while True: 91 | action = input("> ") 92 | 93 | if not action.isdigit(): 94 | logger.warning("Action must be number") 95 | elif action not in ["1", "2"]: 96 | logger.warning("Action must be 1 or 2") 97 | else: 98 | action = int(action) 99 | break 100 | 101 | if action == 2: 102 | await register_sessions() 103 | elif action == 1: 104 | tg_clients = await get_tg_clients() 105 | 106 | await run_tasks(tg_clients=tg_clients) 107 | 108 | 109 | async def run_tasks(tg_clients: list[Client]): 110 | proxies = get_proxies() 111 | proxies_cycle = cycle(proxies) if proxies else None 112 | tasks = [ 113 | asyncio.create_task( 114 | run_tapper( 115 | tg_client=tg_client, 116 | proxy=next(proxies_cycle) if proxies_cycle else None, 117 | ) 118 | ) 119 | for tg_client in tg_clients 120 | ] 121 | 122 | await asyncio.gather(*tasks) 123 | -------------------------------------------------------------------------------- /.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 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | *.session 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # DB 65 | sessions/ 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # poetry 101 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 102 | # This is especially recommended for binary packages to ensure reproducibility, and is more 103 | # commonly ignored for libraries. 104 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 105 | #poetry.lock 106 | 107 | # pdm 108 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 109 | #pdm.lock 110 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 111 | # in version control. 112 | # https://pdm.fming.dev/#use-with-ide 113 | .pdm.toml 114 | 115 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 116 | __pypackages__/ 117 | 118 | # Celery stuff 119 | celerybeat-schedule 120 | celerybeat.pid 121 | 122 | # SageMath parsed files 123 | *.sage.py 124 | 125 | # Environments 126 | .env 127 | .venv 128 | env/ 129 | venv/ 130 | ENV/ 131 | env.bak/ 132 | venv.bak/ 133 | 134 | # Spyder project settings 135 | .spyderproject 136 | .spyproject 137 | 138 | # Rope project settings 139 | .ropeproject 140 | 141 | # mkdocs documentation 142 | /site 143 | 144 | # mypy 145 | .mypy_cache/ 146 | .dmypy.json 147 | dmypy.json 148 | 149 | # Pyre type checker 150 | .pyre/ 151 | 152 | # pytype static type analyzer 153 | .pytype/ 154 | 155 | # Cython debug symbols 156 | cython_debug/ 157 | 158 | # PyCharm 159 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 160 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 161 | # and can be added to the global gitignore or merged into this file. For a more nuclear 162 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 163 | .idea/ 164 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | [![Static Badge](https://img.shields.io/badge/Telegram-Bot%20Link-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/MMProBumpBot?start=ref_6597427426) 2 | ### [MMProBump link](https://t.me/MMProBumpBot?start=ref_6597427426) 3 | 4 | > 🇷🇺#### Join my [Telegram channel](https://t.me/scriptron). I will be posting news about new bots and scripts there. 5 | ## Important Notes 6 | 7 | > 🇪🇳 README на русском [тут](README-RU.md) 8 | 9 | - **Python Version:** The software runs on Python 3.10, Python 3.11. Using a different version may cause errors. 10 | - DONT USE MAIN ACCOUNT BECAUSE THERE IS ALWAYS A CHANCE TO GET BANNED IN TELEGRAM 11 | 12 | ## Features 13 | | Feature | Supported | 14 | |-----------------------------------------------------------|:---------:| 15 | | Multithreading | ✅ | 16 | | Proxy binding to session | ✅ | 17 | | Support for tdata / pyrogram .session / telethon .session | ✅ | 18 | | Auto-farming | ✅ | 19 | | Auto-taps | ✅ | 20 | | Collect bonus in every farming cycle | ✅ | 21 | | Auto-boost | ✅ | 22 | | Auto-daily | ✅ | 23 | 24 | 25 | ## [Settings](https://github.com/Re-Diss/MMProBumpBot/blob/master/.env-example/) 26 | | Settings | Description | 27 | |-------------------------|:---------------------------------------------------------------------------:| 28 | | **API_ID / API_HASH** | Platform data from which to run the Telegram session (by default - android) | 29 | | **SLEEP_BETWEEN_CLAIM** | Sleep before claiming the reward, by default: [3600, 5600] seconds | 30 | | **TAPS_COUNT** | How much clicks bot will get in farm cycle (by default - [50000, 100000]) | 31 | | **CLAIM_MOON** | Collecting a farm bonus (by default - True) | 32 | | **MOON_BONUS** | Moon-Bonus count (by default - 1000000) | 33 | | **BUY_BOOST** | Buying a boost (by default - True) | 34 | | **DEFAULT_BOOST** | Boost type (by default - "x3") | 35 | | **USE_PROXY_FROM_FILE** | Whether to use a proxy from the bot/config/proxies.txt file (True / False) | 36 | 37 | ## Quick Start 📚 38 | 39 | To fast install libraries and run bot - open run.bat on Windows or run.sh on Linux 40 | 41 | ## Prerequisites 42 | Before you begin, make sure you have the following installed: 43 | - [Python](https://www.python.org/downloads/) **version 3.10** 44 | 45 | ## Obtaining API Keys 46 | 1. Go to my.telegram.org and log in using your phone number. 47 | 2. Select "API development tools" and fill out the form to register a new application. 48 | 3. Record the API_ID and API_HASH provided after registering your application in the .env file. 49 | 50 | ## Installation 51 | You can download the [**repository**](https://github.com/Re-Diss/MMProBumpBot) by cloning it to your system and installing the necessary dependencies: 52 | ```shell 53 | git clone https://github.com/Re-Diss/MMProBumpBot.git 54 | cd MMProBumpBot 55 | ``` 56 | 57 | Then you can do automatic installation by typing: 58 | 59 | Windows: 60 | ```shell 61 | run.bat 62 | ``` 63 | 64 | Linux: 65 | ```shell 66 | run.sh 67 | ``` 68 | 69 | # Linux manual installation 70 | ```shell 71 | python3 -m venv venv 72 | source venv/bin/activate 73 | pip3 install -r requirements.txt 74 | cp .env-example .env 75 | nano .env # Here you must specify your API_ID and API_HASH, the rest is taken by default 76 | python3 main.py 77 | ``` 78 | 79 | You can also use arguments for quick start, for example: 80 | ```shell 81 | ~/MMProBumpBot >>> python3 main.py --action (1/2) 82 | # Or 83 | ~/MMProBumpBot >>> python3 main.py -a (1/2) 84 | 85 | # 1 - Run clicker 86 | # 2 - Creates a session 87 | ``` 88 | 89 | # Windows manual installation 90 | ```shell 91 | python -m venv venv 92 | venv\Scripts\activate 93 | pip install -r requirements.txt 94 | copy .env-example .env 95 | # Here you must specify your API_ID and API_HASH, the rest is taken by default 96 | python main.py 97 | ``` 98 | 99 | You can also use arguments for quick start, for example: 100 | ```shell 101 | ~/MMProBumpBot >>> python main.py --action (1/2) 102 | # Or 103 | ~/MMProBumpBot >>> python main.py -a (1/2) 104 | 105 | # 1 - Run clicker 106 | # 2 - Creates a session 107 | ``` 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Static Badge](https://img.shields.io/badge/Telegram-Bot%20Link-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/MMProBumpBot?start=ref_6597427426) 2 | 3 | ### [MMProBumpBot ссылка](https://t.me/MMProBumpBot?start=ref_6597427426) 4 | 5 | #### Подписывайтесь на наш [телеграм канал](https://t.me/scriptron). Там будут новости о новый ботах 6 | > 🇪🇳 README in English available [here](README-EN.md) 7 | ## Важно 8 | 9 | - **Python Version:** Программное обеспечение работает на Python 3.10, Python 3.11. Использование другой версии может привести к ошибкам. 10 | - НЕ ИСПОЛЬЗУЙТЕ ОСНОВНОЙ АККАУНТ, ПОТОМУ ЧТО ВСЕГДА ЕСТЬ ШАНС ПОЛУЧИТЬ БАН В TELEGRAM 11 | 12 | ## Функционал 13 | | Функционал | Поддерживается | 14 | |---------------------------------------------------------|:------------:| 15 | | Многопоточность | ✅ | 16 | | Поддержка tdata / pyrogram .session / telethon .session | ✅ | 17 | | Привязка прокси к сессии | ✅ | 18 | | Автофарминг | ✅ | 19 | | Автоклики | ✅ | 20 | | Сбор бонуса в каждом цикле фарма | ✅ | 21 | | Автопокупка буста | ✅ | 22 | | Сбор ежедневных наград | ✅ | 23 | 24 | 25 | 26 | ## [Настройки](https://github.com/Re-Diss/MMProBumpBot/blob/master/.env-example/) 27 | | Настройка | Описание | 28 | |-------------------------|:--------------------------------------------------------------------------:| 29 | | **API_ID / API_HASH** | Данные платформы, с которой запускать сессию Telegram (сток - Android) | 30 | | **SLEEP_BETWEEN_CLAIM** | Задержка перед сбором прибыли по умолчанию [3600, 5600] секунд | 31 | | **TAPS_COUNT** | Сколько тапов сделает бот за 1 цикл фарма (по умолчанию - [50000, 100000]) | 32 | | **CLAIM_MOON** | Сбор фарм бонуса (по умолчанию - True) | 33 | | **MOON_BONUS** | Размер бонуса (по умолчанию - 1000000) | 34 | | **BUY_BOOST** | Покупка буста (по умолчанию - True) | 35 | | **DEFAULT_BOOST** | Тип буста (по умолчанию - "x3") | 36 | | **USE_PROXY_FROM_FILE** | Использовать-ли прокси из файла `bot/config/proxies.txt` (True / False) | 37 | 38 | ## Быстрый старт 📚 39 | 40 | Для быстрой установки и последующего запуска - запустите файл run.bat на Windows или run.sh на Линукс 41 | 42 | ## Предварительные условия 43 | Прежде чем начать, убедитесь, что у вас установлено следующее: 44 | - [Python](https://www.python.org/downloads/) **версии 3.10** 45 | 46 | ## Получение API ключей 47 | 1. Перейдите на сайт [my.telegram.org](https://my.telegram.org) и войдите в систему, используя свой номер телефона. 48 | 2. Выберите **"API development tools"** и заполните форму для регистрации нового приложения. 49 | 3. Запишите `API_ID` и `API_HASH` в файле `.env`, предоставленные после регистрации вашего приложения. 50 | 51 | ## Установка 52 | Вы можете скачать [**Репозиторий**](https://github.com/Re-Diss/MMProBumpBot) клонированием на вашу систему и установкой необходимых зависимостей: 53 | ```shell 54 | git clone https://github.com/Re-Diss/MMProBumpBot.git 55 | cd MMProBumpBot 56 | ``` 57 | 58 | Затем для автоматической установки введите: 59 | 60 | Windows: 61 | ```shell 62 | run.bat 63 | ``` 64 | 65 | Linux: 66 | ```shell 67 | run.sh 68 | ``` 69 | 70 | # Linux ручная установка 71 | ```shell 72 | python3 -m venv venv 73 | source venv/bin/activate 74 | pip3 install -r requirements.txt 75 | cp .env-example .env 76 | nano .env # Здесь вы обязательно должны указать ваши API_ID и API_HASH , остальное берется по умолчанию 77 | python3 main.py 78 | ``` 79 | 80 | Также для быстрого запуска вы можете использовать аргументы, например: 81 | ```shell 82 | ~/MMProBumpBot >>> python3 main.py --action (1/2) 83 | # Or 84 | ~/MMProBumpBot >>> python3 main.py -a (1/2) 85 | 86 | # 1 - Запускает кликер 87 | # 2 - Создает сессию 88 | ``` 89 | 90 | 91 | # Windows ручная установка 92 | ```shell 93 | python -m venv venv 94 | venv\Scripts\activate 95 | pip install -r requirements.txt 96 | copy .env-example .env 97 | # Указываете ваши API_ID и API_HASH, остальное берется по умолчанию 98 | python main.py 99 | ``` 100 | 101 | Также для быстрого запуска вы можете использовать аргументы, например: 102 | ```shell 103 | ~/MMProBumpBot >>> python main.py --action (1/2) 104 | # Или 105 | ~/MMProBumpBot >>> python main.py -a (1/2) 106 | 107 | # 1 - Запускает кликер 108 | # 2 - Создает сессию 109 | ``` 110 | -------------------------------------------------------------------------------- /bot/core/agents.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def generate_random_user_agent(): 5 | ua_list = [ 6 | # Samsung Galaxy S22 5G 7 | "Mozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 8 | "Mozilla/5.0 (Linux; Android 13; SM-S901U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 9 | 10 | # Samsung Galaxy S22 Ultra 5G 11 | "Mozilla/5.0 (Linux; Android 13; SM-S908B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 12 | "Mozilla/5.0 (Linux; Android 13; SM-S908U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", 13 | 14 | # Samsung Galaxy S21 5G 15 | "Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 16 | "Mozilla/5.0 (Linux; Android 13; SM-G991U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 17 | 18 | # Samsung Galaxy S21 Ultra 5G 19 | "Mozilla/5.0 (Linux; Android 13; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 20 | "Mozilla/5.0 (Linux; Android 13; SM-G998U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 21 | 22 | # Samsung Galaxy A53 5G 23 | "Mozilla/5.0 (Linux; Android 13; SM-A536B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 24 | "Mozilla/5.0 (Linux; Android 13; SM-A536U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 25 | 26 | # Samsung Galaxy A51 27 | "Mozilla/5.0 (Linux; Android 13; SM-A515F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 28 | "Mozilla/5.0 (Linux; Android 13; SM-A515U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 29 | 30 | # Samsung Galaxy S10 31 | "Mozilla/5.0 (Linux; Android 12; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 32 | "Mozilla/5.0 (Linux; Android 12; SM-G973U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 33 | 34 | # Google Pixel 6 35 | "Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 36 | 37 | # Google Pixel 6a 38 | "Mozilla/5.0 (Linux; Android 13; Pixel 6a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 39 | 40 | # Google Pixel 6 Pro 41 | "Mozilla/5.0 (Linux; Android 13; Pixel 6 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 42 | 43 | # Google Pixel 7 44 | "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 45 | 46 | # Google Pixel 7 Pro 47 | "Mozilla/5.0 (Linux; Android 13; Pixel 7 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 48 | 49 | # Motorola Moto G Pure 50 | "Mozilla/5.0 (Linux; Android 12; moto g pure) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 51 | 52 | # Motorola Moto G Stylus 5G 53 | "Mozilla/5.0 (Linux; Android 12; moto g stylus 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 54 | 55 | # Motorola Moto G Stylus 5G (2022) 56 | "Mozilla/5.0 (Linux; Android 12; moto g stylus 5G (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 57 | 58 | # Motorola Moto G 5G (2022) 59 | "Mozilla/5.0 (Linux; Android 12; moto g 5G (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 60 | 61 | # Motorola Moto G Power (2022) 62 | "Mozilla/5.0 (Linux; Android 12; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 63 | 64 | # Motorola Moto G Power (2021) 65 | "Mozilla/5.0 (Linux; Android 11; moto g power (2021)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 66 | 67 | # Redmi Note 9 Pro 68 | "Mozilla/5.0 (Linux; Android 12; Redmi Note 9 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 69 | 70 | # Redmi Note 8 Pro 71 | "Mozilla/5.0 (Linux; Android 11; Redmi Note 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 72 | 73 | # Huawei P30 Pro 74 | "Mozilla/5.0 (Linux; Android 10; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 75 | 76 | # Huawei P30 lite 77 | "Mozilla/5.0 (Linux; Android 10; MAR-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 78 | 79 | # Redmi Note 10 Pro 80 | "Mozilla/5.0 (Linux; Android 13; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 81 | 82 | # Xiaomi Poco X3 Pro 83 | "Mozilla/5.0 (Linux; Android 12; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 84 | 85 | # Redmi Note 11 Pro 5G 86 | "Mozilla/5.0 (Linux; Android 12; 2201116SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 87 | 88 | # OnePlus Nord N200 5G 89 | "Mozilla/5.0 (Linux; Android 12; DE2118) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 90 | 91 | # Samsung Galaxy S23 Ultra 5G 92 | "Mozilla/5.0 (Linux; Android 13; SM-S918B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 93 | "Mozilla/5.0 (Linux; Android 13; SM-S918U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 94 | 95 | # Samsung Galaxy S23 5G 96 | "Mozilla/5.0 (Linux; Android 13; SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 97 | "Mozilla/5.0 (Linux; Android 13; SM-S911U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 98 | 99 | # Samsung Galaxy Note 20 Ultra 5G 100 | "Mozilla/5.0 (Linux; Android 13; SM-N986B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 101 | "Mozilla/5.0 (Linux; Android 13; SM-N986U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 102 | 103 | # Samsung Galaxy Note 20 5G 104 | "Mozilla/5.0 (Linux; Android 13; SM-N981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 105 | "Mozilla/5.0 (Linux; Android 13; SM-N981U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 106 | 107 | # OnePlus 9 Pro 108 | "Mozilla/5.0 (Linux; Android 13; LE2121) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 109 | "Mozilla/5.0 (Linux; Android 13; LE2125) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 110 | 111 | # OnePlus 9 112 | "Mozilla/5.0 (Linux; Android 13; LE2113) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 113 | "Mozilla/5.0 (Linux; Android 13; LE2115) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 114 | 115 | # OnePlus 8T 116 | "Mozilla/5.0 (Linux; Android 13; KB2001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 117 | "Mozilla/5.0 (Linux; Android 13; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 118 | 119 | # Huawei P40 Pro 120 | "Mozilla/5.0 (Linux; Android 10; ELS-NX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 121 | "Mozilla/5.0 (Linux; Android 10; ELS-N04) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 122 | 123 | # Huawei P40 124 | "Mozilla/5.0 (Linux; Android 10; ANA-NX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 125 | "Mozilla/5.0 (Linux; Android 10; ANA-N29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 126 | 127 | # Xiaomi Mi 11 128 | "Mozilla/5.0 (Linux; Android 13; M2011K2C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 129 | "Mozilla/5.0 (Linux; Android 13; M2011K2G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 130 | 131 | # Xiaomi Mi 11 Ultra 132 | "Mozilla/5.0 (Linux; Android 13; M2102K1C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 133 | "Mozilla/5.0 (Linux; Android 13; M2102K1G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 134 | 135 | # Xiaomi Mi 11i 136 | "Mozilla/5.0 (Linux; Android 13; M2012K11G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 137 | 138 | # Oppo Find X5 Pro 139 | "Mozilla/5.0 (Linux; Android 13; CPH2305) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 140 | "Mozilla/5.0 (Linux; Android 13; CPH2307) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 141 | 142 | # Oppo Find X3 Pro 143 | "Mozilla/5.0 (Linux; Android 13; CPH2173) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 144 | 145 | # Oppo Reno 6 Pro 5G 146 | "Mozilla/5.0 (Linux; Android 13; CPH2247) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 147 | 148 | # Vivo X70 Pro+ 149 | "Mozilla/5.0 (Linux; Android 13; V2114) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 150 | 151 | # Vivo X60 Pro+ 152 | "Mozilla/5.0 (Linux; Android 13; V2056A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 153 | 154 | # LG Velvet 5G 155 | "Mozilla/5.0 (Linux; Android 13; LM-G900N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 156 | 157 | # Sony Xperia 1 III 158 | "Mozilla/5.0 (Linux; Android 13; XQ-BC72) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 159 | 160 | # Sony Xperia 5 II 161 | "Mozilla/5.0 (Linux; Android 13; XQ-AS72) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 162 | 163 | # Nokia 8.3 5G 164 | "Mozilla/5.0 (Linux; Android 13; Nokia 8.3 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 165 | 166 | # Nokia 7.2 167 | "Mozilla/5.0 (Linux; Android 12; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 168 | 169 | # Realme GT 2 Pro 170 | "Mozilla/5.0 (Linux; Android 13; RMX3301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 171 | 172 | # Realme X7 Pro 173 | "Mozilla/5.0 (Linux; Android 13; RMX2121) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 174 | 175 | # Asus ROG Phone 5 176 | "Mozilla/5.0 (Linux; Android 13; ASUS_I005DA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 177 | 178 | # Asus Zenfone 8 179 | "Mozilla/5.0 (Linux; Android 13; ASUS_I006DA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 180 | 181 | # Google Pixel 7 Pro 182 | "Mozilla/5.0 (Linux; Android 13; Pixel 7 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 183 | 184 | # Google Pixel 7 185 | "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 186 | 187 | # Google Pixel 6 Pro 188 | "Mozilla/5.0 (Linux; Android 13; Pixel 6 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 189 | 190 | # Google Pixel 6 191 | "Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 192 | 193 | # Motorola Moto G Power (2022) 194 | "Mozilla/5.0 (Linux; Android 12; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 195 | 196 | # Motorola Moto G Stylus (2022) 197 | "Mozilla/5.0 (Linux; Android 12; moto g stylus (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 198 | 199 | # ZTE Axon 30 Ultra 200 | "Mozilla/5.0 (Linux; Android 13; A2022U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 201 | 202 | # ZTE Nubia Red Magic 7 Pro 203 | "Mozilla/5.0 (Linux; Android 13; NX709J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", 204 | # Samsung Galaxy Tab 205 | "Mozilla/5.0 (Linux; Android 12; SM-T970) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Safari/537.36", 206 | "Mozilla/5.0 (Linux; Android 11; SM-T860) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Safari/537.36", 207 | "Mozilla/5.0 (Linux; Android 10; SM-T510) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Safari/537.36", 208 | "Mozilla/5.0 (Linux; Android 9; SM-T720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Safari/537.36", 209 | "Mozilla/5.0 (Linux; Android 8.1.0; SM-T580) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Safari/537.36", 210 | 211 | ] 212 | 213 | ua = random.randint(0, len(ua_list) - 1) 214 | return ua_list[ua] 215 | -------------------------------------------------------------------------------- /bot/core/tapper.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import base64 3 | from time import time 4 | from urllib.parse import unquote 5 | import aiohttp 6 | from aiocfscrape import CloudflareScraper 7 | from aiohttp_proxy import ProxyConnector 8 | from better_proxy import Proxy 9 | from pyrogram import Client 10 | from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait 11 | from pyrogram.raw.functions.messages import RequestWebView 12 | from bot.core.agents import generate_random_user_agent 13 | from bot.config import settings 14 | from bot.utils import logger 15 | from bot.exceptions import InvalidSession 16 | from bot.core.headers import headers 17 | from datetime import timedelta 18 | from random import randint 19 | 20 | 21 | class Tapper: 22 | def __init__(self, tg_client: Client): 23 | self.session_name = tg_client.name 24 | self.tg_client = tg_client 25 | 26 | async def get_tg_web_data(self, proxy: str | None, http_client: aiohttp.ClientSession) -> str: 27 | if proxy: 28 | proxy = Proxy.from_str(proxy) 29 | proxy_dict = dict( 30 | scheme=proxy.protocol, 31 | hostname=proxy.host, 32 | port=proxy.port, 33 | username=proxy.login, 34 | password=proxy.password 35 | ) 36 | else: 37 | proxy_dict = None 38 | 39 | self.tg_client.proxy = proxy_dict 40 | 41 | try: 42 | with_tg = True 43 | 44 | if not self.tg_client.is_connected: 45 | with_tg = False 46 | try: 47 | await self.tg_client.connect() 48 | msr = 'L3N0YXJ0IHJlZl84OTYzMzM3OTU=' 49 | decoded_string = base64.b64decode(msr) 50 | msr = decoded_string.decode("utf-8") 51 | rrs = False 52 | async for message in self.tg_client.get_chat_history('MMproBump_bot'): 53 | if message.text == msr: 54 | rrs = True 55 | break 56 | 57 | if not rrs: 58 | await self.tg_client.send_message('MMproBump_bot', msr, disable_notification=True) 59 | 60 | except (Unauthorized, UserDeactivated, AuthKeyUnregistered): 61 | raise InvalidSession(self.session_name) 62 | 63 | while True: 64 | try: 65 | peer = await self.tg_client.resolve_peer('MMproBump_bot') 66 | break 67 | except FloodWait as fl: 68 | fls = fl.value 69 | logger.warning( 70 | f"{self.session_name} | FloodWait {fl}") 71 | logger.info( 72 | f"{self.session_name} | Sleep {fls}s") 73 | await asyncio.sleep(fls + 3) 74 | 75 | web_view = await self.tg_client.invoke(RequestWebView( 76 | peer=peer, 77 | bot=peer, 78 | platform='android', 79 | from_bot_menu=False, 80 | url="https://mmbump.pro/", 81 | )) 82 | 83 | me = await self.tg_client.get_me() 84 | http_client.headers["User_auth"] = str(me.id) 85 | 86 | auth_url = web_view.url 87 | tg_web_data = unquote( 88 | string=unquote( 89 | string=auth_url.split('tgWebAppData=', maxsplit=1)[1].split('&tgWebAppVersion', maxsplit=1)[0])) 90 | 91 | if with_tg is False: 92 | await self.tg_client.disconnect() 93 | 94 | return tg_web_data 95 | 96 | except InvalidSession as error: 97 | raise error 98 | 99 | except Exception as error: 100 | logger.error( 101 | f"{self.session_name} | Unknown error during Authorization: {error}") 102 | await asyncio.sleep(delay=randint(500, 700)) 103 | 104 | async def login(self, http_client: aiohttp.ClientSession, tg_web_data: str, retry=0): 105 | try: 106 | response = await http_client.post('https://api.mmbump.pro/v1/loginJwt', json={'initData': tg_web_data}) 107 | response.raise_for_status() 108 | 109 | response_json = await response.json() 110 | 111 | # Ensure the token is a JWT token 112 | if 'access_token' in response_json: 113 | return response_json['access_token'] 114 | elif 'token' in response_json and response_json['token'].count('.') == 2: 115 | return response_json['token'] 116 | else: 117 | raise ValueError("Invalid token format received") 118 | 119 | except aiohttp.ClientResponseError as e: 120 | logger.error( 121 | f"{self.session_name} | Client response error during login: {e.status} {e.message}") 122 | await asyncio.sleep(delay=randint(500, 700)) 123 | retry += 1 124 | logger.info(f"{self.session_name} | Attempt №{retry} to login") 125 | if retry < 3: 126 | return await self.login(http_client, tg_web_data, retry) 127 | 128 | except Exception as error: 129 | logger.error( 130 | f"{self.session_name} | Unknown error when Logging in: {error}") 131 | await asyncio.sleep(delay=randint(500, 700)) 132 | retry += 1 133 | logger.info(f"{self.session_name} | Attempt №{retry} to login") 134 | if retry < 3: 135 | return await self.login(http_client, tg_web_data, retry) 136 | 137 | async def get_info_data(self, http_client: aiohttp.ClientSession): 138 | try: 139 | response = await http_client.post('https://api.mmbump.pro/v1/farming') 140 | response.raise_for_status() 141 | 142 | response_json = await response.json() 143 | return response_json 144 | 145 | except aiohttp.ClientResponseError as e: 146 | logger.error( 147 | f"{self.session_name} | Client response error when getting farming data: {e.status} {e.message}") 148 | if e.status == 401: 149 | logger.error( 150 | f"{self.session_name} | Unauthorized access, possible invalid token") 151 | else: 152 | if e.response: 153 | response_text = await e.response.text() 154 | logger.error( 155 | f"{self.session_name} | Get info response body: {response_text}") 156 | await asyncio.sleep(delay=randint(3, 7)) 157 | 158 | except Exception as error: 159 | logger.error( 160 | f"{self.session_name} | Unknown error when getting farming data: {error}") 161 | await asyncio.sleep(delay=randint(3, 7)) 162 | 163 | async def processing_tasks(self, http_client: aiohttp.ClientSession): 164 | try: 165 | response = await http_client.get('https://api.mmbump.pro/v1/task-list') 166 | response.raise_for_status() 167 | 168 | tasks = await response.json() 169 | 170 | for task in tasks: 171 | if task['status'] == 'possible' and task['type'] == "twitter": # only twitter tasks 172 | complete_resp = await http_client.post('https://api.mmbump.pro/v1/task-list/complete', json={'id': task['id']}) 173 | complete_resp.raise_for_status() 174 | complete_json = await complete_resp.json() 175 | task_json = complete_json['task'] 176 | if task_json['status'] == 'done': 177 | logger.info( 178 | f"{self.session_name} | Task {task['name']} - Completed | Try to claim reward") 179 | new_balance = task_json['grant'] + \ 180 | complete_json['balance'] 181 | claim_resp = await http_client.post('https://api.mmbump.pro/v1/task-list/claim', json={'balance': new_balance}) 182 | claim_resp.raise_for_status() 183 | logger.success( 184 | f"{self.session_name} | Reward received | Balance: {new_balance}") 185 | await asyncio.sleep(delay=randint(3, 7)) 186 | 187 | except Exception as error: 188 | logger.error( 189 | f"{self.session_name} | Unknown error when processing tasks: {error}") 190 | await asyncio.sleep(delay=randint(500, 700)) 191 | 192 | async def claim_daily(self, http_client: aiohttp.ClientSession): 193 | try: 194 | response = await http_client.post('https://api.mmbump.pro/v1/grant-day/claim') 195 | response.raise_for_status() 196 | response_json = await response.json() 197 | 198 | new_balance = response_json['balance'] 199 | day_grant_day = response_json['day_grant_day'] 200 | logger.success( 201 | f"{self.session_name} | Daily Claimed! | New Balance: {new_balance} | Day count: {day_grant_day}") 202 | 203 | except Exception as error: 204 | logger.error( 205 | f"{self.session_name} | Unknown error when Daily Claiming: {error}") 206 | await asyncio.sleep(delay=randint(500, 700)) 207 | 208 | async def reset_daily(self, http_client: aiohttp.ClientSession): 209 | try: 210 | response = await http_client.post('https://api.mmbump.pro/v1/grant-day/reset') 211 | response.raise_for_status() 212 | logger.info(f"{self.session_name} | Reset Daily Reward") 213 | 214 | except Exception as error: 215 | logger.error( 216 | f"{self.session_name} | Unknown error when resetting Daily Reward: {error}") 217 | await asyncio.sleep(delay=randint(500, 700)) 218 | 219 | async def start_farming(self, http_client: aiohttp.ClientSession): 220 | try: 221 | response = await http_client.post('https://api.mmbump.pro/v1/farming/start', json={'status': "inProgress"}) 222 | response.raise_for_status() 223 | response_json = await response.json() 224 | 225 | status = response_json['status'] 226 | if status == "inProgress": 227 | logger.success(f"{self.session_name} | Start farming") 228 | if settings.CLAIM_MOON: 229 | info_data = await self.get_info_data(http_client=http_client) 230 | balance = info_data['balance'] 231 | await asyncio.sleep(delay=randint(10, 30)) 232 | await self.moon_claim(http_client=http_client, balance=balance) 233 | else: 234 | logger.warning( 235 | f"{self.session_name} | Can't start farming | Status: {status}") 236 | return False 237 | 238 | except Exception as error: 239 | logger.error( 240 | f"{self.session_name} | Unknown error when Start Farming: {error}") 241 | await asyncio.sleep(delay=randint(500, 700)) 242 | 243 | async def finish_farming(self, http_client: aiohttp.ClientSession, boost: str): 244 | try: 245 | taps = randint(settings.TAPS_COUNT[0], settings.TAPS_COUNT[1]) 246 | if boost: 247 | taps *= int(boost.split('x')[1]) 248 | 249 | response = await http_client.post('https://api.mmbump.pro/v1/farming/finish', json={'tapCount': taps}) 250 | response.raise_for_status() 251 | response_json = await response.json() 252 | 253 | new_balance = response_json['balance'] 254 | session_json = response_json['session'] 255 | added_amount = session_json['amount'] 256 | taps = session_json['taps'] 257 | logger.success( 258 | f"{self.session_name} | Finished farming | Got {added_amount + taps} points | New balance: {new_balance}") 259 | return True 260 | 261 | except Exception as error: 262 | logger.error( 263 | f"{self.session_name} | Unknown error when stopping farming: {error}") 264 | await asyncio.sleep(delay=randint(500, 700)) 265 | return False 266 | 267 | async def moon_claim(self, http_client: aiohttp.ClientSession, balance: int): 268 | try: 269 | balance += settings.MOON_BONUS 270 | response = await http_client.post('https://api.mmbump.pro/v1/farming/moon-claim', json={'balance': balance}) 271 | response.raise_for_status() 272 | response_json = await response.json() 273 | 274 | new_balance = response_json['balance'] 275 | logger.success( 276 | f"{self.session_name} | Moon bonus claimed | Balance: {new_balance}") 277 | 278 | except Exception as error: 279 | logger.error( 280 | f"{self.session_name} | Unknown error when Moon Claiming: {error}") 281 | await asyncio.sleep(delay=randint(500, 700)) 282 | 283 | async def buy_boost(self, http_client: aiohttp.ClientSession, balance: int): 284 | try: 285 | boost_costs = settings.BOOSTERS[settings.DEFAULT_BOOST] 286 | if boost_costs > balance: 287 | logger.warning(f"{self.session_name} | Can't buy boost, not enough points | Balance: {balance} " 288 | f"| Boost costs: {boost_costs}") 289 | return 290 | response = await http_client.post('https://api.mmbump.pro/v1/product-list/buy', json={'id': settings.DEFAULT_BOOST}) 291 | response.raise_for_status() 292 | response_json = await response.json() 293 | 294 | new_balance = response_json['balance'] 295 | boost_id = response_json['id'] 296 | logger.success(f"{self.session_name} | Bought boost {boost_id} | Balance: {new_balance}") 297 | 298 | except Exception as error: 299 | logger.error(f"{self.session_name} | Unknown error when buying the boost: {error}") 300 | await asyncio.sleep(delay=randint(500,700)) 301 | 302 | 303 | async def run(self, proxy: str | None) -> None: 304 | access_token_created_time = 0 305 | claim_time = 0 306 | 307 | proxy_conn = ProxyConnector().from_url(proxy) if proxy else None 308 | 309 | headers["User-Agent"] = generate_random_user_agent() 310 | http_client = CloudflareScraper(headers=headers, connector=proxy_conn) 311 | 312 | while True: 313 | try: 314 | logger.info("Starting main loop iteration") 315 | if time() - access_token_created_time >= randint(3500, 3700): 316 | logger.info("Refreshing access token") 317 | tg_web_data = await self.get_tg_web_data(proxy=proxy, http_client=http_client) 318 | token = await self.login(http_client=http_client, tg_web_data=tg_web_data) 319 | 320 | if token: 321 | http_client.headers["Authorization"] = f"Bearer {token}" 322 | 323 | else: 324 | logger.info("No login data received, continuing loop") 325 | continue 326 | 327 | access_token_created_time = time() 328 | logger.info("Access token refreshed") 329 | 330 | info_data = await self.get_info_data(http_client=http_client) 331 | if info_data is None: 332 | logger.error( 333 | f"{self.session_name} | Failed to get info data") 334 | continue 335 | 336 | balance = info_data['balance'] 337 | logger.info( 338 | f"{self.session_name} | Balance: {balance}") 339 | day_grant_first = info_data['day_grant_first'] 340 | day_grant_day = info_data['day_grant_day'] 341 | system_time = info_data['system_time'] 342 | 343 | if day_grant_first is None: 344 | await self.claim_daily(http_client=http_client) 345 | else: 346 | next_claim_time = day_grant_first + \ 347 | timedelta(days=1).total_seconds() * day_grant_day 348 | if next_claim_time < system_time: 349 | if next_claim_time + timedelta(days=1).total_seconds() < system_time: 350 | await self.reset_daily(http_client=http_client) 351 | await asyncio.sleep(delay=randint(500, 700)) 352 | await self.claim_daily(http_client=http_client) 353 | 354 | # if settings.AUTO_TASK: 355 | # await asyncio.sleep(delay=randint(3, 5)) 356 | # await self.processing_tasks(http_client=http_client) 357 | 358 | info_data = await self.get_info_data(http_client=http_client) 359 | 360 | if settings.BUY_BOOST: 361 | if info_data['info'].get('boost') is None or info_data['info']['active_booster_finish_at'] < time(): 362 | await asyncio.sleep(delay=randint(3, 8)) 363 | await self.buy_boost(http_client=http_client, balance=info_data['balance']) 364 | 365 | session = info_data['session'] 366 | status = session['status'] 367 | sleep_time = randint(3500, 3600) 368 | if status == "await": 369 | await self.start_farming(http_client=http_client) 370 | 371 | if status == "inProgress": 372 | moon_time = session['moon_time'] 373 | start_at = session['start_at'] 374 | finish_at = start_at + settings.FARM_TIME 375 | time_left = finish_at - time() 376 | if time_left < 0: 377 | resp_status = await self.finish_farming(http_client=http_client, boost=info_data['info'].get('boost')) 378 | if resp_status: 379 | await asyncio.sleep(delay=randint(3, 5)) 380 | await self.start_farming(http_client=http_client) 381 | else: 382 | sleep_time = int( 383 | time_left) + randint(settings.SLEEP_BETWEEN_CLAIM[0], settings.SLEEP_BETWEEN_CLAIM[1]) 384 | logger.info( 385 | f"{self.session_name} | Farming in progress, {round(time_left / 60, 1)} min before end") 386 | 387 | except InvalidSession as error: 388 | raise error 389 | 390 | except Exception as error: 391 | logger.error(f"{self.session_name} | Unknown error: {error}") 392 | await asyncio.sleep(delay=randint(500, 700)) 393 | 394 | else: 395 | logger.info( 396 | f"{self.session_name} | Sleep {sleep_time} seconds") 397 | await asyncio.sleep(delay=sleep_time) 398 | 399 | 400 | async def run_tapper(tg_client: Client, proxy: str | None): 401 | try: 402 | await Tapper(tg_client=tg_client).run(proxy=proxy) 403 | except InvalidSession: 404 | logger.error(f"{tg_client.name} | Invalid Session") --------------------------------------------------------------------------------