├── .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 | --------------------------------------------------------------------------------