UNPKG

zixineabra

Version:

A Telegram utility bot for managing sessions, logging in accounts, and retrieving WebView data.

454 lines (406 loc) 13.7 kB
const fs = require("fs"); const path = require("path"); const axios = require("axios"); const colors = require("colors/safe"); const readline = require("readline"); const { performance } = require("perf_hooks"); const winston = require("winston"); const printBanner = require("./banner/galkurta-banner.js"); printBanner(); // Create a custom logger using Winston const logger = winston.createLogger({ level: "info", format: winston.format.combine( winston.format.timestamp(), winston.format.printf(({ timestamp, level, message }) => { let coloredLevel; switch (level) { case "info": coloredLevel = colors.blue(level.toUpperCase()); break; case "warn": coloredLevel = colors.yellow(level.toUpperCase()); break; case "error": coloredLevel = colors.red(level.toUpperCase()); break; default: coloredLevel = level.toUpperCase(); } return `${timestamp} | ${coloredLevel} | ${message}`; }) ), transports: [new winston.transports.Console()], }); class Babydoge { constructor() { this.headers = { Accept: "application/json, text/plain, */*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "vi-VN,vi;q=0.9,en-US;q=0.8,en;q=0.7", "Content-Type": "application/x-www-form-urlencoded", Origin: "https://babydogepawsbot.com", Referer: "https://babydogepawsbot.com/", "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"', "Sec-Ch-Ua-Mobile": "?1", "Sec-Ch-Ua-Platform": '"Android"', "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site", "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", }; this.line = colors.white("-".repeat(42)); } async http(url, headers, data = null) { let attempts = 0; const maxAttempts = 3; while (attempts < maxAttempts) { try { let res; if (data === null) { res = await axios.get(url, { headers }); } else { res = await axios.post(url, data, { headers }); } if (typeof res.data !== "object") { logger.error("Did not receive a valid JSON response!"); attempts++; await this.sleep(2000); continue; } return res; } catch (error) { attempts++; logger.error( `Connection error (Attempt ${attempts}/${maxAttempts}): ${error.message}` ); if (attempts < maxAttempts) { await this.sleep(5000); } else { break; } } } throw new Error("Unable to connect after 3 attempts"); } async login(tgData) { const url = "https://backend.babydogepawsbot.com/authorize"; const headers = { ...this.headers }; try { const res = await this.http(url, headers, tgData); if (res.data) { logger.info("Login successful!"); const { balance, energy, max_energy, access_token, league } = res.data; const points_per_tap = league.points_per_tap; logger.info(`Balance: ${balance}`); logger.info(`Energy: ${energy}/${max_energy}`); logger.info(`Points per tap: ${points_per_tap}`); return { access_token, energy, points_per_tap }; } else { logger.error("Login failed!"); return null; } } catch (error) { logger.error(`Error: ${error.message}`); return null; } } async daily(access_token) { const checkUrl = "https://backend.babydogepawsbot.com/getDailyBonuses"; const claimUrl = "https://backend.babydogepawsbot.com/pickDailyBonus"; const headers = { ...this.headers, "X-Api-Key": access_token }; try { const checkRes = await this.http(checkUrl, headers); if (checkRes.data && checkRes.data.has_available) { logger.info("Daily check-in available!"); const claimRes = await this.http(claimUrl, headers, ""); if (claimRes.data) { logger.info("Daily check-in successful!"); } else { logger.error("Daily check-in failed!"); } } else { logger.info("Daily check-in already claimed today."); } } catch (error) { logger.error( `Error when checking or claiming daily bonus: ${error.message}` ); } } async getTask(access_token) { const url = "https://backend.babydogepawsbot.com/channels"; const headers = { ...this.headers, "X-Api-Key": access_token }; try { const res = await this.http(url, headers); if (res && res.data && res.data.channels) { const availableChannels = res.data.channels.filter( (channel) => channel.is_available && channel.type !== "telegram" ); return availableChannels; } else { logger.info("No tasks available."); return []; } } catch (error) { logger.error(`Error: ${error.message}`); return []; } } async claimTask(access_token, channel) { const url = "https://backend.babydogepawsbot.com/channels"; const headers = { ...this.headers, "X-Api-Key": access_token, "Content-Type": "application/json", }; const data = JSON.stringify({ channel_id: channel.id }); try { const res = await this.http(url, headers, data); if (res && res.data) { logger.info(`Completing task: ${channel.title} | Status: successful`); } else { logger.error(`Error when claiming reward for task: ${channel.title}`); } } catch (error) { logger.error(`Error when claiming reward: ${error.message}`); } } async tap(access_token, initialEnergy, points_per_tap) { const url = "https://backend.babydogepawsbot.com/mine"; const headers = { ...this.headers, "X-Api-Key": access_token, "Content-Type": "application/json", }; let energy = initialEnergy; try { while (energy >= 50) { const randomEnergy = Math.floor(Math.random() * (50 - 10 + 1)) + 10; let count = Math.floor((energy - randomEnergy) / points_per_tap); if (count <= 0) { logger.info( "Not enough energy to continue tapping switching account!" ); break; } const data = JSON.stringify({ count }); const res = await this.http(url, headers, data); if (res.data) { const { balance, mined, newEnergy, league, current_league, next_league, } = res.data.mine; logger.info( `Tapped ${mined} times | Balance: ${balance} | Energy: ${newEnergy}` ); energy = newEnergy; if (energy < 50) { logger.info( "Energy too low to continue tapping switching account!" ); break; } } else { logger.error("Error, unable to tap!"); break; } } } catch (error) { logger.error(`Error: ${error.message}`); } } async buyCards(access_token) { const listCardsUrl = "https://backend.babydogepawsbot.com/cards"; const upgradeUrl = "https://backend.babydogepawsbot.com/cards"; const getMeUrl = "https://backend.babydogepawsbot.com/getMe"; const headers = { ...this.headers, "X-Api-Key": access_token, "Content-Type": "application/json", }; try { const getMeRes = await this.http(getMeUrl, headers); let balance = getMeRes.data.balance; const res = await this.http(listCardsUrl, headers); if (res.data && res.data.length > 0) { for (const category of res.data) { for (const card of category.cards) { if (balance < card.upgrade_cost) { logger.error("Insufficient balance to buy card!"); return; } if (card.cur_level === 0 && card.is_available) { const upgradeData = JSON.stringify({ id: card.id }); const upgradeRes = await this.http( upgradeUrl, headers, upgradeData ); if (upgradeRes.data) { balance = upgradeRes.data.balance; logger.info( `Buying card ${card.name} | Status: Successful | New Balance: ${balance}` ); } else { logger.error(`Buying card ${card.name} | Status: Failed`); } } } } } else { logger.info("No new cards available."); } } catch (error) { logger.error(`Error: ${error.message}`); } } async upgradeMyCards(access_token) { const listCardsUrl = "https://backend.babydogepawsbot.com/cards"; const upgradeUrl = "https://backend.babydogepawsbot.com/cards"; const getMeUrl = "https://backend.babydogepawsbot.com/getMe"; const headers = { ...this.headers, "X-Api-Key": access_token, "Content-Type": "application/json", }; try { const getMeRes = await this.http(getMeUrl, headers); let balance = getMeRes.data.balance; const res = await this.http(listCardsUrl, headers); if (res.data && res.data.length > 0) { while (true) { let upgraded = false; for (const category of res.data) { for (const card of category.cards) { if (balance < card.upgrade_cost) { logger.error("Insufficient balance to upgrade card!"); return; } if (balance >= card.upgrade_cost && card.is_available) { const upgradeData = JSON.stringify({ id: card.id }); const upgradeRes = await this.http( upgradeUrl, headers, upgradeData ); if (upgradeRes.data) { balance = upgradeRes.data.balance; logger.info( `Upgrading card ${card.name} Status: Successful | New Balance: ${balance}` ); upgraded = true; } else { logger.error(`Upgrading card ${card.name} | Status: Failed`); } } } } if (!upgraded) break; } } else { logger.info("No cards need upgrading."); } } catch (error) { logger.error(`Error when upgrading card: ${error.message}`); } } async sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } askQuestion(query) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => rl.question(query, (ans) => { rl.close(); resolve(ans); }) ); } async waitWithCountdown(seconds) { for (let i = seconds; i >= 0; i--) { readline.cursorTo(process.stdout, 0); process.stdout.write( colors.cyan( `Completed all accounts, waiting ${i} seconds to continue the loop` ) ); await new Promise((resolve) => setTimeout(resolve, 1000)); } console.log(""); } async main() { const dataFile = path.join(__dirname, "./../data/theFreeDogs_bot.txt"); const data = fs .readFileSync(dataFile, "utf8") .replace(/\r/g, "") .split("\n") .filter(Boolean); if (data.length <= 0) { logger.error("No accounts added!"); process.exit(); } console.log(this.line); const buyCards = await this.askQuestion( colors.cyan("Do you want to buy new cards? (y/n): ") ); const buyCardsDecision = buyCards.toLowerCase() === "y"; const upgradeMyCards = await this.askQuestion( colors.cyan("Do you want to upgrade cards? (y/n): ") ); const upgradeMyCardsDecision = upgradeMyCards.toLowerCase() === "y"; while (true) { const start = performance.now(); for (const [index, tgData] of data.entries()) { const userData = JSON.parse( decodeURIComponent(tgData.split("&")[1].split("=")[1]) ); const firstName = userData.first_name; logger.info(`Account ${index + 1}/${data.length} | ${firstName}`); const loginData = await this.login(tgData); if (!loginData) { logger.error("Login failed, moving to the next account."); continue; } const { balance, access_token, energy, points_per_tap } = loginData; if (access_token) { await this.daily(access_token); const availableChannels = await this.getTask(access_token); for (const channel of availableChannels) { await this.claimTask(access_token, channel); } if (buyCardsDecision) { await this.buyCards(access_token, balance); } if (upgradeMyCardsDecision) { await this.upgradeMyCards(access_token, balance); } await this.tap(access_token, energy, points_per_tap); } await this.sleep(5000); } await this.waitWithCountdown(60); } } } if (require.main === module) { process.on("SIGINT", () => { console.log( colors.yellow("\nGracefully shutting down from SIGINT (Ctrl+C)") ); process.exit(); }); new Babydoge().main().catch((error) => { logger.error(`Unhandled error in main execution: ${error.message}`); logger.error(error.stack); process.exit(1); }); }