├── query.txt ├── README.md └── bot.py /query.txt: -------------------------------------------------------------------------------- 1 | user= 2 | query_id 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Banana Bot 3 | 4 | Banana harvest by CARV 5 | 6 | Register : https://t.me/OfficialBananaBot/banana?startapp=referral=FI85BH1 7 | 8 | 9 | ## Installation 10 | 11 | 1. **Download Python 3.12+** 12 | - Pastikan kamu sudah memiliki Python versi 3.10 atau yang lebih baru. Kamu bisa mendownloadnya dari [python.org](https://www.python.org/downloads/). 13 | 14 | 2. **Install Module** 15 | - Buka command prompt atau terminal, lalu jalankan perintah: 16 | ``` 17 | pip install requests colorama 18 | ``` 19 | - Ini akan menginstal dua modul yang diperlukan: `requests` untuk melakukan permintaan HTTP dan `colorama` untuk memberi warna teks di konsol. 20 | 21 | 3. **Buka Bot Banana di PC (Telegram Web / Desktop)** 22 | - Buka Telegram Web atau Telegram Desktop di PC kamu. 23 | 24 | 4. **Ambil query_id** 25 | - Buka Bot Banana dan lakukan inspeksi elemen di halaman tersebut. 26 | - Pergi ke tab Application (biasanya di browser, ada di bagian atas inspector). 27 | - Pilih `session storage` dan kemudian `banana.carv.io`. 28 | - Di dalamnya, cari `__telegram_initparam` dan temukan `tgwebappdata`. 29 | - Ambil nilai `query_id=xxx` atau `user=xxx` (ambil semua nilai ini kecuali `tgwebappnya`). 30 | 31 | 5. **Paste di query.txt** 32 | - Buat atau buka file `query.txt` dan paste nilai `query_id` atau `user=xxx` yang telah kamu ambil sebelumnya. 33 | 34 | ## Features 35 | - Auto Tap 36 | - Auto Clear Quest 37 | - Auto Claim 38 | - Auto Gacha Harvest 39 | - Auto Sell Banana If you have more than 1 40 | - Multi Account 41 | - Loop based on the account with the fastest claim time 42 | 43 | 44 | For quest with bind, it will automatically skip, please do by yourself 45 | 46 | Kerjain sendiri tod, tar ga ke bind nyalahin sc 47 | 48 | Entahlah gw males nulis 49 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import time 3 | from colorama import Fore, Style, init 4 | 5 | # Initialize colorama 6 | init(autoreset=True) 7 | 8 | # Base URL for requests 9 | base_url = 'https://interface.carv.io/banana' 10 | 11 | # Headers for the requests 12 | headers = { 13 | 'Content-Type': 'application/json', 14 | 'Accept': 'application/json, text/plain, */*', 15 | 'Accept-Encoding': 'gzip, deflate, br, zstd', 16 | 'Accept-Language': 'en-US,en;q=0.9', 17 | 'Origin': 'https://banana.carv.io', 18 | 'Referer': 'https://banana.carv.io/', 19 | 'Sec-CH-UA': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"', 20 | 'Sec-CH-UA-Mobile': '?0', 21 | 'Sec-CH-UA-Platform': '"Windows"', 22 | 'Sec-Fetch-Dest': 'empty', 23 | 'Sec-Fetch-Mode': 'cors', 24 | 'Sec-Fetch-Site': 'same-site', 25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 26 | 'X-App-ID': 'carv', 27 | } 28 | 29 | def print_welcome_message(): 30 | print(r""" 31 | 32 | _ _ _ ____ _ ___ _ 33 | | \| | /_\ |_ / /_\ | _ \ /_\ 34 | | .` |/ _ \ / / / _ \| / / _ \ 35 | |_|\_/_/ \_\/___/_/ \_\_|_\/_/ \_\ 36 | 37 | 38 | """) 39 | print(Fore.GREEN + Style.BRIGHT + "BANANA BOT") 40 | print(Fore.CYAN + Style.BRIGHT + "Jajanin dong orang baik :)") 41 | print(Fore.YELLOW + Style.BRIGHT + "0x5bc0d1f74f371bee6dc18d52ff912b79703dbb54") 42 | print(Fore.RED + Style.BRIGHT + "Update Link: https://github.com/dcbott01/banana") 43 | print(Fore.BLUE + Style.BRIGHT + "Tukang Rename MATI AJA") 44 | 45 | def login(tg_info): 46 | login_payload = { 47 | "tgInfo": tg_info, 48 | "InviteCode": "" 49 | } 50 | 51 | login_url = f'{base_url}/login' 52 | login_response = requests.post(login_url, headers=headers, json=login_payload) 53 | time.sleep(1) # Sleep for 1 second 54 | 55 | login_response_data = login_response.json() 56 | if 'data' in login_response_data and 'token' in login_response_data['data']: 57 | return login_response_data['data']['token'] 58 | else: 59 | print('Token not found in the response.') 60 | return None 61 | 62 | def achieve_quest(quest_id): 63 | achieve_url = f'{base_url}/achieve_quest' 64 | achieve_payload = {"quest_id": quest_id} 65 | response = requests.post(achieve_url, headers=headers, json=achieve_payload) 66 | return response 67 | 68 | def claim_quest(quest_id): 69 | claim_url = f'{base_url}/claim_quest' 70 | claim_payload = {"quest_id": quest_id} 71 | response = requests.post(claim_url, headers=headers, json=claim_payload) 72 | return response 73 | 74 | def do_click(click_count): 75 | click_url = f'{base_url}/do_click' 76 | click_payload = {"clickCount": click_count} 77 | response = requests.post(click_url, headers=headers, json=click_payload) 78 | return response 79 | 80 | def get_lottery_info(): 81 | lottery_info_url = f'{base_url}/get_lottery_info' 82 | response = requests.get(lottery_info_url, headers=headers) 83 | return response 84 | 85 | def claim_lottery(): 86 | claim_lottery_url = f'{base_url}/claim_lottery' 87 | claim_payload = {"claimLotteryType": 1} 88 | response = requests.post(claim_lottery_url, headers=headers, json=claim_payload) 89 | return response 90 | 91 | def do_lottery(): 92 | do_lottery_url = f'{base_url}/do_lottery' 93 | response = requests.post(do_lottery_url, headers=headers, json={}) 94 | return response 95 | 96 | def get_banana_list(): 97 | banana_list_url = f'{base_url}/get_banana_list' 98 | response = requests.get(banana_list_url, headers=headers) 99 | return response 100 | 101 | def do_sell(banana_id, sell_count): 102 | sell_url = f'{base_url}/do_sell' 103 | sell_payload = { 104 | "bananaId": banana_id, 105 | "sellCount": sell_count 106 | } 107 | response = requests.post(sell_url, headers=headers, json=sell_payload) 108 | return response 109 | 110 | def calculate_remaining_time(lottery_data): 111 | last_countdown_start_time = lottery_data.get('last_countdown_start_time', 0) 112 | countdown_interval = lottery_data.get('countdown_interval', 0) # in minutes 113 | countdown_end = lottery_data.get('countdown_end', False) 114 | 115 | if not countdown_end: 116 | current_time = int(time.time() * 1000) # Current time in milliseconds 117 | elapsed_time_minutes = (current_time - last_countdown_start_time) / 60000 # Convert elapsed time to minutes 118 | remaining_time_minutes = max(countdown_interval - elapsed_time_minutes, 0) # Remaining time in minutes 119 | return remaining_time_minutes 120 | return 0 121 | 122 | def ask_user_choice(prompt): 123 | while True: 124 | choice = input(prompt).strip().lower() 125 | if choice in ['yes', 'no']: 126 | return choice == 'yes' 127 | print("Invalid input. Please enter 'yes' or 'no'.") 128 | 129 | def process_account(tg_info, perform_lottery, perform_quests): 130 | token = login(tg_info) 131 | if token: 132 | headers['Authorization'] = token 133 | headers.update({ 134 | 'Cache-Control': 'no-cache', 135 | 'Pragma': 'no-cache' 136 | }) 137 | 138 | # Fetch user info 139 | user_info_url = f'{base_url}/get_user_info' 140 | user_info_response = requests.get(user_info_url, headers=headers) 141 | print(f"{Fore.GREEN}====== Berhasil Mendapatkan Data ======") 142 | time.sleep(1) # Sleep for 1 second 143 | user_info_data = user_info_response.json() 144 | 145 | user_info = user_info_data.get('data', {}) 146 | username = user_info.get('username', 'N/A') 147 | peel = user_info.get('peel', 'N/A') 148 | usdt = user_info.get('usdt', 'N/A') 149 | banana_name = user_info.get('equip_banana', {}).get('name', 'N/A') 150 | today_click_count = user_info.get('today_click_count', 0) 151 | max_click_count = user_info.get('max_click_count', 0) 152 | 153 | print(f"{Fore.CYAN}[Username] : {Fore.MAGENTA}{username}{Style.RESET_ALL}") 154 | print(f"{Fore.CYAN}[Peels] : {Fore.MAGENTA}{peel}{Style.RESET_ALL}") 155 | print(f"{Fore.CYAN}[USDT] : {Fore.MAGENTA}{usdt}{Style.RESET_ALL}") 156 | print(f"{Fore.CYAN}[Banana Name] : {Fore.MAGENTA}{banana_name}{Style.RESET_ALL}") 157 | print(f"{Fore.CYAN}[Today Click Count] : {Fore.MAGENTA}{today_click_count}{Style.RESET_ALL}") 158 | 159 | remaining_time_minutes = float('inf') # Initialize with an arbitrary large value 160 | 161 | # Fetch lottery info if the user chose to perform lottery or to check claim 162 | if perform_lottery or True: # Always check lottery info 163 | lottery_info_response = get_lottery_info() 164 | time.sleep(1) # Sleep for 1 second 165 | lottery_info_data = lottery_info_response.json() 166 | 167 | # Calculate remaining time for claiming 168 | remaining_time_minutes = calculate_remaining_time(lottery_info_data.get('data', {})) 169 | 170 | # Convert remaining time to hours, minutes, seconds 171 | remaining_hours = int(remaining_time_minutes // 60) 172 | remaining_minutes = int(remaining_time_minutes % 60) 173 | remaining_seconds = int((remaining_time_minutes * 60) % 60) 174 | 175 | print(f"{Fore.YELLOW}Sisa Waktu untuk claim Banana: " 176 | f"{remaining_hours} jam {remaining_minutes} menit {remaining_seconds} detik") 177 | 178 | # Check for remaining lottery count and perform lottery if needed 179 | remain_lottery_count = lottery_info_data.get('data', {}).get('remain_lottery_count', 0) 180 | print(f"{Fore.YELLOW}[Gacha Harvest] : {remain_lottery_count}") 181 | if remain_lottery_count > 0 and perform_lottery: 182 | print(f"{Fore.YELLOW}Melakukan Lottery...") 183 | do_lottery_response = do_lottery() 184 | 185 | # Parse and print lottery result 186 | if do_lottery_response.status_code == 200: 187 | lottery_result = do_lottery_response.json().get('data', {}) 188 | banana_name = lottery_result.get('name', 'N/A') 189 | sell_exchange_peel = lottery_result.get('sell_exchange_peel', 'N/A') 190 | sell_exchange_usdt = lottery_result.get('sell_exchange_usdt', 'N/A') 191 | 192 | print(f"{Fore.GREEN}====== Berhasil Mendapatkan Banana {banana_name} ======") 193 | print(f"{Fore.YELLOW}Banana Name : {banana_name}") 194 | print(f"{Fore.YELLOW}Peel Limit : {lottery_result.get('daily_peel_limit', 'N/A')}") 195 | print(f"{Fore.YELLOW}Harga : {sell_exchange_peel} Peel, {sell_exchange_usdt} Usdt") 196 | print(f"{Fore.GREEN}======") 197 | 198 | time.sleep(1) # Sleep for 1 second 199 | 200 | # Claim lottery if countdown is finished 201 | if remaining_time_minutes <= 0: 202 | print(f"{Fore.YELLOW}Claiming Lottery Reward...") 203 | claim_lottery_response = claim_lottery() 204 | 205 | banana_list_response = get_banana_list() 206 | if banana_list_response.status_code == 200: 207 | banana_list_data = banana_list_response.json().get('data', {}).get('banana_list', []) 208 | print(f"{Fore.YELLOW}====== Try To Sell Banana ======") 209 | for banana in banana_list_data: 210 | banana_id = banana.get('banana_id', 'N/A') 211 | banana_name = banana.get('name', 'N/A') 212 | banana_url = banana.get('url', 'N/A') 213 | banana_rarity = banana.get('rarity', 'N/A') 214 | banana_ripeness = banana.get('ripeness', 'N/A') 215 | daily_peel_limit = banana.get('daily_peel_limit', 'N/A') 216 | sell_exchange_peel = banana.get('sell_exchange_peel', 'N/A') 217 | sell_exchange_usdt = banana.get('sell_exchange_usdt', 'N/A') 218 | count = banana.get('count', 0) 219 | 220 | # Sell bananas if count is 2 or more 221 | if count >= 2: 222 | print(f"{Fore.YELLOW}Menjual {banana_name} (Banana ID: {banana_id}) sebanyak 1...") 223 | sell_response = do_sell(banana_id, 1) 224 | if sell_response.status_code == 200: 225 | print(f"{Fore.GREEN}Berhasil menjual 1 {banana_name}.") 226 | else: 227 | print(f"{Fore.RED}Gagal menjual {banana_name}: {sell_response.status_code}") 228 | 229 | else: 230 | print(f"{Fore.RED}Error fetching banana list: {banana_list_response.status_code}") 231 | 232 | # Perform quests if user chose to 233 | if perform_quests: 234 | print(f"{Fore.GREEN}====== Berhasil Mendapatkan List Quest ======") 235 | 236 | # Check for clicks if below max clicks 237 | if today_click_count < max_click_count: 238 | click_count = max_click_count - today_click_count 239 | if click_count > 0: 240 | print(f"{Fore.YELLOW}Performing {click_count} clicks...") 241 | do_click(click_count) 242 | time.sleep(1) # Sleep for 1 second 243 | else: 244 | print(f"{Fore.YELLOW}Click tidak diperlukan atau sudah mencapai batas maksimum.") 245 | 246 | # Fetch quest list 247 | quest_list_url = f'{base_url}/get_quest_list' 248 | quest_list_response = requests.get(quest_list_url, headers=headers) 249 | time.sleep(1) # Sleep for 1 second 250 | quest_list_data = quest_list_response.json() 251 | 252 | # Extract and print quest names and claim statuses 253 | quest_list = quest_list_data.get('data', {}).get('quest_list', []) 254 | for index, quest in enumerate(quest_list, start=1): 255 | quest_name = quest.get('quest_name', 'N/A') 256 | is_achieved = quest.get('is_achieved', False) 257 | is_claimed = quest.get('is_claimed', False) 258 | quest_id = quest.get('quest_id') 259 | 260 | # Convert boolean to Yes/No 261 | achieved_status = "Yes" if is_achieved else "No" 262 | claimed_status = "Yes" if is_claimed else "No" 263 | 264 | # Color coding for quest details 265 | quest_name_color = Fore.CYAN 266 | achieved_color = Fore.GREEN if is_achieved else Fore.RED 267 | claimed_color = Fore.GREEN if is_claimed else Fore.RED 268 | 269 | print(f"{Fore.BLUE}[Quest {index}] : {quest_name_color}{quest_name} {Fore.BLUE}, " 270 | f"[Is Achieved] : {achieved_color}{achieved_status} {Fore.BLUE}, " 271 | f"[Is Claimed] : {claimed_color}{claimed_status}{Style.RESET_ALL}") 272 | 273 | # Skip the achievement process for 'bind' quests 274 | if 'bind' in quest_name.lower(): 275 | if not is_achieved: 276 | print(f"{Fore.YELLOW}Skipping Quest, Please do by Yourself") 277 | time.sleep(1) # Sleep for 1 second 278 | continue 279 | 280 | # Achieve quests if not achieved 281 | if not is_achieved: 282 | # Automatically achieve the quest without prompting 283 | achieve_response = achieve_quest(quest_id) 284 | time.sleep(1) # Sleep for 1 second 285 | 286 | # Claim quests if achieved and not claimed 287 | if is_achieved and not is_claimed: 288 | # Automatically claim the quest without prompting 289 | claim_response = claim_quest(quest_id) 290 | time.sleep(1) # Sleep for 1 second 291 | 292 | 293 | print(f"{Fore.GREEN}====== Memproses Akun Berikutnya.... ======") 294 | 295 | else: 296 | print(f"{Fore.RED}Unable to fetch user info and quest list due to missing token.") 297 | 298 | def main(): 299 | # Print the welcome message 300 | print_welcome_message() 301 | 302 | # Read tg_info from file 303 | with open('query.txt', 'r') as file: 304 | tg_infos = file.readlines() 305 | 306 | # Collect user choices once at the start 307 | perform_lottery = ask_user_choice("Do you want to do gacha Harvest? (yes/no): ") 308 | perform_quests = ask_user_choice("Do you want to do quests? (yes/no): ") 309 | 310 | while True: 311 | min_remaining_time = float('inf') 312 | 313 | # Process all accounts and find the one with the minimum remaining claim time 314 | for index, tg_info in enumerate(tg_infos, start=1): 315 | tg_info = tg_info.strip() 316 | if tg_info: 317 | print(f"{Fore.CYAN}====== Memproses Akun {index} ======") 318 | token = login(tg_info) 319 | if token: 320 | headers['Authorization'] = token 321 | headers.update({ 322 | 'Cache-Control': 'no-cache', 323 | 'Pragma': 'no-cache' 324 | }) 325 | 326 | # Fetch lottery info 327 | lottery_info_response = get_lottery_info() 328 | time.sleep(1) # Sleep for 1 second 329 | lottery_info_data = lottery_info_response.json() 330 | 331 | # Calculate remaining time for claiming 332 | remaining_time_minutes = calculate_remaining_time(lottery_info_data.get('data', {})) 333 | if remaining_time_minutes < min_remaining_time: 334 | min_remaining_time = remaining_time_minutes 335 | 336 | process_account(tg_info, perform_lottery, perform_quests) 337 | time.sleep(5) # Sleep for 5 seconds between accounts 338 | 339 | if min_remaining_time < float('inf'): 340 | # Convert remaining time to hours, minutes, seconds 341 | remaining_hours = int(min_remaining_time // 60) 342 | remaining_minutes = int(min_remaining_time % 60) 343 | remaining_seconds = int((min_remaining_time * 60) % 60) 344 | 345 | print(f"{Fore.GREEN}Menunggu {remaining_hours} jam {remaining_minutes} menit {remaining_seconds} detik sebelum memproses ulang...") 346 | time.sleep(min_remaining_time * 60) # Sleep for the minimum remaining time before re-evaluating 347 | else: 348 | print(f"{Fore.RED}Tidak ada akun yang memenuhi kriteria claim dalam waktu dekat.") 349 | print(f"{Fore.GREEN}Menunggu waktu sebelum memproses ulang...") 350 | time.sleep(10 * 60) # Sleep for 10 minutes before re-evaluating 351 | 352 | if __name__ == '__main__': 353 | main() 354 | --------------------------------------------------------------------------------