├── 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 | [](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 | [](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")
--------------------------------------------------------------------------------