├── .env-example
├── Dockerfile
├── README.md
├── bot
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-311.pyc
│ └── __init__.cpython-312.pyc
├── config
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ ├── __init__.cpython-312.pyc
│ │ ├── config.cpython-311.pyc
│ │ └── config.cpython-312.pyc
│ ├── config.py
│ └── proxies.txt
├── core
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ ├── __init__.cpython-312.pyc
│ │ ├── agents.cpython-311.pyc
│ │ ├── headers.cpython-311.pyc
│ │ ├── query.cpython-311.pyc
│ │ ├── registrator.cpython-311.pyc
│ │ ├── tapper.cpython-311.pyc
│ │ └── tapper.cpython-312.pyc
│ ├── agents.py
│ ├── headers.py
│ ├── query.py
│ ├── registrator.py
│ └── tapper.py
├── exceptions
│ ├── __init__.py
│ └── __pycache__
│ │ └── __init__.cpython-311.pyc
└── utils
│ ├── __init__.py
│ ├── __pycache__
│ ├── __init__.cpython-311.pyc
│ ├── __init__.cpython-312.pyc
│ ├── launcher.cpython-311.pyc
│ ├── launcher.cpython-312.pyc
│ ├── logger.cpython-311.pyc
│ └── logger.cpython-312.pyc
│ ├── launcher.py
│ └── logger.py
├── data.txt
├── docker-compose.yml
├── main.py
├── requirements.txt
└── run.bat
/.env-example:
--------------------------------------------------------------------------------
1 | API_ID=
2 | API_HASH=
3 |
4 |
5 | REF_LINK=
6 | X3POINTS=
7 | AUTO_UPGRADE_PAINT_REWARD=
8 | AUTO_UPGRADE_RECHARGE_SPEED=
9 | AUTO_UPGRADE_RECHARGE_ENERGY=
10 | AUTO_TASK=
11 |
12 | NIGHT_MODE=
13 | SLEEP_TIME=
14 | SLEEP_TIME_BETWEEN_EACH_ROUND=
15 |
16 | USE_PROXY_FROM_FILE=
17 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.11.5-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", "1", "-m", "n"]
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NotPixelBot
2 | 🖱️ clicker for [https://t.me/notpx_bot](https://t.me/notpixel/app?startapp=f558455838)
3 |
4 | ## Recommendation before use
5 | # 🔥🔥 Use PYTHON 3.10 🔥🔥
6 |
7 | ## Features
8 | | Feature | Supported |
9 | |---------------------------------------------------------------|:----------------:|
10 | | Multithreading | ✅ |
11 | | Proxy binding to session | ✅ |
12 | | Auto ref | ✅ |
13 | | Auto claim | ✅ |
14 | | Auto paint | ✅ |
15 | | Auto paint specific pixel to get 3x px | ✅ |
16 | | Auto task | ✅ |
17 | | Auto UPGRADE | ✅ |
18 | | Night mode | ✅ |
19 | | Support for pyrogram .session / Query | ✅ |
20 |
21 | ## [Settings](https://github.com/sizifart/NotPixelBot/blob/main/.env-example)
22 | | Settings | Description |
23 | |----------------------------|:-------------------------------------------------------------------------------------------------------------:|
24 | | **API_ID / API_HASH** | Platform data from which to run the Telegram session (default - android) |
25 | | **REF_LINK** | Put your ref link here (default: my ref link) |
26 | | **X3POINTS** | Auto paint specific pixel to get 3x px (default: True) |
27 | | **AUTO_TASK** | Auto do tasks (default: True) |
28 | | **AUTO_UPGRADE_PAINT_REWARD** | AUTO upgrade paint reward if possible (default: True) |
29 | | **AUTO_UPGRADE_RECHARGE_SPEED** | AUTO upgrade recharge speed if possible (default: True) |
30 | | **AUTO_UPGRADE_RECHARGE_ENERGY** | AUTO upgrade energy limit if possible (default: True) |
31 | | **NIGHT_MODE** | Sleep time for the bot (default: True) |
32 | | **SLEEP_TIME** | Sleep in your timezone for the bot (default: [0, 7] 0am to 7am) |
33 | | **SLEEP_BETWEEN_EACH_ROUND** | Sleep time in second between each round (default: [1000, 1500] 0am to 7am) |
34 | | **USE_PROXY_FROM_FILE** | Whether to use a proxy from the bot/config/proxies.txt file (True / False) |
35 |
36 |
37 |
38 | ## Prerequisites
39 | Before you begin, make sure you have the following installed:
40 | - [Python](https://www.python.org/downloads/) **version 3.10**
41 | - Telegram API_ID and API_HASH (you can get them [here](https://my.telegram.org/auth))
42 |
43 | ## Obtaining API Keys
44 | 1. Go to my.telegram.org and log in using your phone number.
45 | 2. Select "API development tools" and fill out the form to register a new application.
46 | 3. Record the API_ID and API_HASH provided after registering your application in the .env file.
47 |
48 | ## Auto Install/Run
49 | - Click on RUN.bat to automatically install the required dependencies and run the project
50 |
51 | ## Menual Install/Run
52 | 1. Install the required dependencies:
53 | ```bash
54 | pip install -r requirements.txt
55 | ```
56 | 2. Please edit the name file .env-example to .env and add your API_ID and API_HASH:
57 |
58 | ## Usage
59 | 1. Run the bot:
60 | ```bash
61 | python main.py
62 | ```
63 |
64 | # Telegram Channel
65 |
66 | ✅ Channel for information and training on Telegram airdrop bots 🔷 Follow us on Telegram : [SIZIFAIRDROP](https://t.me/sizifairdrop)
67 |
68 | # Donate
69 | Your donations help us continue our work. Thank you for your support! | 💳 [Donate](https://sizvpn.com/donate/)
70 |
71 | # Discussion
72 |
73 | If you have an question or something you can ask in here : [F.Davoodi](https://t.me/sizifart)
74 |
--------------------------------------------------------------------------------
/bot/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '1.0'
2 |
--------------------------------------------------------------------------------
/bot/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/__pycache__/__init__.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/__pycache__/__init__.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/config/__init__.py:
--------------------------------------------------------------------------------
1 | from .config import settings
2 |
--------------------------------------------------------------------------------
/bot/config/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/config/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/config/__pycache__/__init__.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/config/__pycache__/__init__.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/config/__pycache__/config.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/config/__pycache__/config.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/config/__pycache__/config.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/config/__pycache__/config.cpython-312.pyc
--------------------------------------------------------------------------------
/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 |
11 | REF_LINK: str = "https://t.me/notpixel/app?startapp=f558455838"
12 | X3POINTS: bool = True
13 | AUTO_UPGRADE_PAINT_REWARD: bool = True
14 | AUTO_UPGRADE_RECHARGE_SPEED:bool = True
15 | AUTO_UPGRADE_RECHARGE_ENERGY:bool = True
16 | AUTO_TASK: bool = True
17 |
18 | NIGHT_MODE: bool = True
19 | SLEEP_TIME: list[int] = [0, 7] # your time zone
20 |
21 | DELAY_EACH_ACCOUNT: list[int] = [10,15]
22 | SLEEP_TIME_BETWEEN_EACH_ROUND: list[int] = [1000, 1500]
23 | USE_PROXY_FROM_FILE: bool = False
24 |
25 |
26 | settings = Settings()
27 |
28 |
--------------------------------------------------------------------------------
/bot/config/proxies.txt:
--------------------------------------------------------------------------------
1 | https://38.154.227.167:5868:vanhbaka:Vanhdayyyy
2 | https://45.127.248.127:5128:vanhbaka:Vanhdayyyy
3 | https://207.244.217.165:6712:vanhbaka:Vanhdayyyy
4 |
--------------------------------------------------------------------------------
/bot/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__init__.py
--------------------------------------------------------------------------------
/bot/core/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/__init__.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/__init__.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/agents.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/agents.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/headers.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/headers.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/query.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/query.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/registrator.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/registrator.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/tapper.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/tapper.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/core/__pycache__/tapper.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/core/__pycache__/tapper.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/core/agents.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 |
4 | def generate_random_user_agent(device_type='android', browser_type='chrome'):
5 | chrome_versions = list(range(110, 127))
6 | firefox_versions = list(range(90, 100))
7 |
8 | if browser_type == 'chrome':
9 | major_version = random.choice(chrome_versions)
10 | minor_version = random.randint(0, 9)
11 | build_version = random.randint(1000, 9999)
12 | patch_version = random.randint(0, 99)
13 | browser_version = f"{major_version}.{minor_version}.{build_version}.{patch_version}"
14 | elif browser_type == 'firefox':
15 | browser_version = random.choice(firefox_versions)
16 |
17 | if device_type == 'android':
18 | android_versions = ['10.0', '11.0', '12.0', '13.0']
19 | android_device = random.choice([
20 | 'SM-G960F', 'Pixel 5', 'SM-A505F', 'Pixel 4a', 'Pixel 6 Pro', 'SM-N975F',
21 | 'SM-G973F', 'Pixel 3', 'SM-G980F', 'Pixel 5a', 'SM-G998B', 'Pixel 4',
22 | 'SM-G991B', 'SM-G996B', 'SM-F711B', 'SM-F916B', 'SM-G781B', 'SM-N986B',
23 | 'SM-N981B', 'Pixel 2', 'Pixel 2 XL', 'Pixel 3 XL', 'Pixel 4 XL',
24 | 'Pixel 5 XL', 'Pixel 6', 'Pixel 6 XL', 'Pixel 6a', 'Pixel 7', 'Pixel 7 Pro',
25 | 'OnePlus 8', 'OnePlus 8 Pro', 'OnePlus 9', 'OnePlus 9 Pro', 'OnePlus Nord', 'OnePlus Nord 2',
26 | 'OnePlus Nord CE', 'OnePlus 10', 'OnePlus 10 Pro', 'OnePlus 10T', 'OnePlus 10T Pro',
27 | 'Xiaomi Mi 9', 'Xiaomi Mi 10', 'Xiaomi Mi 11', 'Xiaomi Redmi Note 8', 'Xiaomi Redmi Note 9',
28 | 'Huawei P30', 'Huawei P40', 'Huawei Mate 30', 'Huawei Mate 40', 'Sony Xperia 1',
29 | 'Sony Xperia 5', 'LG G8', 'LG V50', 'LG V60', 'Nokia 8.3', 'Nokia 9 PureView'
30 | ])
31 | android_version = random.choice(android_versions)
32 | if browser_type == 'chrome':
33 | return (f"Mozilla/5.0 (Linux; Android {android_version}; {android_device}) AppleWebKit/537.36 "
34 | f"(KHTML, like Gecko) Chrome/{browser_version} Mobile Safari/537.36")
35 | elif browser_type == 'firefox':
36 | return (f"Mozilla/5.0 (Android {android_version}; Mobile; rv:{browser_version}.0) "
37 | f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
38 |
39 | elif device_type == 'ios':
40 | ios_versions = ['13.0', '14.0', '15.0', '16.0']
41 | ios_version = random.choice(ios_versions)
42 | if browser_type == 'chrome':
43 | return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
44 | f"AppleWebKit/537.36 (KHTML, like Gecko) CriOS/{browser_version} Mobile/15E148 Safari/604.1")
45 | elif browser_type == 'firefox':
46 | return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
47 | f"AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/{browser_version}.0 Mobile/15E148 Safari/605.1.15")
48 |
49 | elif device_type == 'windows':
50 | windows_versions = ['10.0', '11.0']
51 | windows_version = random.choice(windows_versions)
52 | if browser_type == 'chrome':
53 | return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
54 | f"Chrome/{browser_version} Safari/537.36")
55 | elif browser_type == 'firefox':
56 | return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64; rv:{browser_version}.0) "
57 | f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
58 |
59 | elif device_type == 'ubuntu':
60 | if browser_type == 'chrome':
61 | return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) AppleWebKit/537.36 (KHTML, like Gecko) "
62 | f"Chrome/{browser_version} Safari/537.36")
63 | elif browser_type == 'firefox':
64 | return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{browser_version}.0) Gecko/{browser_version}.0 "
65 | f"Firefox/{browser_version}.0")
66 |
67 | return None
68 |
--------------------------------------------------------------------------------
/bot/core/headers.py:
--------------------------------------------------------------------------------
1 | headers = {
2 | 'Accept': '*/*',
3 | 'Accept-Language': 'en-US',
4 | 'Content-Type': 'application/json',
5 | 'Authorization': '',
6 | 'Cache-Control': 'no-cache',
7 | 'Pragma': 'no-cache',
8 | 'Priority': "u=1, i",
9 | 'Origin': 'https://image.notpx.app',
10 | 'Referer': 'https://image.notpx.app/',
11 | 'Sec-Fetch-Dest': 'empty',
12 | 'Sec-Fetch-Mode': 'cors',
13 | 'Sec-Fetch-Site': 'same-site',
14 | 'Sec-Ch-Ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
15 | 'Sec-Ch-Ua-mobile': '?1',
16 | 'Sec-Ch-Ua-platform': '"Android"',
17 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36',
18 | }
--------------------------------------------------------------------------------
/bot/core/query.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import random
3 | from itertools import cycle
4 |
5 | import aiohttp
6 | import requests
7 | from aiocfscrape import CloudflareScraper
8 | from aiohttp_proxy import ProxyConnector
9 | from better_proxy import Proxy
10 | from bot.core.agents import generate_random_user_agent
11 | from bot.config import settings
12 | import cloudscraper
13 | from datetime import datetime, timedelta
14 | from tzlocal import get_localzone
15 | import time as time_module
16 |
17 | from bot.utils import logger
18 | from bot.exceptions import InvalidSession
19 | from .headers import headers
20 | from random import randint
21 |
22 | import urllib3
23 |
24 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
25 |
26 | def calc_id(x: int, y: int, x1: int, y1: int):
27 | px_id = randint(min(y, y1), max(y1, y))*1000
28 | px_id += randint(min(x, x1), max(x1, x))+1
29 | # print(px_id)
30 | return px_id
31 |
32 | class Tapper:
33 | def __init__(self, query: str, session_name, multi_thread):
34 | self.query = query
35 | self.session_name = session_name
36 | self.first_name = ''
37 | self.last_name = ''
38 | self.user_id = ''
39 | self.auth_token = ""
40 | self.last_claim = None
41 | self.last_checkin = None
42 | self.balace = 0
43 | self.maxtime = 0
44 | self.fromstart = 0
45 | self.color_list = ["#E46E6E", "#FFD635" , "#7EED56", "#00CCC0", "#51E9F4", "#000000"]
46 | self.balance = 0
47 | self.checked = [False] * 5
48 | self.multi_thread = multi_thread
49 |
50 | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
51 | try:
52 | response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5))
53 | ip = (await response.json()).get('origin')
54 | logger.info(f"{self.session_name} | Proxy IP: {ip}")
55 | return True
56 | except Exception as error:
57 | logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
58 | return False
59 |
60 | def login(self, session: requests.Session):
61 | response = session.get("https://notpx.app/api/v1/users/me", headers=headers, verify=False)
62 | if response.status_code == 200:
63 | logger.success(f"{self.session_name} | Logged in.")
64 | return True
65 | else:
66 | print(response.json())
67 | logger.warning("{self.session_name} | Failed to login")
68 | return False
69 |
70 | def get_user_data(self, session: requests.Session):
71 | response = session.get("https://notpx.app/api/v1/mining/status", headers=headers, verify=False)
72 | if response.status_code == 200:
73 | return response.json()
74 | else:
75 | print(response.json())
76 | return None
77 |
78 | def generate_random_color(self):
79 |
80 | return random.choice(self.color_list)
81 |
82 | def generate_random_pos(self):
83 | return randint(1, 1000000)
84 |
85 | def get_cor(self, session: requests.Session):
86 | res = session.get("https://raw.githubusercontent.com/vanhbakaa/notpixel-3x-points/refs/heads/main/data4.json")
87 | if res.status_code == 200:
88 | cor = res.json()
89 | paint = random.choice(cor['data'])
90 | color = paint['color']
91 | random_cor = random.choice(paint['cordinates'])
92 | # print(f"{color}: {random_cor}")
93 | px_id = calc_id(random_cor['start'][0], random_cor['start'][1], random_cor['end'][0], random_cor['end'][1])
94 | return [color, px_id]
95 |
96 | def repaint(self, session: requests.Session, chance_left):
97 | # print("starting to paint")
98 | if settings.X3POINTS:
99 | data = self.get_cor(session)
100 | payload = {
101 | "newColor": data[0],
102 | "pixelId": data[1]
103 | }
104 | else:
105 | data = [str(self.generate_random_color()), int(self.generate_random_pos())]
106 | payload = {
107 | "newColor": data[0],
108 | "pixelId": data[1]
109 | }
110 | response = session.post("https://notpx.app/api/v1/repaint/start", headers=headers, json=payload, verify=False)
111 | if response.status_code == 200:
112 | if settings.X3POINTS:
113 | logger.success(
114 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
115 | self.balance = int(response.json()['balance'])
116 | else:
117 | logger.success(
118 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
119 | self.balance = int(response.json()['balance'])
120 | else:
121 | print(response.text)
122 | logger.warning(f"{self.session_name} | Faled to repaint: {response.status_code}")
123 |
124 | def repaintV2(self, session: requests.Session, chance_left, i, data):
125 | if i % 2 == 0:
126 | payload = {
127 | "newColor": data[0],
128 | "pixelId": data[1]
129 | }
130 |
131 | else:
132 | data1 = [str(self.generate_random_color()), int(self.generate_random_pos())]
133 | payload = {
134 | "newColor": data1[0],
135 | "pixelId": data[1]
136 | }
137 | response = session.post("https://notpx.app/api/v1/repaint/start", headers=headers, json=payload, verify=False)
138 | if response.status_code == 200:
139 | if i % 2 == 0:
140 | logger.success(
141 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
142 | self.balance = int(response.json()['balance'])
143 | data = self.get_cor(session)
144 | else:
145 | logger.success(
146 | f"{self.session_name} | Painted {data[1]} successfully new color: {data1[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
147 | self.balance = int(response.json()['balance'])
148 | else:
149 | print(response.text)
150 | logger.warning(f"{self.session_name} | Faled to repaint: {response.status_code}")
151 |
152 |
153 | def auto_task(self, session: cloudscraper.CloudScraper):
154 | pass
155 |
156 |
157 | async def auto_upgrade_paint(self, session: requests.Session):
158 | res = session.get("https://notpx.app/api/v1/mining/boost/check/paintReward", headers=headers, verify=False)
159 | if res.status_code == 200:
160 | logger.success(f"{self.session_name} | Upgrade paint reward successfully!")
161 | await asyncio.sleep(random.uniform(2,4))
162 |
163 | async def auto_upgrade_recharge_speed(self, session: requests.Session):
164 | res = session.get("https://notpx.app/api/v1/mining/boost/check/reChargeSpeed", headers=headers, verify=False)
165 | if res.status_code == 200:
166 | logger.success(f"{self.session_name} | Upgrade recharging speed successfully!")
167 | await asyncio.sleep(random.uniform(2,4))
168 |
169 | async def auto_upgrade_energy_limit(self, session: requests.Session):
170 | res = session.get("https://notpx.app/api/v1/mining/boost/check/energyLimit", headers=headers, verify=False)
171 | if res.status_code == 200:
172 | logger.success(f"{self.session_name} | Upgrade energy limit successfully!")
173 |
174 |
175 | def claimpx(self, session: requests.Session):
176 | res = session.get("https://notpx.app/api/v1/mining/claim", headers=headers, verify=False)
177 | if res.status_code == 200:
178 | logger.success(f"{self.session_name} | Successfully claimed {res.json()['claimed']} px from mining!")
179 | else:
180 | logger.warning(f"{self.session_name} | Failed to claim px from mining: {res.json()}")
181 |
182 | async def run(self, proxy: str | None) -> None:
183 | access_token_created_time = 0
184 | proxy_conn = ProxyConnector().from_url(proxy) if proxy else None
185 |
186 | headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
187 | http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
188 | session = requests.Session()
189 |
190 | if proxy:
191 | proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
192 | if proxy_check:
193 | proxy_type = proxy.split(':')[0]
194 | proxies = {
195 | proxy_type: proxy
196 | }
197 | session.proxies.update(proxies)
198 | logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")
199 |
200 | token_live_time = randint(1000, 1500)
201 | while True:
202 | try:
203 | if time_module.time() - access_token_created_time >= token_live_time:
204 | # tg_web_data = await self.get_tg_web_data(proxy=proxy)
205 | headers['Authorization'] = f"initData {self.query}"
206 | access_token_created_time = time_module.time()
207 | token_live_time = randint(1000, 1500)
208 |
209 | local_timezone = get_localzone()
210 | current_time = datetime.now(local_timezone)
211 | start_time = current_time.replace(hour=settings.SLEEP_TIME[0], minute=0, second=0, microsecond=0)
212 | end_time = current_time.replace(hour=settings.SLEEP_TIME[1], minute=0, second=0, microsecond=0)
213 |
214 | if end_time < start_time:
215 | end_time += timedelta(days=1)
216 |
217 | if settings.NIGHT_MODE and (start_time <= current_time <= end_time):
218 | time_to_sleep = (end_time - current_time).total_seconds()
219 | logger.info(f"{self.session_name} | Sleeping for {time_to_sleep} seconds until {end_time}.")
220 | await asyncio.sleep(time_to_sleep)
221 |
222 |
223 | if self.login(session):
224 | user = self.get_user_data(session)
225 |
226 | if user:
227 | self.maxtime = user['maxMiningTime']
228 | self.fromstart = user['fromStart']
229 | self.balance = int(user['userBalance'])
230 |
231 | if user['charges'] > 0:
232 | # print("starting to paint 1")
233 | total_chance = int(user['charges'])
234 | i = 0
235 | data = self.get_cor(session)
236 | while total_chance > 0:
237 | total_chance -= 1
238 | i += 1
239 | if settings.X3POINTS:
240 | self.repaintV2(session, total_chance, i, data)
241 | else:
242 | self.repaint(session, total_chance)
243 | sleep_ = random.uniform(0.5, 0.8)
244 | logger.info(f"{self.session_name} | Sleep {sleep_} before continue...")
245 | await asyncio.sleep(sleep_)
246 |
247 | logger.info(
248 | f"{self.session_name} | Pixel Balance: {int(user['userBalance'])} | Pixel available to paint: {user['charges']}")
249 | r = random.uniform(2, 4)
250 | if float(self.fromstart) >= self.maxtime / r:
251 | self.claimpx(session)
252 | await asyncio.sleep(random.uniform(2, 5))
253 | if settings.AUTO_TASK:
254 | res = session.get("https://notpx.app/api/v1/mining/task/check/x?name=notpixel",
255 | headers=headers, verify=False)
256 | if res.status_code == 200 and res.json()['x:notpixel'] and self.checked[1] is False:
257 | self.checked[1] = True
258 | logger.success("Task Not pixel on x completed!")
259 | res = session.get("https://notpx.app/api/v1/mining/task/check/x?name=notcoin",
260 | headers=headers, verify=False)
261 | if res.status_code == 200 and res.json()['x:notcoin'] and self.checked[2] is False:
262 | self.checked[2] = True
263 | logger.success("Task Not coin on x completed!")
264 | res = session.get("https://notpx.app/api/v1/mining/task/check/paint20pixels",
265 | headers=headers, verify=False)
266 | if res.status_code == 200 and res.json()['paint20pixels'] and self.checked[3] is False:
267 | self.checked[3] = True
268 | logger.success("Task paint 20 pixels completed!")
269 |
270 |
271 | if settings.AUTO_UPGRADE_PAINT_REWARD:
272 | await self.auto_upgrade_paint(session)
273 | if settings.AUTO_UPGRADE_RECHARGE_ENERGY:
274 | await self.auto_upgrade_recharge_speed(session)
275 | if settings.AUTO_UPGRADE_RECHARGE_SPEED:
276 | await self.auto_upgrade_energy_limit(session)
277 |
278 | else:
279 | logger.warning(f"{self.session_name} | Failed to get user data!")
280 |
281 | else:
282 | logger.warning(f"invaild query: {self.query}")
283 |
284 | if self.multi_thread:
285 | sleep_ = randint(settings.SLEEP_TIME_BETWEEN_EACH_ROUND[0],
286 | settings.SLEEP_TIME_BETWEEN_EACH_ROUND[1])
287 | logger.info(f"{self.session_name} | Sleep {sleep_}s...")
288 | await asyncio.sleep(sleep_)
289 | else:
290 | await http_client.close()
291 | session.close()
292 | break
293 |
294 | except InvalidSession as error:
295 | raise error
296 |
297 | except Exception as error:
298 | logger.error(f"{self.session_name} | Unknown error: {error}")
299 | await asyncio.sleep(delay=randint(60, 120))
300 |
301 |
302 | async def run_query_tapper(query: str, name: str, proxy: str | None):
303 | try:
304 | sleep_ = randint(1, 15)
305 | logger.info(f" start after {sleep_}s")
306 | # await asyncio.sleep(sleep_)
307 | await Tapper(query=query, session_name=name, multi_thread=True).run(proxy=proxy)
308 | except InvalidSession:
309 | logger.error(f"Invalid Query: {query}")
310 |
311 | async def run_query_tapper1(querys: list[str], proxies):
312 | proxies_cycle = cycle(proxies) if proxies else None
313 | name = "Account"
314 |
315 | while True:
316 | i = 0
317 | for query in querys:
318 | try:
319 | await Tapper(query=query,session_name=f"{name} {i}",multi_thread=False).run(next(proxies_cycle) if proxies_cycle else None)
320 | except InvalidSession:
321 | logger.error(f"Invalid Query: {query}")
322 |
323 | sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
324 | logger.info(f"Sleep {sleep_}s...")
325 | await asyncio.sleep(sleep_)
326 |
327 | sleep_ = randint(settings.SLEEP_TIME_BETWEEN_EACH_ROUND[0], settings.SLEEP_TIME_BETWEEN_EACH_ROUND[1])
328 | logger.info(f"Sleep {sleep_}s...")
329 | await asyncio.sleep(sleep_)
330 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/bot/core/tapper.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import random
3 | import sys
4 | from itertools import cycle
5 | from urllib.parse import unquote
6 |
7 | import aiohttp
8 | import requests
9 | from aiocfscrape import CloudflareScraper
10 | from aiohttp_proxy import ProxyConnector
11 | from better_proxy import Proxy
12 | from pyrogram import Client
13 | from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait
14 | from pyrogram.raw.types import InputBotAppShortName
15 | from pyrogram.raw.functions.messages import RequestAppWebView
16 | from bot.core.agents import generate_random_user_agent
17 | from bot.config import settings
18 | from datetime import datetime, timedelta
19 | from tzlocal import get_localzone
20 | import time as time_module
21 |
22 | from bot.utils import logger
23 | from bot.exceptions import InvalidSession
24 | from .headers import headers
25 | from random import randint
26 | import urllib3
27 |
28 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
29 |
30 |
31 | def calc_id(x: int, y: int, x1: int, y1: int):
32 | px_id = randint(min(y, y1), max(y1, y)) * 1000
33 | px_id += randint(min(x, x1), max(x1, x)) + 1
34 | # print(px_id)
35 | return px_id
36 |
37 |
38 | class Tapper:
39 | def __init__(self, tg_client: Client, multi_thread: bool):
40 | self.tg_client = tg_client
41 | self.session_name = tg_client.name
42 | self.first_name = ''
43 | self.last_name = ''
44 | self.user_id = ''
45 | self.auth_token = ""
46 | self.last_claim = None
47 | self.last_checkin = None
48 | self.balace = 0
49 | self.maxtime = 0
50 | self.fromstart = 0
51 | self.checked = [False] * 9
52 | self.balance = 0
53 | self.color_list = ["#FFD635" , "#7EED56", "#00CCC0", "#51E9F4", "#94B3FF", "#000000"]
54 | self.multi_thread = multi_thread
55 | self.my_ref = "f6624523270"
56 |
57 | async def get_tg_web_data(self, proxy: str | None) -> str:
58 | try:
59 | if settings.REF_LINK == "":
60 | ref_param = "f6624523270"
61 | else:
62 | ref_param = settings.REF_LINK.split("=")[1]
63 | except:
64 | logger.error(f"{self.session_name} | Ref link invaild please check again !")
65 | sys.exit()
66 | actual = random.choices([self.my_ref, ref_param], weights=[30, 70]) # edit this line if you don't want to support me
67 | # print(actual)
68 | if proxy:
69 | proxy = Proxy.from_str(proxy)
70 | proxy_dict = dict(
71 | scheme=proxy.protocol,
72 | hostname=proxy.host,
73 | port=proxy.port,
74 | username=proxy.login,
75 | password=proxy.password
76 | )
77 | else:
78 | proxy_dict = None
79 |
80 | self.tg_client.proxy = proxy_dict
81 | try:
82 | if not self.tg_client.is_connected:
83 | try:
84 | await self.tg_client.connect()
85 | except (Unauthorized, UserDeactivated, AuthKeyUnregistered):
86 | raise InvalidSession(self.session_name)
87 |
88 | while True:
89 | try:
90 | peer = await self.tg_client.resolve_peer('notpixel')
91 | break
92 | except FloodWait as fl:
93 | fls = fl.value
94 |
95 | logger.warning(f"{self.session_name} | FloodWait {fl}")
96 | logger.info(f"{self.session_name} | Sleep {fls}s")
97 |
98 | await asyncio.sleep(fls + 3)
99 |
100 | web_view = await self.tg_client.invoke(RequestAppWebView(
101 | peer=peer,
102 | app=InputBotAppShortName(bot_id=peer, short_name="app"),
103 | platform='android',
104 | write_allowed=True,
105 | start_param=actual[0]
106 | ))
107 |
108 | auth_url = web_view.url
109 | # print(auth_url)
110 | tg_web_data = unquote(string=auth_url.split('tgWebAppData=')[1].split('&tgWebAppVersion')[0])
111 | # print(tg_web_data)
112 |
113 | if self.tg_client.is_connected:
114 | await self.tg_client.disconnect()
115 |
116 | return tg_web_data
117 |
118 | except InvalidSession as error:
119 | raise error
120 |
121 | except Exception as error:
122 | logger.error(f"{self.session_name} | Unknown error during Authorization: "
123 | f"{error}")
124 | await asyncio.sleep(delay=3)
125 |
126 | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
127 | try:
128 | response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5), )
129 | ip = (await response.json()).get('origin')
130 | logger.info(f"{self.session_name} | Proxy IP: {ip}")
131 | return True
132 | except Exception as error:
133 | logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
134 | return False
135 |
136 | def login(self, session: requests.Session):
137 | response = session.get("https://notpx.app/api/v1/users/me", headers=headers, verify=False)
138 | if response.status_code == 200:
139 | logger.success(f"{self.session_name} | Logged in.")
140 | return True
141 | else:
142 | print(response.json())
143 | logger.warning("{self.session_name} | Failed to login")
144 | return False
145 |
146 | def get_user_data(self, session: requests.Session):
147 | response = session.get("https://notpx.app/api/v1/mining/status", headers=headers, verify=False)
148 | if response.status_code == 200:
149 | return response.json()
150 | else:
151 | print(response.json())
152 | return None
153 |
154 | def generate_random_color(self, color):
155 | a = random.choice(self.color_list)
156 | while a == color:
157 | a = random.choice(self.color_list)
158 | return a
159 |
160 | def generate_random_pos(self):
161 | return randint(1, 1000000)
162 |
163 | def get_cor(self, session: requests.Session):
164 | res = session.get("https://raw.githubusercontent.com/vanhbakaa/notpixel-3x-points/refs/heads/main/data4.json")
165 | # print(res.text)
166 | if res.status_code == 200:
167 | cor = res.json()
168 | paint = random.choice(cor['data'])
169 | color = paint['color']
170 | random_cor = random.choice(paint['cordinates'])
171 | # print(f"{color}: {random_cor}")
172 | px_id = calc_id(random_cor['start'][0], random_cor['start'][1], random_cor['end'][0], random_cor['end'][1])
173 | return [color, px_id]
174 |
175 | def repaint(self, session: requests.Session, chance_left):
176 | # print("starting to paint")
177 | if settings.X3POINTS:
178 |
179 | payload = {
180 | "newColor": data[0],
181 | "pixelId": data[1]
182 | }
183 | data = self.get_cor(session)
184 | else:
185 | data = [str(self.generate_random_color(data[0])), int(self.generate_random_pos())]
186 | payload = {
187 | "newColor": data[0],
188 | "pixelId": data[1]
189 | }
190 | response = session.post("https://notpx.app/api/v1/repaint/start", headers=headers, json=payload, verify=False)
191 | if response.status_code == 200:
192 | if settings.X3POINTS:
193 | logger.success(
194 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
195 | self.balance = int(response.json()['balance'])
196 | else:
197 | logger.success(
198 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
199 | self.balance = int(response.json()['balance'])
200 | else:
201 | print(response.text)
202 | logger.warning(f"{self.session_name} | Faled to repaint: {response.status_code}")
203 |
204 | def repaintV2(self, session: requests.Session, chance_left, i, data):
205 | if i % 2 == 0:
206 | payload = {
207 | "newColor": data[0],
208 | "pixelId": data[1]
209 | }
210 |
211 | else:
212 | data1 = [str(self.generate_random_color(data[0])), int(self.generate_random_pos())]
213 | payload = {
214 | "newColor": data1[0],
215 | "pixelId": data[1]
216 | }
217 | response = session.post("https://notpx.app/api/v1/repaint/start", headers=headers, json=payload, verify=False)
218 | if response.status_code == 200:
219 | if i % 2 == 0:
220 | logger.success(
221 | f"{self.session_name} | Painted {data[1]} successfully new color: {data[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
222 | self.balance = int(response.json()['balance'])
223 | data = self.get_cor(session)
224 | else:
225 | logger.success(
226 | f"{self.session_name} | Painted {data[1]} successfully new color: {data1[0]} | Earned {int(response.json()['balance']) - self.balance} | Balace: {response.json()['balance']} | Repaint left: {chance_left}")
227 | self.balance = int(response.json()['balance'])
228 | else:
229 | print(response.text)
230 | logger.warning(f"{self.session_name} | Faled to repaint: {response.status_code}")
231 |
232 | async def auto_upgrade_paint(self, session: requests.Session):
233 | res = session.get("https://notpx.app/api/v1/mining/boost/check/paintReward", headers=headers, verify=False)
234 | if res.status_code == 200:
235 | logger.success(f"{self.session_name} | Upgrade paint reward successfully!")
236 | await asyncio.sleep(random.uniform(2, 4))
237 |
238 | async def auto_upgrade_recharge_speed(self, session: requests.Session):
239 | res = session.get("https://notpx.app/api/v1/mining/boost/check/reChargeSpeed", headers=headers, verify=False)
240 | if res.status_code == 200:
241 | logger.success(f"{self.session_name} | Upgrade recharging speed successfully!")
242 | await asyncio.sleep(random.uniform(2, 4))
243 |
244 | async def auto_upgrade_energy_limit(self, session: requests.Session):
245 | res = session.get("https://notpx.app/api/v1/mining/boost/check/energyLimit", headers=headers, verify=False)
246 | if res.status_code == 200:
247 | logger.success(f"{self.session_name} | Upgrade energy limit successfully!")
248 |
249 | def claimpx(self, session: requests.Session):
250 | res = session.get("https://notpx.app/api/v1/mining/claim", headers=headers, verify=False)
251 | if res.status_code == 200:
252 | logger.success(
253 | f"{self.session_name} | Successfully claimed {res.json()['claimed']} px from mining!")
254 | else:
255 | logger.warning(f"{self.session_name} | Failed to claim px from mining: {res.json()}")
256 |
257 | async def run(self, proxy: str | None) -> None:
258 | access_token_created_time = 0
259 | proxy_conn = ProxyConnector().from_url(proxy) if proxy else None
260 |
261 | headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
262 | http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
263 |
264 | session = requests.Session()
265 |
266 | if proxy:
267 | proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
268 | if proxy_check:
269 | proxy_type = proxy.split(':')[0]
270 | proxies = {
271 | proxy_type: proxy
272 | }
273 | session.proxies.update(proxies)
274 | logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")
275 |
276 | token_live_time = randint(1000, 1500)
277 | while True:
278 | try:
279 | if time_module.time() - access_token_created_time >= token_live_time:
280 | tg_web_data = await self.get_tg_web_data(proxy=proxy)
281 | headers['Authorization'] = f"initData {tg_web_data}"
282 | access_token_created_time = time_module.time()
283 | token_live_time = randint(1000, 1500)
284 |
285 | local_timezone = get_localzone()
286 | current_time = datetime.now(local_timezone)
287 | start_time = current_time.replace(hour=settings.SLEEP_TIME[0], minute=0, second=0, microsecond=0)
288 | end_time = current_time.replace(hour=settings.SLEEP_TIME[1], minute=0, second=0, microsecond=0)
289 |
290 | if end_time < start_time:
291 | end_time += timedelta(days=1)
292 |
293 | if settings.NIGHT_MODE and (start_time <= current_time <= end_time):
294 | time_to_sleep = (end_time - current_time).total_seconds()
295 | logger.info(f"{self.session_name} | Sleeping for {time_to_sleep} seconds until {end_time}.")
296 | await asyncio.sleep(time_to_sleep)
297 |
298 | elif self.login(session):
299 | user = self.get_user_data(session)
300 |
301 | if user:
302 | self.maxtime = user['maxMiningTime']
303 | self.fromstart = user['fromStart']
304 | self.balance = int(user['userBalance'])
305 | repaints = int(user['repaintsTotal'])
306 | user_league = user['league']
307 | logger.info(
308 | f"{self.session_name} | Pixel Balance: {int(user['userBalance'])} | Pixel available to paint: {user['charges']} | User league: {user_league}")
309 |
310 | if user['charges'] > 0:
311 | # print("starting to paint 1")
312 | total_chance = int(user['charges'])
313 | i = 0
314 | data = self.get_cor(session)
315 | while total_chance > 0:
316 | total_chance -= 1
317 | i += 1
318 | if settings.X3POINTS:
319 | self.repaintV2(session, total_chance, i, data)
320 | else:
321 | self.repaint(session, total_chance)
322 | sleep_ = random.uniform(0.5, 0.8)
323 | logger.info(f"{self.session_name} | Sleep {sleep_} before continue...")
324 | await asyncio.sleep(sleep_)
325 |
326 | r = random.uniform(2, 4)
327 | if float(self.fromstart) >= self.maxtime / r:
328 | self.claimpx(session)
329 | await asyncio.sleep(random.uniform(2, 5))
330 | if settings.AUTO_TASK:
331 | res = session.get("https://notpx.app/api/v1/mining/task/check/x?name=notpixel",
332 | headers=headers, verify=False)
333 | if res.status_code == 200 and res.json()['x:notpixel'] and self.checked[1] is False:
334 | self.checked[1] = True
335 | logger.success("Task Not pixel on x completed!")
336 | res = session.get("https://notpx.app/api/v1/mining/task/check/x?name=notcoin",
337 | headers=headers, verify=False)
338 | if res.status_code == 200 and res.json()['x:notcoin'] and self.checked[2] is False:
339 | self.checked[2] = True
340 | logger.success("Task Not coin on x completed!")
341 | res = session.get("https://notpx.app/api/v1/mining/task/check/paint20pixels",
342 | headers=headers, verify=False)
343 | if res.status_code == 200 and res.json()['paint20pixels'] and self.checked[3] is False:
344 | self.checked[3] = True
345 | logger.success("Task paint 20 pixels completed!")
346 |
347 | if repaints >= 2049:
348 | res = session.get("https://notpx.app/api/v1/mining/task/check/leagueBonusPlatinum",
349 | headers=headers, verify=False)
350 | if res.status_code == 200 and res.json()['leagueBonusPlatinum'] and self.checked[8] is False:
351 | self.checked[8] = True
352 | logger.success("Upgraded to Plantium league!")
353 | if repaints >= 129:
354 | res = session.get("https://notpx.app/api/v1/mining/task/check/leagueBonusGold",
355 | headers=headers, verify=False)
356 | if res.status_code == 200 and res.json()['leagueBonusGold'] and self.checked[
357 | 7] is False:
358 | self.checked[7] = True
359 | logger.success("Upgraded to Gold league!")
360 | if repaints >= 9:
361 | res = session.get("https://notpx.app/api/v1/mining/task/check/leagueBonusSilver",
362 | headers=headers, verify=False)
363 | if res.status_code == 200 and res.json()['leagueBonusSilver'] and self.checked[
364 | 6] is False:
365 | self.checked[6] = True
366 | logger.success("Upgraded to Silver league!")
367 |
368 | res = session.get("https://notpx.app/api/v1/mining/task/check/leagueBonusBronze",
369 | headers=headers, verify=False)
370 | if res.status_code == 200 and res.json()['leagueBonusBronze'] and self.checked[
371 | 5] is False:
372 | self.checked[5] = True
373 | logger.success("Upgraded to Bronze league!")
374 |
375 |
376 | if settings.AUTO_UPGRADE_PAINT_REWARD:
377 | await self.auto_upgrade_paint(session)
378 | if settings.AUTO_UPGRADE_RECHARGE_SPEED:
379 | await self.auto_upgrade_recharge_speed(session)
380 | if settings.AUTO_UPGRADE_RECHARGE_ENERGY:
381 | await self.auto_upgrade_energy_limit(session)
382 |
383 | else:
384 | logger.warning(f"{self.session_name} | Failed to get user data!")
385 | if self.multi_thread:
386 | sleep_ = randint(settings.SLEEP_TIME_BETWEEN_EACH_ROUND[0], settings.SLEEP_TIME_BETWEEN_EACH_ROUND[1])
387 | logger.info(f"{self.session_name} | Sleep {sleep_}s...")
388 | await asyncio.sleep(sleep_)
389 | else:
390 | await http_client.close()
391 | session.close()
392 | break
393 | except InvalidSession as error:
394 | raise error
395 |
396 | except Exception as error:
397 | logger.error(f"{self.session_name} | Unknown error: {error}")
398 | await asyncio.sleep(delay=randint(60, 120))
399 |
400 |
401 | async def run_tapper(tg_client: Client, proxy: str | None):
402 | try:
403 | sleep_ = randint(1, 15)
404 | logger.info(f"{tg_client.name} | start after {sleep_}s")
405 | await asyncio.sleep(sleep_)
406 | await Tapper(tg_client=tg_client, multi_thread=True).run(proxy=proxy)
407 | except InvalidSession:
408 | logger.error(f"{tg_client.name} | Invalid Session")
409 |
410 |
411 | async def run_tapper1(tg_clients: list[Client], proxies):
412 | proxies_cycle = cycle(proxies) if proxies else None
413 | while True:
414 | for tg_client in tg_clients:
415 | try:
416 | await Tapper(tg_client=tg_client, multi_thread=False).run(
417 | next(proxies_cycle) if proxies_cycle else None)
418 | except InvalidSession:
419 | logger.error(f"{tg_client.name} | Invalid Session")
420 |
421 | sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
422 | logger.info(f"Sleep {sleep_}s...")
423 | await asyncio.sleep(sleep_)
424 |
425 | sleep_ = randint(settings.SLEEP_TIME_BETWEEN_EACH_ROUND[0], settings.SLEEP_TIME_BETWEEN_EACH_ROUND[1])
426 | logger.info(f"Sleep {sleep_}s...")
427 | await asyncio.sleep(sleep_)
428 |
--------------------------------------------------------------------------------
/bot/exceptions/__init__.py:
--------------------------------------------------------------------------------
1 | class InvalidSession(BaseException):
2 | ...
3 |
--------------------------------------------------------------------------------
/bot/exceptions/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/exceptions/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/bot/utils/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/utils/__pycache__/__init__.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/__init__.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/utils/__pycache__/launcher.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/launcher.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/utils/__pycache__/launcher.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/launcher.cpython-312.pyc
--------------------------------------------------------------------------------
/bot/utils/__pycache__/logger.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/logger.cpython-311.pyc
--------------------------------------------------------------------------------
/bot/utils/__pycache__/logger.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/bot/utils/__pycache__/logger.cpython-312.pyc
--------------------------------------------------------------------------------
/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, run_tapper1
13 | from bot.core.query import run_query_tapper, run_query_tapper1
14 | from bot.core.registrator import register_sessions
15 |
16 |
17 | start_text = """
18 |
19 | ███████╗██╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗
20 | ██╔════╝██║╚══███╔╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗
21 | ███████╗██║ ███╔╝ ██║ ██║ ██║██║ ██║█████╗ ██████╔╝
22 | ╚════██║██║ ███╔╝ ██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗
23 | ███████║██║███████╗ ╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║
24 | ╚══════╝╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝
25 |
26 | NotPixel BOT V 1.2
27 | Prepared and Developed by: F.Davoodi
28 |
29 | Select an action:
30 |
31 | 1. Run clicker (Session)
32 | 2. Create session
33 | 3. Run clicker (Query)
34 | """
35 |
36 | global tg_clients
37 |
38 | def get_session_names() -> list[str]:
39 | session_names = sorted(glob.glob("sessions/*.session"))
40 | session_names = [
41 | os.path.splitext(os.path.basename(file))[0] for file in session_names
42 | ]
43 |
44 | return session_names
45 |
46 |
47 | def get_proxies() -> list[Proxy]:
48 | if settings.USE_PROXY_FROM_FILE:
49 | with open(file="bot/config/proxies.txt", encoding="utf-8-sig") as file:
50 | proxies = [Proxy.from_str(proxy=row.strip()).as_url for row in file]
51 | else:
52 | proxies = []
53 |
54 | return proxies
55 |
56 |
57 | async def get_tg_clients() -> list[Client]:
58 | global tg_clients
59 |
60 | session_names = get_session_names()
61 |
62 | if not session_names:
63 | raise FileNotFoundError("Not found session files")
64 |
65 | if not settings.API_ID or not settings.API_HASH:
66 | raise ValueError("API_ID and API_HASH not found in the .env file.")
67 |
68 | tg_clients = [
69 | Client(
70 | name=session_name,
71 | api_id=settings.API_ID,
72 | api_hash=settings.API_HASH,
73 | workdir="sessions/",
74 | plugins=dict(root="bot/plugins"),
75 | )
76 | for session_name in session_names
77 | ]
78 |
79 | return tg_clients
80 |
81 |
82 | async def process() -> None:
83 | parser = argparse.ArgumentParser()
84 | parser.add_argument("-a", "--action", type=int, help="Action to perform")
85 | parser.add_argument("-m", "--multithread", type=str, help="Enable multi-threading")
86 |
87 | action = parser.parse_args().action
88 | ans = parser.parse_args().multithread
89 | logger.info(f"Detected {len(get_session_names())} sessions | {len(get_proxies())} proxies")
90 |
91 | if not action:
92 | print(start_text)
93 |
94 | while True:
95 | action = input("> ")
96 |
97 | if not action.isdigit():
98 | logger.warning("Action must be number")
99 | elif action not in ["1", "2", "3"]:
100 | logger.warning("Action must be 1, 2 or 3")
101 | else:
102 | action = int(action)
103 | break
104 |
105 | if action == 2:
106 | await register_sessions()
107 | elif action == 1:
108 | if ans is None:
109 | while True:
110 | ans = input("> Do you want to run the bot with multi-thread? (y/n) ")
111 | if ans not in ["y", "n"]:
112 | logger.warning("Answer must be y or n")
113 | else:
114 | break
115 |
116 | if ans == "y":
117 | tg_clients = await get_tg_clients()
118 |
119 | await run_tasks(tg_clients=tg_clients)
120 | else:
121 | tg_clients = await get_tg_clients()
122 | proxies = get_proxies()
123 | await run_tapper1(tg_clients=tg_clients, proxies=proxies)
124 | elif action == 3:
125 | if ans is None:
126 | while True:
127 | ans = input("> Do you want to run the bot with multi-thread? (y/n) ")
128 | if ans not in ["y", "n"]:
129 | logger.warning("Answer must be y or n")
130 | else:
131 | break
132 | if ans == "y":
133 | with open("data.txt", "r") as f:
134 | query_ids = [line.strip() for line in f.readlines()]
135 | # proxies = get_proxies()
136 | await run_tasks_query(query_ids)
137 | else:
138 | with open("data.txt", "r") as f:
139 | query_ids = [line.strip() for line in f.readlines()]
140 | proxies = get_proxies()
141 |
142 | await run_query_tapper1(query_ids, proxies)
143 |
144 | async def run_tasks_query(query_ids: list[str]):
145 | proxies = get_proxies()
146 | proxies_cycle = cycle(proxies) if proxies else None
147 | account_name = [i for i in range(len(query_ids) + 10)]
148 | name_cycle = cycle(account_name)
149 | tasks = [
150 | asyncio.create_task(
151 | run_query_tapper(
152 | query=query,
153 | proxy=next(proxies_cycle) if proxies_cycle else None,
154 | name=f"Account{next(name_cycle)}"
155 | )
156 | )
157 | for query in query_ids
158 | ]
159 |
160 | await asyncio.gather(*tasks)
161 | async def run_tasks(tg_clients: list[Client]):
162 | proxies = get_proxies()
163 | proxies_cycle = cycle(proxies) if proxies else None
164 | tasks = [
165 | asyncio.create_task(
166 | run_tapper(
167 | tg_client=tg_client,
168 | proxy=next(proxies_cycle) if proxies_cycle else None,
169 | )
170 | )
171 | for tg_client in tg_clients
172 | ]
173 |
174 | await asyncio.gather(*tasks)
175 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/data.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/data.txt
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '1'
2 | services:
3 | bot:
4 | container_name: 'notpixel'
5 | build:
6 | context: .
7 | stop_signal: SIGINT
8 | restart: unless-stopped
9 | command: "python3 main.py -a 1 -m n"
10 | volumes:
11 | - .:/app
12 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sizifart/NotPixelBot/6af2bc00a63753f4b002cabc8ad7090a9d0bc797/requirements.txt
--------------------------------------------------------------------------------
/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 | :loop
33 | python main.py
34 | echo Restarting the program in 2 seconds...
35 | timeout /t 2 /nobreak >nul
36 | goto :loop
37 |
--------------------------------------------------------------------------------