diff --git a/.gitignore b/.gitignore index a0d932c..a06ecea 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ data.json settings.json yarn-error.log yarn.lock -db.json1 \ No newline at end of file +db.json1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d9310a9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) Minicx and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0afbc44 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +
+

HK_BOT🤖

+ Hits + License +
+ +# Installing + +1. #### Cloning repo + + To do this run `git clone https://git.disroot.org/minicx/hk_bot.git` +2. #### Installing all dependencies + + Run in `hk_bot` directory `npm install` or `yarn install` +3. #### Starting + + Run `npm start` or `yarn start` + +
+ Other commands + + | Command | Description | + | ------- | ------------------------------------------------------------------ | + | build | just compile all `.ts` files to `build` directory into `.js` | + +
+ +# Format of [Faucet](https://faucetpay.io) wallets data + +* **❗ The script currently does not use the email or password of the faucet account ❗** +* **JSON file must be in root of `hk_bot` directory** + +*
+ Explanation.json + + ```json + { + "": { + "mail_passphrase": "", + "faucetpay": { + "username": "", + "password": "" + } + } + } + ``` + +
+ + +# Creator and contributors +
+ minicx_pict + Main devoloper +
+ + diff --git a/automatization.ts b/automatization.ts index b57e827..bf07f35 100644 --- a/automatization.ts +++ b/automatization.ts @@ -1,584 +1,932 @@ import Hero from "@ulixee/hero"; -import * as telegram from 'telegram'; +import * as telegram from "telegram"; import { sleep } from "telegram/Helpers"; import { AccountInterface } from "./interfaces/databaseInterface"; import { prevTaskInterface } from "./interfaces/otherInterfaces"; import logger from "./logger"; -import { CaptchaError, getMessagesByEntity, NoNewMessagesError, waitNewMessages } from "./utils"; -import {settings} from './database' +import { + CaptchaError, + getMessagesByEntity, + NoNewMessagesError, + waitNewMessages, +} from "./utils"; +import { settings } from "./database"; import { isNull } from "lodash"; - -export const vertification=async function (client: telegram.TelegramClient,worker: AccountInterface,hero: Hero,url: string,botEntity: telegram.Api.Chat | telegram.Api.User,idOfLastMessage: number) { - await hero.goto(url,{timeoutMs:2_000_000}); - await hero.waitForLoad('AllContentLoaded',{timeoutMs:1180_000}); - const captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); - if (captchaButton!=null){ - let verify=hero.document.querySelector('body > section > h2'); - while (isNull(verify)!=true && (await verify.textContent)!.includes('All right!')==false){ - const isCaptchaPassed=hero.document.querySelector("input[id='recaptcha-token']"); - if (isNull(isCaptchaPassed) || (await isCaptchaPassed.$isVisible)==false){ - await hero.interact({click:{element: captchaButton, verification: 'exactElement'}}); +export const vertification = async function (hero: Hero, url: string) { + await hero.goto(url, { timeoutMs: 2_000_000 }); + await hero.waitForLoad("AllContentLoaded", { timeoutMs: 1180_000 }); + const captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); + if (captchaButton != null) { + let verify = hero.document.querySelector("body > section > h2"); + while ( + isNull(verify) != true && + (await verify.textContent)!.includes("All right!") == false + ) { + const isCaptchaPassed = hero.document.querySelector( + "input[id='recaptcha-token']" + ); + if ( + isNull(isCaptchaPassed) || + (await isCaptchaPassed.$isVisible) == false + ) { + await hero.interact({ + click: { + element: captchaButton, + verification: "exactElement", + }, + }); await sleep(5000); - verify=hero.document.querySelector('body > section > h2'); + verify = hero.document.querySelector("body > section > h2"); } else { logger.error("Captcha detected"); throw new CaptchaError("Auhtung captcha detected"); } } - } else { - throw new Error('Cant find captcha button'); + throw new Error("Cant find captcha button"); } -} +}; -export const doSitesTasks=async function (client: telegram.TelegramClient,worker: AccountInterface,hero: Hero,botEntity: telegram.Api.Chat | telegram.Api.User,tasksSelector: telegram.Api.Message) { - const taskSitesButton=tasksSelector.buttons![1][0]; - let prevTask: prevTaskInterface={ - task:tasksSelector, - lastMessage:tasksSelector +export const doSitesTasks = async function ( + client: telegram.TelegramClient, + worker: AccountInterface, + hero: Hero, + botEntity: telegram.Api.Chat | telegram.Api.User, + tasksSelector: telegram.Api.Message +) { + const taskSitesButton = tasksSelector.buttons![1][0]; + const prevTask: prevTaskInterface = { + task: tasksSelector, + lastMessage: tasksSelector, }; - mainLoop: - while (true){ + mainLoop: while (true) { await sleep(2000); - await taskSitesButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const task=(await client.getMessages(botEntity,{ - minId:prevTask.lastMessage.id, - // search: (await settings.botMessages()).tasksSelector, - }))[0]; + await taskSitesButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const task = ( + await client.getMessages(botEntity, { + minId: prevTask.lastMessage.id, + // search: (await settings.botMessages()).tasksSelector, + }) + )[0]; - if (task.buttonCount==2){ - + if (task.buttonCount == 2) { logger.debug(`New ad task | ${worker.phoneNumber}`); - - const urlButton=task.buttons![0][0]; - const skipButton=task.buttons![0][1]; - await hero.goto(urlButton.url!,{timeoutMs:2_000_000}); - await hero.waitForLoad('AllContentLoaded',{timeoutMs:1180_000}); - - let captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); + const urlButton = task.buttons![0][0]; + const skipButton = task.buttons![0][1]; + await hero.goto(urlButton.url!, { timeoutMs: 2_000_000 }); + await hero.waitForLoad("AllContentLoaded", { timeoutMs: 1180_000 }); + let captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); - if (isNull(captchaButton) && (await hero.activeTab.url).includes('hkbots')){ - if (prevTask.task.message==task.message){ - logger.warn(`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`); - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; + if ( + isNull(captchaButton) && + (await hero.activeTab.url).includes("hkbots") + ) { + if (prevTask.task.message == task.message) { + logger.warn( + `Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......` + ); + await skipButton.click({ sharePhone: false }); + await waitNewMessages(client, worker, botEntity, task.id); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; } else { - prevTask.task=task; - logger.warn(`Captcha isnt detected... | ${worker.phoneNumber}`); - } + prevTask.task = task; + logger.warn( + `Captcha isnt detected... | ${worker.phoneNumber}` + ); + } } else { - prevTask.task=task; - if ((await hero.activeTab.url).includes('hkbots')){ - if (await captchaButton.$isClickable!=true){ + prevTask.task = task; + if ((await hero.activeTab.url).includes("hkbots")) { + if ((await captchaButton.$isClickable) != true) { // timer page logger.warn(`Found timer... | ${worker.phoneNumber}`); - if (settings.bypassMode==true){ - logger.warn(`Bypassing timer... | ${worker.phoneNumber}`); - try{ - await hero.executeJs("document.getElementById('form').setAttribute('style', '')"); - } catch (err){ + if (settings.bypassMode == true) { + logger.warn( + `Bypassing timer... | ${worker.phoneNumber}` + ); + try { + await hero.executeJs( + "document.getElementById('form').setAttribute('style', '')" + ); + } catch (err) { logger.error(`Something went wrong due bypass`); } - } else { - while (hero.document.querySelector("i[id='timer']")!=null && await captchaButton.$isClickable!=true){ + while ( + hero.document.querySelector("i[id='timer']") != + null && + (await captchaButton.$isClickable) != true + ) { await sleep(1000); } } } - const now=new Date(); - while (await hero.activeTab.url==urlButton.url!){ - if ((+(new Date())-+now)/1000>2*60){ - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; - logger.warn(`Anomaly activity in browser. Please checkout`); + const now = new Date(); + while ((await hero.activeTab.url) == urlButton.url!) { + if ((+new Date() - +now) / 1000 > 2 * 60) { + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + task.id + ); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; + logger.warn( + `Anomaly activity in browser. Please checkout` + ); continue mainLoop; } else { - const isCaptchaPassed=hero.document.querySelector("input[id='recaptcha-token']"); - if ((isNull(isCaptchaPassed) || (await isCaptchaPassed.$isVisible)==false) ){ - if (await captchaButton.$isClickable){ - try{ - await hero.interact({click:{element: captchaButton, verification: 'exactElement'}}); - } catch (err){ - logger.warn(`Some error due clicking | ${worker.phoneNumber}`); + const isCaptchaPassed = hero.document.querySelector( + "input[id='recaptcha-token']" + ); + if ( + isNull(isCaptchaPassed) || + (await isCaptchaPassed.$isVisible) == false + ) { + if (await captchaButton.$isClickable) { + try { + await hero.interact({ + click: { + element: captchaButton, + verification: "exactElement", + }, + }); + } catch (err) { + logger.warn( + `Some error due clicking | ${worker.phoneNumber}` + ); continue mainLoop; } } await sleep(1000); - captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); + captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); } else { - logger.error(`Captcha detected | ${worker.phoneNumber}`); + logger.error( + `Captcha detected | ${worker.phoneNumber}` + ); throw new Error("Captcha detected"); } } } } - await waitNewMessages(client,worker,botEntity,task.id); - const afterTask:telegram.Api.Message=(await client.getMessages(botEntity,{ - minId:task.id, - limit:100 - })).filter((value)=>{return value.message.includes(settings.botMessages.taskComplete)})[0]; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; - if (afterTask!=null){ // need update - if (afterTask.message.includes(settings.botMessages.taskComplete)==true){ - logger.info(`Site task complete | ${worker.phoneNumber}`); - continue + await waitNewMessages(client, worker, botEntity, task.id); + const afterTask: telegram.Api.Message = ( + await client.getMessages(botEntity, { + minId: task.id, + limit: 100, + }) + ).filter((value) => { + return value.message.includes( + settings.botMessages.taskComplete + ); + })[0]; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; + if (afterTask != null) { + // need update + if ( + afterTask.message.includes( + settings.botMessages.taskComplete + ) == true + ) { + logger.info( + `Site task complete | ${worker.phoneNumber}` + ); + continue; } } } - - } else if (task.message.includes(settings.botMessages.taskOver)==true){ + } else if ( + task.message.includes(settings.botMessages.taskOver) == true + ) { logger.info(`Ad tasks completed | ${worker.phoneNumber}`); - break + break; } else { logger.error(`Check out last message of ${worker.phoneNumber}`); - throw new Error(`Check out last message of ${worker.phoneNumber}`) + throw new Error(`Check out last message of ${worker.phoneNumber}`); } - } -} +}; - -export const doChatsTasks=async function (client: telegram.TelegramClient,worker: AccountInterface,hero: Hero,botEntity: telegram.Api.Chat | telegram.Api.User,tasksSelector: telegram.Api.Message){ - const taskChatsButton=tasksSelector.buttons![1][1]; - let prevTask: prevTaskInterface={ - task:tasksSelector, - lastMessage:tasksSelector +export const doChatsTasks = async function ( + client: telegram.TelegramClient, + worker: AccountInterface, + hero: Hero, + botEntity: telegram.Api.Chat | telegram.Api.User, + tasksSelector: telegram.Api.Message +) { + const taskChatsButton = tasksSelector.buttons![1][1]; + const prevTask: prevTaskInterface = { + task: tasksSelector, + lastMessage: tasksSelector, }; - mainLoop: - while (true){ + mainLoop: while (true) { await sleep(2000); - await taskChatsButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const task=(await client.getMessages(botEntity,{ - minId:prevTask.lastMessage.id, - // search: (await settings.botMessages()).tasksSelector, - }))[0]; - if (task.buttonCount==3){ - + await taskChatsButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const task = ( + await client.getMessages(botEntity, { + minId: prevTask.lastMessage.id, + // search: (await settings.botMessages()).tasksSelector, + }) + )[0]; + if (task.buttonCount == 3) { logger.info(`New chat task | ${worker.phoneNumber}`); - - const urlButton=task.buttons![0][0]; - const confirmButton=task.buttons![0][1]; - const skipButton=task.buttons![0][2]; + const urlButton = task.buttons![0][0]; + const confirmButton = task.buttons![0][1]; + const skipButton = task.buttons![0][2]; - let groupLink=''; - if (urlButton.url?.includes('hkbot')==true){ - await hero.goto(urlButton.url,{timeoutMs:2_000_000}); - await hero.waitForLoad('AllContentLoaded',{timeoutMs:1180_000}); - let captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); - if (isNull(captchaButton)){ - if (prevTask.task.message==task.message){ - logger.warn(`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`); - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; + let groupLink = ""; + if (urlButton.url?.includes("hkbot") == true) { + await hero.goto(urlButton.url, { timeoutMs: 2_000_000 }); + await hero.waitForLoad("AllContentLoaded", { + timeoutMs: 1180_000, + }); + let captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); + if (isNull(captchaButton)) { + if (prevTask.task.message == task.message) { + logger.warn( + `Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......` + ); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + task.id + ); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; } else { - prevTask.task=task; - prevTask.lastMessage=task; - logger.warn(`Captcha isnt detected... | ${worker.phoneNumber}`); + prevTask.task = task; + prevTask.lastMessage = task; + logger.warn( + `Captcha isnt detected... | ${worker.phoneNumber}` + ); } continue mainLoop; } - const now=new Date() - while (captchaButton!=null && await hero.activeTab.url==urlButton.url!){ - if ((+(new Date())-+now)/1000>2*60){ - if ( (await captchaButton.$isClickable)==false){ - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; + const now = new Date(); + while ( + captchaButton != null && + (await hero.activeTab.url) == urlButton.url! + ) { + if ((+new Date() - +now) / 1000 > 2 * 60) { + if ((await captchaButton.$isClickable) == false) { + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + task.id + ); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; continue mainLoop; - } - - logger.warn(`Anomaly activity in browser. Please checkout`); - await hero.reload(); + + logger.warn( + `Anomaly activity in browser. Please checkout` + ); + await hero.reload(); } - const isCaptchaPassed=hero.document.querySelector("input[id='recaptcha-token']"); - if ((isCaptchaPassed==null || await isCaptchaPassed.$isVisible==false) ){ - if (await captchaButton.$isClickable){ + const isCaptchaPassed = hero.document.querySelector( + "input[id='recaptcha-token']" + ); + if ( + isCaptchaPassed == null || + (await isCaptchaPassed.$isVisible) == false + ) { + if (await captchaButton.$isClickable) { try { - await hero.interact({click:{element: captchaButton, verification: 'exactElement'}}); - } catch( err){ - - logger.warn(`Some error due clicking | ${worker.phoneNumber}`); + await hero.interact({ + click: { + element: captchaButton, + verification: "exactElement", + }, + }); + } catch (err) { + logger.warn( + `Some error due clicking | ${worker.phoneNumber}` + ); continue mainLoop; } } await sleep(1000); - captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); - + captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); } else { logger.error("Captcha detected"); throw new CaptchaError("Auhtung captcha detected"); } } - groupLink=await hero.url; - + groupLink = await hero.url; } else { - groupLink=urlButton.url!; + groupLink = urlButton.url!; } // https://gram.js.org/tl/messages/GetFullChat // hash checking - let group:telegram.Api.Channel | undefined; - if (!/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)([\w-]+)/i.test(groupLink)){ - groupLink=groupLink.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i,''); + let group: telegram.Api.Channel | undefined; + if ( + !/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)([\w-]+)/i.test( + groupLink + ) + ) { + groupLink = groupLink.replace( + /(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i, + "" + ); try { - group=(((await client.invoke( - new telegram.Api.channels.JoinChannel({ - channel:groupLink - }) - )) as telegram.Api.Updates).chats[0] as telegram.Api.Channel) - } catch (err: unknown){ - if (err instanceof telegram.errors.RPCError){ + group = ( + (await client.invoke( + new telegram.Api.channels.JoinChannel({ + channel: groupLink, + }) + )) as telegram.Api.Updates + ).chats[0] as telegram.Api.Channel; + } catch (err: unknown) { + if (err instanceof telegram.errors.RPCError) { switch (err.errorMessage) { - case 'CHANNELS_TOO_MUCH': - logger.warn(`Too much groups | ${worker.phoneNumber}`); + case "CHANNELS_TOO_MUCH": + logger.warn( + `Too much groups | ${worker.phoneNumber}` + ); return; - - case 'USER_ALREADY_PARTICIPANT': - logger.warn(`Already in group | ${worker.phoneNumber}`) - group=(await client.invoke( - new telegram.Api.channels.GetChannels({ - id:[groupLink] - }) - ))[0] + + case "USER_ALREADY_PARTICIPANT": + logger.warn( + `Already in group | ${worker.phoneNumber}` + ); + group = ( + await client.invoke( + new telegram.Api.channels.GetChannels({ + id: [groupLink], + }) + ) + )[0]; break; default: - logger.warn(`Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}`) - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; + logger.warn( + `Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}` + ); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + task.id + ); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; continue mainLoop; - } } } } else { - // hash - groupLink=groupLink.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)/i,''); + // hash + groupLink = groupLink.replace( + /(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)/i, + "" + ); try { - group=(((await client.invoke( - new telegram.Api.messages.ImportChatInvite({ - hash:groupLink - }) - )) as telegram.Api.Updates).chats[0] as telegram.Api.Channel) - } catch (err: unknown){ - if (err instanceof telegram.errors.RPCError){ + group = ( + (await client.invoke( + new telegram.Api.messages.ImportChatInvite({ + hash: groupLink, + }) + )) as telegram.Api.Updates + ).chats[0] as telegram.Api.Channel; + } catch (err: unknown) { + if (err instanceof telegram.errors.RPCError) { switch (err.errorMessage) { - case 'CHANNELS_TOO_MUCH': - logger.warn(`Too much groups | ${worker.phoneNumber}`); + case "CHANNELS_TOO_MUCH": + logger.warn( + `Too much groups | ${worker.phoneNumber}` + ); return; - - case 'USER_ALREADY_PARTICIPANT': - logger.warn(`Already in group | ${worker.phoneNumber}`) - group=((await client.invoke( - new telegram.Api.messages.CheckChatInvite({ - hash:groupLink - }) - )) as telegram.Api.ChatInviteAlready).chat as telegram.Api.Channel + + case "USER_ALREADY_PARTICIPANT": + logger.warn( + `Already in group | ${worker.phoneNumber}` + ); + group = ( + (await client.invoke( + new telegram.Api.messages.CheckChatInvite( + { + hash: groupLink, + } + ) + )) as telegram.Api.ChatInviteAlready + ).chat as telegram.Api.Channel; break; default: - logger.warn(`Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}`) - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id - }))[0]; + logger.warn( + `Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}` + ); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + task.id + ); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; continue mainLoop; - } } } } - - await confirmButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - const afterTask=(await client.getMessages(botEntity,{ - minId: task.id, - limit:100 - })).filter((value)=>{ - if (value.message.includes(settings.botMessages.notInGroup) || value.message.includes(settings.botMessages.taskComplete)){ - return true + + await confirmButton.click({ sharePhone: false }); + await waitNewMessages(client, worker, botEntity, task.id); + const afterTask = ( + await client.getMessages(botEntity, { + minId: task.id, + limit: 100, + }) + ).filter((value) => { + if ( + value.message.includes(settings.botMessages.notInGroup) || + value.message.includes(settings.botMessages.taskComplete) + ) { + return true; } else { - return false + return false; } })[0]; - const lastMessage=(await client.getMessages(botEntity,{ - minId: task.id - }))[0]; - prevTask.task=task; - prevTask.lastMessage=(lastMessage!==undefined) ? lastMessage: afterTask ; - if (afterTask.message.includes(settings.botMessages.taskComplete)==true){ - worker.completedGroupsTasks.push( - { - timeToLeave: +(new Date())+Number(afterTask.message.replace(/\D/g,''))*3600*1_000, - groupID:(await client.getPeerId(group!)) - } - ); + const lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + }) + )[0]; + prevTask.task = task; + prevTask.lastMessage = + lastMessage !== undefined ? lastMessage : afterTask; + if ( + afterTask.message.includes(settings.botMessages.taskComplete) == + true + ) { + worker.completedGroupsTasks.push({ + timeToLeave: + +new Date() + + Number(afterTask.message.replace(/\D/g, "")) * + 3600 * + 1_000, + groupID: await client.getPeerId(group!), + }); logger.info(`Chat task complete | ${worker.phoneNumber}`); continue; - } else if (afterTask.message.includes(settings.botMessages.notInGroup)==true){ - logger.warn(`User joined but hk says not. Skipping...`) - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,task.id); - prevTask.task=task; - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:task.id, - // search: (await settings.botMessages()).tasksSelector, - }))[0]; - worker.completedGroupsTasks.push( - { - timeToLeave: 1, - groupID:(await client.getPeerId(group!)) - } - ); + } else if ( + afterTask.message.includes(settings.botMessages.notInGroup) == + true + ) { + logger.warn(`User joined but hk says not. Skipping...`); + await skipButton.click({ sharePhone: false }); + await waitNewMessages(client, worker, botEntity, task.id); + prevTask.task = task; + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: task.id, + // search: (await settings.botMessages()).tasksSelector, + }) + )[0]; + worker.completedGroupsTasks.push({ + timeToLeave: 1, + groupID: await client.getPeerId(group!), + }); } else { logger.debug(`Anomaly | ${worker.phoneNumber}`); logger.debug(task.message); } - }else if (task.message.includes(settings.botMessages.taskOver)==true){ - logger.info(`Chats tasks completed | ${worker.phoneNumber}`) - break + } else if ( + task.message.includes(settings.botMessages.taskOver) == true + ) { + logger.info(`Chats tasks completed | ${worker.phoneNumber}`); + break; } else { logger.error(`Check out last message of ${worker.phoneNumber}`); - throw new Error(`Check out last message of ${worker.phoneNumber}`) + throw new Error(`Check out last message of ${worker.phoneNumber}`); } } -} +}; -export const doBotTasks=async function(client: telegram.TelegramClient,worker: AccountInterface,hero: Hero,botEntity: telegram.Api.Chat | telegram.Api.User,tasksSelector: telegram.Api.Message) { - const taskBotsButton=tasksSelector.buttons![1][2]; - let prevTask: prevTaskInterface={ - task:tasksSelector, - lastMessage:tasksSelector - }; - mainLoop: - while (true){ - await sleep(2000); - await taskBotsButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - let task: telegram.Api.Message; - [(prevTask.lastMessage),task]=(await client.getMessages(botEntity,{ - minId:prevTask.lastMessage.id, - limit:2 - })); - if (task===undefined){ - task=prevTask.lastMessage - } - if (task.buttonCount==3){ - logger.info(`New bot task | ${worker.phoneNumber}`); - - const urlButton=task.buttons![0][0]; - const skipButton=task.buttons![0][1]; - let botLink='@'; - if (urlButton.url?.includes('hkbot')==true){ - await hero.goto(urlButton.url,{timeoutMs:2_000_000}); - await hero.waitForLoad('AllContentLoaded',{timeoutMs:1180_000}); - let captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); - if (isNull(captchaButton)){ - if (prevTask.task.message==task.message){ - logger.warn(`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`); - await skipButton.click({sharePhone: false}); - } else { - logger.warn(`Captcha isnt detected... | ${worker.phoneNumber}`); - } - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:cancelMessage.id - }))[0]; - prevTask.task=task; - continue mainLoop; - } - const now=new Date() - while (captchaButton!=null && await hero.activeTab.url==urlButton.url!){ - if ((+(new Date())-+now)/1000>2*60){ - if ( (await captchaButton.$isClickable)==false){ - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:cancelMessage.id - }))[0]; - prevTask.task=task; - continue mainLoop; - } - logger.warn(`Anomaly activity in browser. Please checkout`); - await hero.reload(); - } - const isCaptchaPassed=hero.document.querySelector("input[id='recaptcha-token']"); - if ((isCaptchaPassed==null || await isCaptchaPassed.$isVisible==false) ){ - if (await captchaButton.$isClickable){ - try { - await hero.interact({click:{element: captchaButton, verification: 'exactElement'}}); - } catch( err){ - - logger.warn(`Some error due clicking | ${worker.phoneNumber}`); - continue mainLoop; - } - } - await sleep(1000); - captchaButton=hero.document.querySelector('button.g-recaptcha.btn.btn-primary'); - - } else { - logger.error("Captcha detected"); - throw new CaptchaError("Auhtung captcha detected"); - } - } - botLink+=(await hero.url).replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i,'')!.replace(/(?:\?start=)[A-Za-z0-9]+/i,'')! - } else { - botLink+=urlButton.url?.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i,'')!.replace(/(?:\?start=)[A-Za-z0-9]+/i,'')! - } - await client.invoke( - new telegram.Api.contacts.Unblock({ - id: botLink - })); - try{ - await waitNewMessages(client,worker,botLink,(await client.sendMessage(botLink,{message:'/start'})).id); - } catch( err){ - if (err instanceof NoNewMessagesError){ - logger.warn(`Target bot doesnt work | ${worker.phoneNumber}`); - logger.debug(err.message); - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:cancelMessage.id - }))[0]; - prevTask.task=task; - continue mainLoop; +export const doBotTasks = async function ( + client: telegram.TelegramClient, + worker: AccountInterface, + hero: Hero, + botEntity: telegram.Api.Chat | telegram.Api.User, + tasksSelector: telegram.Api.Message +) { + const taskBotsButton = tasksSelector.buttons![1][2]; + const prevTask: prevTaskInterface = { + task: tasksSelector, + lastMessage: tasksSelector, + }; + mainLoop: while (true) { + await sleep(2000); + await taskBotsButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + let task: telegram.Api.Message; + [prevTask.lastMessage, task] = await client.getMessages(botEntity, { + minId: prevTask.lastMessage.id, + limit: 2, + }); + if (task === undefined) { + task = prevTask.lastMessage; + } + if (task.buttonCount == 3) { + logger.info(`New bot task | ${worker.phoneNumber}`); + + const urlButton = task.buttons![0][0]; + const skipButton = task.buttons![0][1]; + let botLink = "@"; + if (urlButton.url?.includes("hkbot") == true) { + await hero.goto(urlButton.url, { timeoutMs: 2_000_000 }); + await hero.waitForLoad("AllContentLoaded", { + timeoutMs: 1180_000, + }); + let captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); + if (isNull(captchaButton)) { + if (prevTask.task.message == task.message) { + logger.warn( + `Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......` + ); + await skipButton.click({ sharePhone: false }); } else { - throw err + logger.warn( + `Captcha isnt detected... | ${worker.phoneNumber}` + ); } - } - let forwardMessage: telegram.Api.Message; - try{ - forwardMessage=(await (await getMessagesByEntity(client,botLink,botLink,{ - limit:1000 - }))[0].forwardTo(botEntity))![0]; - } catch (err){ - if (err instanceof telegram.errors.RPCError){ - - client.invoke(new telegram.Api.messages.DeleteHistory({ - justClear:true, - peer:botLink - })); - client.invoke( - new telegram.Api.contacts.Block({ - id: botLink, - })); - - logger.warn(`Error when forwarding a message. Skipping task... | ${worker.phoneNumber}`); - logger.debug(err.message); - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:cancelMessage.id - }))[0]; - prevTask.task=task; - continue mainLoop; - } else { - throw err - } - } - - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const afterTask=(await client.getMessages(botEntity,{ - minId: prevTask.lastMessage.id, - limit:10 - })).filter((value)=>{ - if (value.message.includes(settings.botMessages.taskComplete) || value.message.includes(settings.botMessages.oldMessage)){ - return true - } else { - return false - } - })[0]; - if (afterTask!==undefined){ - if (afterTask.message.includes(settings.botMessages.taskComplete)==true){ - await client.invoke(new telegram.Api.messages.DeleteHistory({ - justClear:true, - peer:botLink - })) - await client.invoke( - new telegram.Api.contacts.Block({ - id: botLink, - }) - ); - logger.info(`Bot task complete | ${worker.phoneNumber}`); - - } else if (afterTask.message.includes(settings.botMessages.oldMessage)){ - logger.warn(`Forwarded message was old | ${worker.phoneNumber}`); - } - } else { - - client.invoke(new telegram.Api.messages.DeleteHistory({ - justClear:true, - peer:botLink - })); - client.invoke( - new telegram.Api.contacts.Block({ - id: botLink, - })); - - logger.warn(`Message that i found is unknown | ${worker.phoneNumber}`); - await skipButton.click({sharePhone: false}); - await waitNewMessages(client,worker,botEntity,prevTask.lastMessage.id); - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - prevTask.lastMessage=(await client.getMessages(botEntity,{ - minId:cancelMessage.id - }))[0]; - prevTask.task=task; + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const cancelMessage = await client.sendMessage(botEntity, { + message: "/cancel", + }); + await waitNewMessages( + client, + worker, + botEntity, + cancelMessage.id + ); + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; continue mainLoop; } - - const cancelMessage=(await client.sendMessage(botEntity,{message:'/cancel'})); - await waitNewMessages(client,worker,botEntity,cancelMessage.id); - const lastMessage=(await client.getMessages(botEntity,{ - minId: cancelMessage.id - }))[0]; - prevTask.task=task; - prevTask.lastMessage=(lastMessage!==undefined) ? lastMessage: afterTask ; - continue; - } else if (task.message.includes(settings.botMessages.taskOver)==true){ - logger.info(`Bots tasks completed | ${worker.phoneNumber}`) - break + const now = new Date(); + while ( + captchaButton != null && + (await hero.activeTab.url) == urlButton.url! + ) { + if ((+new Date() - +now) / 1000 > 2 * 60) { + if ((await captchaButton.$isClickable) == false) { + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const cancelMessage = await client.sendMessage( + botEntity, + { message: "/cancel" } + ); + await waitNewMessages( + client, + worker, + botEntity, + cancelMessage.id + ); + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; + continue mainLoop; + } + logger.warn( + `Anomaly activity in browser. Please checkout` + ); + await hero.reload(); + } + const isCaptchaPassed = hero.document.querySelector( + "input[id='recaptcha-token']" + ); + if ( + isCaptchaPassed == null || + (await isCaptchaPassed.$isVisible) == false + ) { + if (await captchaButton.$isClickable) { + try { + await hero.interact({ + click: { + element: captchaButton, + verification: "exactElement", + }, + }); + } catch (err) { + logger.warn( + `Some error due clicking | ${worker.phoneNumber}` + ); + continue mainLoop; + } + } + await sleep(1000); + captchaButton = hero.document.querySelector( + "button.g-recaptcha.btn.btn-primary" + ); + } else { + logger.error("Captcha detected"); + throw new CaptchaError("Auhtung captcha detected"); + } + } + botLink += (await hero.url) + .replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i, "")! + .replace(/(?:\?start=)[A-Za-z0-9]+/i, "")!; } else { - logger.error(`Check out last message of ${worker.phoneNumber}`); - throw new Error(`Check out last message of ${worker.phoneNumber}`) + botLink += urlButton.url + ?.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i, "")! + .replace(/(?:\?start=)[A-Za-z0-9]+/i, "")!; } + await client.invoke( + new telegram.Api.contacts.Unblock({ + id: botLink, + }) + ); + try { + await waitNewMessages( + client, + worker, + botLink, + ( + await client.sendMessage(botLink, { message: "/start" }) + ).id + ); + } catch (err) { + if (err instanceof NoNewMessagesError) { + logger.warn( + `Target bot doesnt work | ${worker.phoneNumber}` + ); + logger.debug(err.message); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const cancelMessage = await client.sendMessage(botEntity, { + message: "/cancel", + }); + await waitNewMessages( + client, + worker, + botEntity, + cancelMessage.id + ); + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; + continue mainLoop; + } else { + throw err; + } + } + let forwardMessage: telegram.Api.Message; + try { + forwardMessage = (await ( + await getMessagesByEntity(client, botLink, botLink, { + limit: 1000, + }) + )[0].forwardTo(botEntity))![0]; + } catch (err) { + if (err instanceof telegram.errors.RPCError) { + client.invoke( + new telegram.Api.messages.DeleteHistory({ + justClear: true, + peer: botLink, + }) + ); + client.invoke( + new telegram.Api.contacts.Block({ + id: botLink, + }) + ); + + logger.warn( + `Error when forwarding a message. Skipping task... | ${worker.phoneNumber}` + ); + logger.debug(err.message); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const cancelMessage = await client.sendMessage(botEntity, { + message: "/cancel", + }); + await waitNewMessages( + client, + worker, + botEntity, + cancelMessage.id + ); + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; + continue mainLoop; + } else { + throw err; + } + } + + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const afterTask = ( + await client.getMessages(botEntity, { + minId: prevTask.lastMessage.id, + limit: 10, + }) + ).filter((value) => { + if ( + value.message.includes(settings.botMessages.taskComplete) || + value.message.includes(settings.botMessages.oldMessage) + ) { + return true; + } else { + return false; + } + })[0]; + if (afterTask !== undefined) { + if ( + afterTask.message.includes( + settings.botMessages.taskComplete + ) == true + ) { + await client.invoke( + new telegram.Api.messages.DeleteHistory({ + justClear: true, + peer: botLink, + }) + ); + await client.invoke( + new telegram.Api.contacts.Block({ + id: botLink, + }) + ); + logger.info(`Bot task complete | ${worker.phoneNumber}`); + } else if ( + afterTask.message.includes(settings.botMessages.oldMessage) + ) { + logger.warn( + `Forwarded message was old | ${worker.phoneNumber}` + ); + } + } else { + client.invoke( + new telegram.Api.messages.DeleteHistory({ + justClear: true, + peer: botLink, + }) + ); + client.invoke( + new telegram.Api.contacts.Block({ + id: botLink, + }) + ); + + logger.warn( + `Message that i found is unknown | ${worker.phoneNumber}` + ); + await skipButton.click({ sharePhone: false }); + await waitNewMessages( + client, + worker, + botEntity, + prevTask.lastMessage.id + ); + const cancelMessage = await client.sendMessage(botEntity, { + message: "/cancel", + }); + await waitNewMessages( + client, + worker, + botEntity, + cancelMessage.id + ); + prevTask.lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; + continue mainLoop; + } + + const cancelMessage = await client.sendMessage(botEntity, { + message: "/cancel", + }); + await waitNewMessages(client, worker, botEntity, cancelMessage.id); + const lastMessage = ( + await client.getMessages(botEntity, { + minId: cancelMessage.id, + }) + )[0]; + prevTask.task = task; + prevTask.lastMessage = + lastMessage !== undefined ? lastMessage : afterTask; + continue; + } else if ( + task.message.includes(settings.botMessages.taskOver) == true + ) { + logger.info(`Bots tasks completed | ${worker.phoneNumber}`); + break; + } else { + logger.error(`Check out last message of ${worker.phoneNumber}`); + throw new Error(`Check out last message of ${worker.phoneNumber}`); } - -} \ No newline at end of file + } +}; diff --git a/database.ts b/database.ts index 9f3eee9..a4f582c 100644 --- a/database.ts +++ b/database.ts @@ -1,237 +1,272 @@ -import {JsonDB,Config} from "node-json-db" -import {FingerprintGenerator} from "fingerprint-generator" -import logger from "./logger" -import * as interfacesDB from "./interfaces/databaseInterface" -import * as interfacesSettings from "./interfaces/settingsInterface" -import { arrayWithoutElementAtIndex } from "./utils" +import { JsonDB, Config } from "node-json-db"; +import { FingerprintGenerator } from "fingerprint-generator"; +import logger from "./logger"; +import * as interfacesDB from "./interfaces/databaseInterface"; +import * as interfacesSettings from "./interfaces/settingsInterface"; +import { arrayWithoutElementAtIndex } from "./utils"; export class Database { - public readonly default: interfacesDB.DatabaseInterface={ - accounts:[] - } + public readonly default: interfacesDB.DatabaseInterface = { + accounts: [], + }; private json: JsonDB; - constructor (){ - this.json=new JsonDB(new Config('db.json',false,true,'/')); - this.json.getData('/').then((result)=>{ - if (Object.keys(result).length==0){ - this.json.push('/',this.default,true) - .catch((err) => logger.error(`${err} due setting defaults`)) - .then(() => { - logger.info('Setting DB to defaults...'); - }); + constructor() { + this.json = new JsonDB(new Config("db.json", false, true, "/")); + this.json.getData("/").then((result) => { + if (Object.keys(result).length == 0) { + this.json + .push("/", this.default, true) + .catch((err) => logger.error(`${err} due setting defaults`)) + .then(() => { + logger.info("Setting DB to defaults..."); + }); this.save(); } - }) + }); } - async findWallet(walletsFile: string): Promise{ - const wallets_json=new JsonDB(new Config(walletsFile,true,true,'/')); - const wallets=(await wallets_json.getData('/')); - if (Object.keys(wallets).length==0){ - logger.error('File which you choose doesnt have anything'); - throw new Error('File which you choose doesnt have anything') - } - const accounts=(await this.getUsers()); - let faucetWallet:interfacesDB.faucetMailInterface | undefined=undefined; - for (const _wallet in wallets){ - let flag=false; - if (accounts.length>0){ - for (const account of accounts){ - if (account.faucetMail.mail.address==_wallet ){ - flag=true; + async findWallet( + walletsFile: string + ): Promise { + const wallets_json = new JsonDB( + new Config(walletsFile, true, true, "/") + ); + const wallets = await wallets_json.getData("/"); + if (Object.keys(wallets).length == 0) { + logger.error("File which you choose doesnt have anything"); + throw new Error("File which you choose doesnt have anything"); + } + const accounts = await this.getUsers(); + let faucetWallet: interfacesDB.faucetMailInterface | undefined = + undefined; + for (const _wallet in wallets) { + let flag = false; + if (accounts.length > 0) { + for (const account of accounts) { + if (account.faucetMail.mail.address == _wallet) { + flag = true; break; } } } - if (flag==false){ - faucetWallet={ + if (flag == false) { + faucetWallet = { faucet: { - username:wallets[_wallet].faucetpay.username, - password:wallets[_wallet].faucetpay.password + username: wallets[_wallet].faucetpay.username, + password: wallets[_wallet].faucetpay.password, }, mail: { - address:_wallet, - password:wallets[_wallet].mail_passphrase - } - } + address: _wallet, + password: wallets[_wallet].mail_passphrase, + }, + }; break; } - } return faucetWallet; - } - async findRefferal(maxRefferals: number): Promise{ - let refferal: number | null=null; - const accounts=(await this.getUsers()); - if (accounts.length>0){ - for (const mainAccount of accounts){ - - - let counter=0; - if (mainAccount.canBeRefferal==true){ - let _accounts=arrayWithoutElementAtIndex(accounts,accounts.indexOf(mainAccount)); - for (const _account of _accounts){ - - if (_account.refferal==mainAccount.telegramID){ - counter+=1; + async findRefferal(maxRefferals: number): Promise { + let refferal: number | null = null; + const accounts = await this.getUsers(); + if (accounts.length > 0) { + for (const mainAccount of accounts) { + let counter = 0; + if (mainAccount.canBeRefferal == true) { + const _accounts = arrayWithoutElementAtIndex( + accounts, + accounts.indexOf(mainAccount) + ); + for (const _account of _accounts) { + if (_account.refferal == mainAccount.telegramID) { + counter += 1; } } - - if (counter,wallets_json: string): Promise{ + async addUser( + account: Omit< + interfacesDB.AccountInterface, + | "balance" + | "withdraws" + | "completedGroupsTasks" + | "canBeRefferal" + | "browserFingerprint" + | "faucetMail" + >, + wallets_json: string + ): Promise { const fingerprintGenerator = new FingerprintGenerator(); - const fingerprint=fingerprintGenerator.getFingerprint({ - devices: ['desktop'], - browsers: ['chrome'], - + const fingerprint = fingerprintGenerator.getFingerprint({ + devices: ["desktop"], + browsers: ["chrome"], }).fingerprint; - const faucet:interfacesDB.faucetMailInterface | undefined=await this.findWallet(wallets_json); - if (faucet === undefined){ - logger.error('Add new faucet accounts'); - throw new Error('Add new faucet accounts'); - }else { - const canBeRefferal: boolean=Math.random() < 0.5; - - const _account: interfacesDB.AccountInterface={ - phoneNumber:account.phoneNumber, - telegramID:account.telegramID, - apiID:account.apiID, - apiHash:account.apiHash, - password:account.password, - faucetMail:faucet, - stringSession:account.stringSession, - balance:0.0, - withdraws:[], - completedGroupsTasks:[], - canBeRefferal:canBeRefferal, - refferal:account.refferal, - browserFingerprint:fingerprint - } - await this.json.push(`/accounts[]`,_account); + const faucet: interfacesDB.faucetMailInterface | undefined = + await this.findWallet(wallets_json); + if (faucet === undefined) { + logger.error("Add new faucet accounts"); + throw new Error("Add new faucet accounts"); + } else { + const canBeRefferal: boolean = Math.random() < 0.5; + + const _account: interfacesDB.AccountInterface = { + phoneNumber: account.phoneNumber, + telegramID: account.telegramID, + apiID: account.apiID, + apiHash: account.apiHash, + password: account.password, + faucetMail: faucet, + stringSession: account.stringSession, + balance: 0.0, + withdraws: [], + completedGroupsTasks: [], + canBeRefferal: canBeRefferal, + refferal: account.refferal, + browserFingerprint: fingerprint, + }; + await this.json.push(`/accounts[]`, _account); } await this.save(); - } - async getUsers(): Promise{ - + async getUsers(): Promise { try { - return await this.json.getObject('/accounts'); + return await this.json.getObject( + "/accounts" + ); } catch { return []; } - - } - - - + } } - export class Settings implements interfacesSettings.settingsInterface { - public readonly default: interfacesSettings.settingsInterface={ - logLevel: 'debug', + public readonly default: interfacesSettings.settingsInterface = { + logLevel: "debug", pararels: 2, - mainCrypto: 'TRX', + mainCrypto: "TRX", minimalToWithdraw: 0.0003, maxRefferals: 3, botMessages: { - verification: 'To continue using this bot,', - tasksSelector: 'Choose an option to start earning your TRX', - taskOver: 'Sorry, there are no new ads available.', - taskComplete: 'Success, ', - notInGroup: 'not entered the chat', - oldMessage: 'forwarded is old' + verification: "To continue using this bot,", + tasksSelector: "Choose an option to start earning your TRX", + taskOver: "Sorry, there are no new ads available.", + taskComplete: "Success, ", + notInGroup: "not entered the chat", + oldMessage: "forwarded is old", }, botButtons: { - earn: '❇️ Earn cryptocurrency', - balance: '💰 Balance', - withdraw: '📤 Withdraw' + earn: "❇️ Earn cryptocurrency", + balance: "💰 Balance", + withdraw: "📤 Withdraw", }, telegramLinks: { - botLink: '@hkearn_trx_bot', - groupsToJoin: ['@hkearn_transactions', '@hkearn_updates'] + botLink: "@hkearn_trx_bot", + groupsToJoin: ["@hkearn_transactions", "@hkearn_updates"], }, bypassMode: false, sleepTime: { - afterDoing: [1*3600,2*3600], - betweenSessions: [35,70], + afterDoing: [1 * 3600, 2 * 3600], + betweenSessions: [35, 70], }, - shuffleAccounts: true - } + shuffleAccounts: true, + }; logLevel: "debug" | "info" | "error"; mainCrypto: "TRX"; minimalToWithdraw: number; maxRefferals: number; - botMessages: { verification: string; tasksSelector: string; taskOver: string, taskComplete: string, notInGroup: string, oldMessage: string}; - botButtons: { earn: string; balance: string; withdraw: string; }; - telegramLinks: { botLink: string; groupsToJoin: string[]; }; - bypassMode: boolean - pararels: number + botMessages: { + verification: string; + tasksSelector: string; + taskOver: string; + taskComplete: string; + notInGroup: string; + oldMessage: string; + }; + botButtons: { earn: string; balance: string; withdraw: string }; + telegramLinks: { botLink: string; groupsToJoin: string[] }; + bypassMode: boolean; + pararels: number; sleepTime: { - afterDoing: number[], - betweenSessions: number[], - } - shuffleAccounts: boolean + afterDoing: number[]; + betweenSessions: number[]; + }; + shuffleAccounts: boolean; private json: JsonDB; - constructor (){ - this.json=new JsonDB(new Config('settings.json',false,true,'/')); - this.json.getObject('/').then((result) => { - if (Object.keys(result).length==0){ - logger.warn('Setup config first...'); - - this.json.push('/',this.default,true) - .catch((err)=> logger.error(`${err} due setting defaults`)) - .then(()=>{ - this.json.save(true).then(()=>{ - throw new Error("Config doesn't setup"); - }) - }); - } else { - mainLoop: - for (const setting of Object.keys(this.default)){ - if (result[setting]===undefined || typeof(result[setting])!=typeof(this.default[setting])){ - this[setting]=this.default[setting]; - logger.warn(`Setting '${setting}' corrupted or undefined. Check out it...`) - } else { - if (typeof(result[setting])=='object'){ - for (const attr of Object.keys(this.default[setting])){ - if (Object.keys(result[setting]).indexOf(attr)==-1){ - this[setting] = this.default[setting]; - logger.warn(`Setting '${setting}' corrupted. Check out it...`) - continue mainLoop; + constructor() { + this.json = new JsonDB(new Config("settings.json", false, true, "/")); + this.json + .getObject("/") + .then((result) => { + if (Object.keys(result).length == 0) { + logger.warn("Setup config first..."); + + this.json + .push("/", this.default, true) + .catch((err) => + logger.error(`${err} due setting defaults`) + ) + .then(() => { + this.json.save(true).then(() => { + throw new Error("Config doesn't setup"); + }); + }); + } else { + mainLoop: for (const setting of Object.keys(this.default)) { + if ( + result[setting] === undefined || + typeof result[setting] != + typeof this.default[setting] + ) { + this[setting] = this.default[setting]; + logger.warn( + `Setting '${setting}' corrupted or undefined. Check out it...` + ); + } else { + if (typeof result[setting] == "object") { + for (const attr of Object.keys( + this.default[setting] + )) { + if ( + Object.keys(result[setting]).indexOf( + attr + ) == -1 + ) { + this[setting] = this.default[setting]; + logger.warn( + `Setting '${setting}' corrupted. Check out it...` + ); + continue mainLoop; + } } } + this[setting] = result[setting]; } - this[setting]=result[setting]; } + logger.level = this.logLevel; } - logger.level=this.logLevel; - } - }); - } - + }); + } } -const database=new Database(); -const settings=new Settings(); -export {database,settings} \ No newline at end of file +const database = new Database(); +const settings = new Settings(); +export { database, settings }; diff --git a/index.ts b/index.ts index 69f33e3..dd7957a 100644 --- a/index.ts +++ b/index.ts @@ -1,173 +1,206 @@ -import fs = require('fs'); -import { database as db, settings } from './database' -import prompt from 'prompts'; -import logger from "./logger" -import * as telegram from 'telegram'; -import { LogLevel } from 'telegram/extensions/Logger'; -import { AccountInterface } from './interfaces/databaseInterface'; -import { sleep } from 'telegram/Helpers'; -import findFreePorts from 'find-free-ports'; -import { waitNewMessages, startNewTorDocker, getIP, getMessagesByEntity, isBannedByClient, randomAB } from './utils'; -import TorControl from "tor-control"; -import Miner from '@ulixee/miner'; -import Hero from '@ulixee/hero'; -import { portsInterface, usedIPInterface } from "./interfaces/otherInterfaces" -import { doSitesTasks, vertification, doChatsTasks, doBotTasks } from './automatization'; -import ExecuteJsPlugin from '@ulixee/execute-js-plugin'; -import _ from 'lodash'; -import Docker from 'dockerode'; -import cliProgress from "cli-progress" +import fs = require("fs"); +import { database as db, settings } from "./database"; +import prompt from "prompts"; +import logger from "./logger"; +import * as telegram from "telegram"; +import { LogLevel } from "telegram/extensions/Logger"; +import { AccountInterface } from "./interfaces/databaseInterface"; +import { sleep } from "telegram/Helpers"; +import findFreePorts from "find-free-ports"; +import { + waitNewMessages, + startNewTorDocker, + getIP, + getMessagesByEntity, + isBannedByClient, + randomAB, +} from "./utils"; +import TorControl from "tor-control"; +import Miner from "@ulixee/miner"; +import Hero from "@ulixee/hero"; +import { portsInterface, usedIPInterface } from "./interfaces/otherInterfaces"; +import { + doSitesTasks, + vertification, + doChatsTasks, + doBotTasks, +} from "./automatization"; +import ExecuteJsPlugin from "@ulixee/execute-js-plugin"; +import _ from "lodash"; +import Docker from "dockerode"; +import cliProgress from "cli-progress"; import BigInteger from "big-integer"; const addAccounts: () => Promise = async () => { - let apiId: number = 0 - let apiHash: string = ''; + let apiId = 0; + let apiHash = ""; let accounts = await db.getUsers(); if (accounts.length != 0) { const usePrevData = await prompt({ - type: 'confirm', - name: 'confirmed', - message: 'Use apiId and apiHash from last added account?' + type: "confirm", + name: "confirmed", + message: "Use apiId and apiHash from last added account?", }); if (usePrevData.confirmed == true) { apiId = accounts[accounts.length - 1].apiID; apiHash = accounts[accounts.length - 1].apiHash; } } - if (apiId == 0 && apiHash == '') { + if (apiId == 0 && apiHash == "") { const api = await prompt([ { - type: 'number', - name: 'apiId', - message: 'ApiId?' + type: "number", + name: "apiId", + message: "ApiId?", }, { - type: 'text', - name: 'apiHash', - message: 'ApiHash?' - } + type: "text", + name: "apiHash", + message: "ApiHash?", + }, ]); apiId = Number(api.apiId); apiHash = api.apiHash; } - let jsonFiles: prompt.Choice[] = []; + const jsonFiles: prompt.Choice[] = []; fs.readdirSync("./").forEach((file) => { - if (file.search('.json') != -1 && file != 'db.json' && file != 'settings.json') { - jsonFiles.push( - { - title: file, - description: 'json file', - value: file, - } - ); + if ( + file.search(".json") != -1 && + file != "db.json" && + file != "settings.json" + ) { + jsonFiles.push({ + title: file, + description: "json file", + value: file, + }); } }); - const walletsFile = (await prompt({ - type: 'select', - name: 'file', - message: 'Choose wallets json file', - choices: jsonFiles - })).file + const walletsFile = ( + await prompt({ + type: "select", + name: "file", + message: "Choose wallets json file", + choices: jsonFiles, + }) + ).file; await db.findWallet(walletsFile); - - - mainLoop: - while (true) { + mainLoop: while (true) { accounts = await db.getUsers(); const answers = await prompt([ { - type: 'text', - name: 'number', - message: 'Phone number?' + type: "text", + name: "number", + message: "Phone number?", }, { - type: 'text', - name: 'password', - message: '2FA Password?' - } + type: "text", + name: "password", + message: "2FA Password?", + }, ]); for (const account of accounts) { if (account.phoneNumber == answers.number) { - logger.warn('You already added this number'); + logger.warn("You already added this number"); continue mainLoop; } } - const session = new telegram.sessions.StringSession(''); - const client = new telegram.TelegramClient(session, apiId, apiHash, { deviceModel: 'Samsung SM-G980', connectionRetries: 5, systemVersion: '10' }); + const session = new telegram.sessions.StringSession(""); + const client = new telegram.TelegramClient(session, apiId, apiHash, { + deviceModel: "Samsung SM-G980", + connectionRetries: 5, + systemVersion: "10", + }); client.setLogLevel(LogLevel.ERROR); await client.start({ phoneNumber: async () => answers.number.replace(/ /g, ""), password: async () => answers.password.replace(/ /g, ""), - phoneCode: async () => (await prompt({ - type: 'number', - name: 'code', - message: 'Enter recieved code' - })).code.toString(), + phoneCode: async () => + ( + await prompt({ + type: "number", + name: "code", + message: "Enter recieved code", + }) + ).code.toString(), onError: (err) => { - logger.error(`Error due singning into telegram account\n${err}`); - throw err + logger.error( + `Error due singning into telegram account\n${err}` + ); + throw err; }, }); if ((await client.isUserAuthorized()) == true) { - const account: telegram.Api.User | telegram.Api.InputPeerUser = (await client.getMe(false)); + const account: telegram.Api.User | telegram.Api.InputPeerUser = + await client.getMe(false); if (account instanceof telegram.Api.User) { - await db.addUser({ - password: answers.password, - phoneNumber: answers.number, - apiHash: apiHash, - telegramID: Number(account.id), - apiID: apiId, - stringSession: String(client.session.save()), - refferal: await db.findRefferal(settings.maxRefferals) - }, walletsFile) + await db.addUser( + { + password: answers.password, + phoneNumber: answers.number, + apiHash: apiHash, + telegramID: Number(account.id), + apiID: apiId, + stringSession: String(client.session.save()), + refferal: await db.findRefferal(settings.maxRefferals), + }, + walletsFile + ); } else { logger.error("Wrong type of account?"); } - } else { - logger.error('Client not authorized'); + logger.error("Client not authorized"); } - if ((await prompt({ - type: 'confirm', - name: 'continue', - message: 'continue?' - })).continue != true) { + if ( + ( + await prompt({ + type: "confirm", + name: "continue", + message: "continue?", + }) + ).continue != true + ) { return; } } - -} +}; const farm: () => Promise = async () => { - let usedIPs: usedIPInterface[] = []; - const proccesGroup = async (workersGroups: AccountInterface[], ports: portsInterface) => { - - - workersLoop: - for (const worker of workersGroups) { - logger.info(`Current worker:${worker.phoneNumber}\nBalance:${worker.balance}`); + const usedIPs: usedIPInterface[] = []; + const proccesGroup = async ( + workersGroups: AccountInterface[], + ports: portsInterface + ) => { + workersLoop: for (const worker of workersGroups) { + logger.info( + `Current worker:${worker.phoneNumber}\nBalance:${worker.balance}` + ); { - let tor: any - try{ - tor=new TorControl({ - host:'127.0.0.1', + let tor: any; + try { + tor = new TorControl({ + host: "127.0.0.1", port: ports.control, - password: 'qwerty', // Your password for tor-control - persistent: false // Keep connection (persistent) + password: "qwerty", // Your password for tor-control + persistent: false, // Keep connection (persistent) }); - } catch( err){ - logger.error(`Cant connect to tor control via ${ports.control}\n${err}`) - continue + } catch (err) { + logger.error( + `Cant connect to tor control via ${ports.control}\n${err}` + ); + continue; } - + function isFree(currentIP: string) { for (const usedIP of usedIPs) { - - if (usedIP.usedIps.indexOf(currentIP) != -1 || usedIP.current == currentIP) { + if ( + usedIP.usedIps.indexOf(currentIP) != -1 || + usedIP.current == currentIP + ) { return false; } - } return true; } @@ -175,49 +208,57 @@ const farm: () => Promise = async () => { const currentIP = await getIP(ports.http); if (currentIP != null) { if (isFree(currentIP)) { - usedIPs.filter((value) => { return _.isEqual(worker, value.worker) })[0].current = currentIP; - usedIPs.filter((value) => { return _.isEqual(worker, value.worker) })[0].usedIps.push(currentIP); + usedIPs.filter((value) => { + return _.isEqual(worker, value.worker); + })[0].current = currentIP; + usedIPs + .filter((value) => { + return _.isEqual(worker, value.worker); + })[0] + .usedIps.push(currentIP); break; } else { await tor.signalNewnym(); await sleep(3_000); } - } } - } - const fingerprint = worker.browserFingerprint + const fingerprint = worker.browserFingerprint; let hero: Hero; while (true) { - hero = new Hero({ userProfile: { deviceProfile: { deviceMemory: fingerprint.navigator.deviceMemory, - } + }, }, name: `${worker.telegramID}`, - connectionToCore: { host: `ws://127.0.0.1:${ports.minerPort}` }, + connectionToCore: { + host: `ws://127.0.0.1:${ports.minerPort}`, + }, disableDevtools: true, // to bypass hk site - showChrome:true, // to debug + showChrome: true, // to debug userAgent: fingerprint.navigator.userAgent, viewport: fingerprint.screen, locale: fingerprint.navigator.language, upstreamProxyUrl: `socks5://127.0.0.1:${ports.socks}`, - upstreamProxyIpMask:{ - ipLookupService:'icanhazip.com', - proxyIp:usedIPs.filter((value) => { return _.isEqual(worker, value.worker) })[0].current - } - + upstreamProxyIpMask: { + ipLookupService: "icanhazip.com", + proxyIp: usedIPs.filter((value) => { + return _.isEqual(worker, value.worker); + })[0].current, + }, }); hero.use(ExecuteJsPlugin); try { - await hero.goto('https://www.google.com'); + await hero.goto("https://www.google.com"); } catch (err) { await hero.close(); - logger.warn(`Some error due openning Hero. Trying again...\n${err}`); - continue + logger.warn( + `Some error due openning Hero. Trying again...\n${err}` + ); + continue; } break; } @@ -225,204 +266,346 @@ const farm: () => Promise = async () => { new telegram.sessions.StringSession(worker.stringSession), worker.apiID, worker.apiHash, - { deviceModel: 'Samsung SM-G980', connectionRetries: 5, systemVersion: '10' } + { + deviceModel: "Samsung SM-G980", + connectionRetries: 5, + systemVersion: "10", + } ); client.setLogLevel(LogLevel.NONE); await client.connect(); if ((await client.checkAuthorization()) == false) { - logger.error(`Account ${worker.phoneNumber} is not authorizated`); - continue workersLoop + logger.error( + `Account ${worker.phoneNumber} is not authorizated` + ); + continue workersLoop; } else { - logger.debug(`Successfully connected to account ${worker.phoneNumber}`); + logger.debug( + `Successfully connected to account ${worker.phoneNumber}` + ); // https://gram.js.org/beta/modules/Api.channels.html // https://gram.js.org/beta/classes/Api.messages.DeleteChat.html let botEntity: telegram.Api.User; try { - botEntity = await client.getEntity(settings.telegramLinks.botLink) as telegram.Api.User; + botEntity = (await client.getEntity( + settings.telegramLinks.botLink + )) as telegram.Api.User; } catch (err) { if (err instanceof telegram.errors.FloodWaitError) { switch (err.errorMessage) { - case 'FLOOD': - logger.warn(`Account has flood(${err.seconds} secs timeout) error,skipping`); + case "FLOOD": + logger.warn( + `Account has flood(${err.seconds} secs timeout) error,skipping` + ); break; default: - logger.error(`Unknown error due getEntity ${err}`) + logger.error( + `Unknown error due getEntity ${err}` + ); break; } } else { - logger.error(`Unknown error due getEntity ${err}`) + logger.error(`Unknown error due getEntity ${err}`); } - usedIPs.filter((value) => { return _.isEqual(worker, value.worker) })[0].current = '' - usedIPs.filter((value) => { return _.isEqual(worker, value.worker) })[0].usedIps.pop() - await hero.close() - continue workersLoop + usedIPs.filter((value) => { + return _.isEqual(worker, value.worker); + })[0].current = ""; + usedIPs + .filter((value) => { + return _.isEqual(worker, value.worker); + })[0] + .usedIps.pop(); + await hero.close(); + continue workersLoop; } // leaving old groups { const now = new Date(); - worker.completedGroupsTasks = worker.completedGroupsTasks.filter(async (oldGroup) => { - if (+now > oldGroup.timeToLeave) { - const olderGroups = worker.completedGroupsTasks.filter((value) => { - if (value.groupID == oldGroup.groupID && value.timeToLeave > oldGroup.timeToLeave) { - return true; - } else { - return false; - } - }); - if (olderGroups.length == 0) { - let peerChannel: string | number | BigInteger.BigInteger | telegram.Api.PeerUser | telegram.Api.PeerChat | telegram.Api.PeerChannel | telegram.Api.InputPeerEmpty | telegram.Api.InputPeerSelf | telegram.Api.InputPeerChat | telegram.Api.InputPeerUser | telegram.Api.InputPeerChannel | telegram.Api.InputPeerUserFromMessage | telegram.Api.InputPeerChannelFromMessage | telegram.Api.User | telegram.Api.Chat | telegram.Api.Channel | telegram.Api.UserEmpty | telegram.Api.ChatEmpty | telegram.Api.ChatForbidden | telegram.Api.ChannelForbidden | telegram.Api.UserFull | telegram.Api.messages.ChatFull | telegram.Api.ChatFull | telegram.Api.ChannelFull | telegram.Api.InputChannelEmpty | telegram.Api.InputChannel | telegram.Api.InputChannelFromMessage | telegram.Api.InputUserEmpty | telegram.Api.InputUserSelf | telegram.Api.InputUser | telegram.Api.InputUserFromMessage; - try{ - peerChannel = await client.getInputEntity(BigInteger(oldGroup.groupID)); - } - catch (err){ - return false - } - try { - await client.invoke(new telegram.Api.channels.GetParticipant({ channel: peerChannel, participant: 'me' })); - } catch (err) { - if (err.code == 400) { - return false - } else { - logger.error(`Unknown error due GetParticipant | ${worker.phoneNumber}`) - return true + worker.completedGroupsTasks = + worker.completedGroupsTasks.filter(async (oldGroup) => { + if (+now > oldGroup.timeToLeave) { + const olderGroups = + worker.completedGroupsTasks.filter( + (value) => { + if ( + value.groupID == + oldGroup.groupID && + value.timeToLeave > + oldGroup.timeToLeave + ) { + return true; + } else { + return false; + } + } + ); + if (olderGroups.length == 0) { + let peerChannel: telegram.Api.TypeInputPeer; + try { + peerChannel = + await client.getInputEntity( + BigInteger(oldGroup.groupID) + ); + } catch (err) { + return false; + } + try { + await client.invoke( + new telegram.Api.channels.GetParticipant( + { + channel: peerChannel, + participant: "me", + } + ) + ); + } catch (err) { + if (err.code == 400) { + return false; + } else { + logger.error( + `Unknown error due GetParticipant | ${worker.phoneNumber}` + ); + return true; + } + } + try { + await client.invoke( + new telegram.Api.channels.LeaveChannel( + { + channel: peerChannel, + } + ) + ); + } catch (err) { + logger.debug( + `Cant leave channel | ${worker.phoneNumber}` + ); + return true; } } - try { - await client.invoke( - new telegram.Api.channels.LeaveChannel({ - channel: peerChannel - }) - ); - } catch (err){ - logger.debug(`Cant leave channel | ${worker.phoneNumber}`); - return true; - } - - + return false; + } else { + return true; } - return false; - } else { - return true - } - }) + }); } // - for (const chat of settings.telegramLinks.groupsToJoin) { try { - await client.invoke(new telegram.Api.channels.GetParticipant({ channel: chat, participant: 'me' })); + await client.invoke( + new telegram.Api.channels.GetParticipant({ + channel: chat, + participant: "me", + }) + ); } catch (err) { if (err.code == 400) { - await client.invoke(new telegram.Api.channels.JoinChannel({ channel: chat })); + try { + await client.invoke( + new telegram.Api.channels.JoinChannel({ + channel: chat, + }) + ); + } catch (err) { + if (err instanceof telegram.errors.RPCError) { + switch (err.errorMessage) { + case "CHANNELS_TOO_MUCH": + logger.error( + `Too much groups | ${worker.phoneNumber}` + ); + continue workersLoop; + default: + logger.error( + `Some error due joining HK groups | ${worker.phoneNumber}\n${err.message}\n${err.stack}` + ); + continue workersLoop; + } + } + } } else { - logger.error(`Unknown error due GetParticipant | ${worker.phoneNumber}`) + logger.error( + `Unknown error due GetParticipant | ${worker.phoneNumber}` + ); throw err; } } } { // unblock hkbot - if (await isBannedByClient(client, settings.telegramLinks.botLink)) { - + if ( + await isBannedByClient( + client, + settings.telegramLinks.botLink + ) + ) { const result = await client.invoke( new telegram.Api.contacts.Unblock({ - id: settings.telegramLinks.botLink - })); + id: settings.telegramLinks.botLink, + }) + ); if (result != true) { - logger.error(`Cant unblock ${settings.telegramLinks.botLink} | ${worker.phoneNumber}`); + logger.error( + `Cant unblock ${settings.telegramLinks.botLink} | ${worker.phoneNumber}` + ); continue workersLoop; } else { - logger.info(`HK bot unblocked | ${worker.phoneNumber}`) + logger.info( + `HK bot unblocked | ${worker.phoneNumber}` + ); } } - } await sleep(Math.random() * 50_000); - if ((await getMessagesByEntity(client, botEntity, botEntity)).length == 0) { + if ( + (await getMessagesByEntity(client, botEntity, botEntity)) + .length == 0 + ) { // sending start message - let id: number = -1; + let id = -1; if (worker.refferal !== null) { - id = (await client.sendMessage(botEntity, { message: `/start ${worker.refferal}` })).id; - logger.debug(`First start of ${botEntity.username} via refferal link of ${worker.refferal} | ${worker.phoneNumber}`); + id = ( + await client.sendMessage(botEntity, { + message: `/start ${worker.refferal}`, + }) + ).id; + logger.debug( + `First start of ${botEntity.username} via refferal link of ${worker.refferal} | ${worker.phoneNumber}` + ); } else { - id = (await client.sendMessage(botEntity, { message: `/start` })).id; - logger.debug(`First start of ${botEntity.username} | ${worker.phoneNumber}`); + id = ( + await client.sendMessage(botEntity, { + message: `/start`, + }) + ).id; + logger.debug( + `First start of ${botEntity.username} | ${worker.phoneNumber}` + ); } - await waitNewMessages(client, worker, botEntity, id) + await waitNewMessages(client, worker, botEntity, id); } logger.info(`Sending earn message... | ${worker.phoneNumber}`); - const requestTasksMessage = await client.sendMessage(botEntity, { message: settings.botButtons.earn }); - await waitNewMessages(client, worker, botEntity, requestTasksMessage.id) - let tasksSelector: telegram.Api.Message = (await client.getMessages(botEntity, { - minId: requestTasksMessage.id, - }))[0]; - if (tasksSelector.message.includes(settings.botMessages.verification) == true) { - // vertification - logger.warn(`Account ${worker.phoneNumber} is unvertificated`) - const url: string = tasksSelector.buttons![0][0].url!; - await vertification(client, worker, hero, url, botEntity, tasksSelector.id); - const requestTasksMessage = await client.sendMessage(botEntity, { message: settings.botButtons.earn }); - await waitNewMessages(client, worker, botEntity, requestTasksMessage.id) - tasksSelector = (await client.getMessages(botEntity, { + const requestTasksMessage = await client.sendMessage( + botEntity, + { + message: settings.botButtons.earn, + } + ); + await waitNewMessages( + client, + worker, + botEntity, + requestTasksMessage.id + ); + let tasksSelector: telegram.Api.Message = ( + await client.getMessages(botEntity, { minId: requestTasksMessage.id, - }))[0]; + }) + )[0]; + if ( + tasksSelector.message.includes( + settings.botMessages.verification + ) == true + ) { + // vertification + logger.warn( + `Account ${worker.phoneNumber} is unvertificated` + ); + const url: string = tasksSelector.buttons![0][0].url!; + await vertification(hero, url); + const requestTasksMessage = await client.sendMessage( + botEntity, + { + message: settings.botButtons.earn, + } + ); + await waitNewMessages( + client, + worker, + botEntity, + requestTasksMessage.id + ); + tasksSelector = ( + await client.getMessages(botEntity, { + minId: requestTasksMessage.id, + }) + )[0]; } - try{ - await doSitesTasks(client,worker,hero,botEntity,tasksSelector); - await doChatsTasks(client, worker, hero, botEntity, tasksSelector); - try{ - await doBotTasks(client, worker, hero, botEntity, tasksSelector); - } catch (err){ - await client.sendMessage(botEntity,{message:'/cancel'}) - throw err + try { + await doSitesTasks( + client, + worker, + hero, + botEntity, + tasksSelector + ); + await doChatsTasks( + client, + worker, + hero, + botEntity, + tasksSelector + ); + try { + await doBotTasks( + client, + worker, + hero, + botEntity, + tasksSelector + ); + } catch (err) { + await client.sendMessage(botEntity, { + message: "/cancel", + }); + throw err; } - - } catch (err){ - logger.error(`Some error due doing tasks\n${err}\n${err.stack}`) + } catch (err) { + logger.error( + `Some error due doing tasks\n${err}\n${err.stack}` + ); } db.updateUser(worker); await hero.close(); await client.disconnect(); - await sleep(randomAB(settings.sleepTime.betweenSessions[0],settings.sleepTime.betweenSessions[1])*1_000); + await sleep( + randomAB( + settings.sleepTime.betweenSessions[0], + settings.sleepTime.betweenSessions[1] + ) * 1_000 + ); } - } - } - + }; const workers = await db.getUsers(); - if (settings.shuffleAccounts){ - workers.sort(() => Math.random() - 0.5) + if (settings.shuffleAccounts) { + workers.sort(() => Math.random() - 0.5); } - let workersGroups: Array = []; + const workersGroups: Array = []; for (const worker of workers) { usedIPs.push({ worker: worker, usedIps: [], - current: '', - }) + current: "", + }); } - for (let i = 0; i != workers.length + 1; i += settings.pararels) { - const _workers = workers.slice(i, i + settings.pararels); - if (_workers.length != 0) { - workersGroups.push(_workers); - } else { - break; - } + for (let i = 0; i != settings.pararels; i++) { + const startIndex = i * Math.ceil(workers.length / settings.pararels); + const _workers = workers.slice( + startIndex, + startIndex + Math.ceil(workers.length / settings.pararels) + ); + workersGroups.push(_workers); + } + const pararels: Promise[] = []; - } - if (workersGroups.length != Math.ceil(workers.length / settings.pararels)) { - logger.warn(`There is strange thing with workersGroups\n${workersGroups.length} ${Math.ceil(workers.length / settings.pararels)}`); - } - let pararels: Promise[] = []; - const miner = new Miner(); - await miner.listen({port:(await findFreePorts(1))[0]}); + await miner.listen({ port: (await findFreePorts(1))[0] }); const _ports = await findFreePorts(workers.length * 3); // logger.debug(`Is there port of miner:${_ports.indexOf(await miner.port)}, ${await miner.port}`) @@ -432,102 +615,133 @@ const farm: () => Promise = async () => { const multibar = new cliProgress.MultiBar({ hideCursor: true, barsize: 50, - barCompleteChar: '❌', - barIncompleteChar: '✔️', + barCompleteChar: "❌", + barIncompleteChar: "✔️", clearOnComplete: true, format: `{status} | {bar} | {value}/{total}sec timeout`, - }); - let _containers: Promise[] = []; + const _containers: Promise[] = []; for (let i = 0; i != workersGroups.length; i++) { _containers.push( - startNewTorDocker(_ports[i * 3], _ports[i * 3 + 1], _ports[i * 3 + 2], multibar) + startNewTorDocker( + _ports[i * 3], + _ports[i * 3 + 1], + _ports[i * 3 + 2], + multibar + ) ); } - containers = (await Promise.allSettled(_containers)).map((value) => { return (value as PromiseFulfilledResult).value }); + containers = (await Promise.allSettled(_containers)).map((value) => { + return (value as PromiseFulfilledResult).value; + }); multibar.stop(); } - - for (let i = 0; i != workersGroups.length; i++) { - - pararels.push(proccesGroup(workersGroups[i], { - http: _ports[i * 3], - socks: _ports[i * 3 + 1], - control: _ports[i * 3 + 2], - minerPort: await miner.port - - } - )); + pararels.push( + proccesGroup(workersGroups[i], { + http: _ports[i * 3], + socks: _ports[i * 3 + 1], + control: _ports[i * 3 + 2], + minerPort: await miner.port, + }) + ); } const results = await Promise.allSettled(pararels); for (const result of results) { - if (result.status == 'rejected') { + if (result.status == "rejected") { logger.warn(`Promise is canceled due ${result.reason}`); - } + } } - logger.debug('Closing opened docker containers ') + logger.debug("Closing opened docker containers "); for (const container of containers) { - try { await container.stop(); - } catch (err) { } - + } catch (err) {} } - await db.save() + await db.save(); await miner.close(true); -} +}; // menu (async () => { - while (true) { + while (true) { + let accounts: AccountInterface[] = []; + try { + accounts = await db.getUsers(); + } catch (err) { + continue; + } - const answer = await prompt({ - type: 'select', - name: 'menu', - message: 'Choose action', - choices: [ - ((await db.getUsers()).length > 0) ? { title: 'Start', description: 'Starting farm', value: 'start' } : { title: 'Start', description: 'Add accounts first...', value: 'start', disabled: true }, - { title: 'Add accounts', description: 'Add accounts to database', value: 'addAccounts' }, - { title: 'Check balances', value: 'checkBalances', disabled: true }, - { title: 'Withdraw', value: 'withdraw', disabled: true }, - { title: 'Exit', description: 'You realy dont know what it mean?' } - ] - }) - switch (answer.menu) { - case 'addAccounts': - await addAccounts(); - break; - case 'start': - while (true) { - try { - await farm(); - const sleepTime=randomAB(settings.sleepTime.afterDoing[0],settings.sleepTime.afterDoing[1]); - logger.info(`Sleeping for ${sleepTime} secs`); - await sleep(sleepTime*1_000); - } catch (err) { - logger.error(`Unknown error\n${err.stack}\n${typeof err}`); - break; - } + const answer = await prompt({ + type: "select", + name: "menu", + message: "Choose action", + choices: [ + accounts.length > 0 + ? { + title: "Start", + description: `Starting farm for ${accounts.length} accounts`, + value: "start", + } + : { + title: "Start", + description: "Add accounts first...", + value: "start", + disabled: true, + }, + { + title: "Add accounts", + description: "Add accounts to database", + value: "addAccounts", + }, + { + title: "Check balances", + value: "checkBalances", + disabled: true, + }, + { title: "Withdraw", value: "withdraw", disabled: true }, + { + title: "Exit", + description: "You realy dont know what it mean?", + }, + ], + }); + switch (answer.menu) { + case "addAccounts": + await addAccounts(); + break; + case "start": + while (true) { + try { + await farm(); + const sleepTime = randomAB( + settings.sleepTime.afterDoing[0], + settings.sleepTime.afterDoing[1] + ); + logger.info(`Sleeping for ${sleepTime} secs`); + await sleep(sleepTime * 1_000); + } catch (err) { + logger.error( + `Unknown error\n${err.stack}\n${typeof err}` + ); + break; } - break; - - - default: - logger.info('Bye bye'); - process.exit(); - - } + } + break; + default: + logger.info("Bye bye"); + process.exit(); + } } })(); -process.on('SIGINT', function () { - db.save().then(()=>{ - logger.info('Bye bye'); +process.on("SIGINT", function () { + db.save().then(() => { + logger.info("Bye bye"); process.exit(); - }) - + }); }); + diff --git a/interfaces/databaseInterface.d.ts b/interfaces/databaseInterface.d.ts index d3be3c2..d41f683 100644 --- a/interfaces/databaseInterface.d.ts +++ b/interfaces/databaseInterface.d.ts @@ -1,38 +1,35 @@ -import {Fingerprint} from "fingerprint-generator" +import { Fingerprint } from "fingerprint-generator"; export interface faucetMailInterface { faucet: { - username: string, - password: string - } + username: string; + password: string; + }; mail: { - address: string, - password: string - } + address: string; + password: string; + }; } export interface AccountCompletedGroupsTasksInterface { - timeToLeave: number, - groupID: string + timeToLeave: number; + groupID: string; } -export interface AccountWithdrawInterface { - -} +export interface AccountWithdrawInterface {} export interface AccountInterface { - phoneNumber: string, - telegramID: number, - apiID: number, - apiHash: string, - password: string, - faucetMail: faucetMailInterface, - stringSession: string, - balance: number, - withdraws:AccountWithdrawInterface[], - completedGroupsTasks:AccountCompletedGroupsTasksInterface[], - canBeRefferal: boolean, - browserFingerprint:Fingerprint, - refferal:number | null - + phoneNumber: string; + telegramID: number; + apiID: number; + apiHash: string; + password: string; + faucetMail: faucetMailInterface; + stringSession: string; + balance: number; + withdraws: AccountWithdrawInterface[]; + completedGroupsTasks: AccountCompletedGroupsTasksInterface[]; + canBeRefferal: boolean; + browserFingerprint: Fingerprint; + refferal: number | null; } export interface DatabaseInterface { - accounts: AccountInterface[] + accounts: AccountInterface[]; } diff --git a/interfaces/otherInterfaces.d.ts b/interfaces/otherInterfaces.d.ts index 4e10661..2458919 100644 --- a/interfaces/otherInterfaces.d.ts +++ b/interfaces/otherInterfaces.d.ts @@ -1,22 +1,20 @@ -import * as telegram from 'telegram'; -import {AccountInterface} from './databaseInterface' - +import * as telegram from "telegram"; +import { AccountInterface } from "./databaseInterface"; export interface prevTaskInterface { - task: telegram.Api.Message, - lastMessage:telegram.Api.Message - + task: telegram.Api.Message; + lastMessage: telegram.Api.Message; } export interface portsInterface { - http: number, - socks: number, - control:number, - minerPort?:number + http: number; + socks: number; + control: number; + minerPort?: number; } -export interface usedIPInterface{ - worker: AccountInterface, - usedIps: string[], - current: string -} +export interface usedIPInterface { + worker: AccountInterface; + usedIps: string[]; + current: string; +} diff --git a/interfaces/settingsInterface.d.ts b/interfaces/settingsInterface.d.ts index 08974d4..da89bf0 100644 --- a/interfaces/settingsInterface.d.ts +++ b/interfaces/settingsInterface.d.ts @@ -1,37 +1,33 @@ - export interface settingsInterface { - - logLevel: 'debug' | 'info' | 'error', - pararels: number, - mainCrypto: 'TRX', - minimalToWithdraw: number, - maxRefferals: number, + logLevel: "debug" | "info" | "error"; + pararels: number; + mainCrypto: "TRX"; + minimalToWithdraw: number; + maxRefferals: number; // to find botMessages: { - verification: string, - tasksSelector: string, - taskOver: string, - taskComplete: string, - notInGroup: string, - oldMessage: string - } + verification: string; + tasksSelector: string; + taskOver: string; + taskComplete: string; + notInGroup: string; + oldMessage: string; + }; // to send - botButtons:{ - earn: string, - balance: string, - withdraw: string - }, + botButtons: { + earn: string; + balance: string; + withdraw: string; + }; // to join - telegramLinks:{ - botLink: string, - groupsToJoin: string[] - - }, + telegramLinks: { + botLink: string; + groupsToJoin: string[]; + }; sleepTime: { - afterDoing: number[], - betweenSessions: number[] - }, - shuffleAccounts: boolean - bypassMode: boolean + afterDoing: number[]; + betweenSessions: number[]; + }; + shuffleAccounts: boolean; + bypassMode: boolean; } - diff --git a/logger.ts b/logger.ts index 579d5b9..fe85102 100644 --- a/logger.ts +++ b/logger.ts @@ -1,18 +1,19 @@ -import winston = require("winston") -const logger=winston.createLogger({ - level: 'debug', +import winston = require("winston"); +const logger = winston.createLogger({ + level: "debug", format: winston.format.combine( winston.format.colorize(), - winston.format.printf((info)=>{ - return `${new Date().toLocaleTimeString()} | ${info.level} - ${info.message} ` + winston.format.printf((info) => { + return `${new Date().toLocaleTimeString()} | ${info.level} - ${ + info.message + } `; }) ), transports: [ new winston.transports.Console(), - new winston.transports.File({ filename: 'errors.log', level: 'error' }), - new winston.transports.File({ filename: 'info.log' }), + new winston.transports.File({ filename: "errors.log", level: "error" }), + new winston.transports.File({ filename: "info.log" }), ], }); - export default logger; diff --git a/package.json b/package.json index d73c761..52d1b46 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "name": "hk_bot", "version": "0.0.1", - "description": "test", + "description": "Script which allow earn some crypto via telegram", "main": "/build/index.js", "devDependencies": { "@types/cli-progress": "^3.11.0", @@ -35,7 +35,7 @@ }, "repository": { "type": "git", - "url": "https://notabug.org/minicx/hk_bot.git" + "url": "https://git.disroot.org/minicx/hk_bot.git" }, "keywords": [ "telegram", @@ -44,5 +44,5 @@ "crypto" ], "author": "minicx", - "license": "ISC" + "license": "MIT" } diff --git a/utils.ts b/utils.ts index cf4156c..179a1e8 100644 --- a/utils.ts +++ b/utils.ts @@ -1,51 +1,83 @@ import Docker from "dockerode"; import logger from "./logger"; -import {database as db,settings} from './database'; +import { settings } from "./database"; // import Hero from "@ulixee/hero"; // import Miner from "@ulixee/miner"; import { sleep } from "telegram/Helpers"; import { AccountInterface } from "./interfaces/databaseInterface"; -import * as telegram from 'telegram'; +import * as telegram from "telegram"; import axios from "axios"; -import cliProgress from "cli-progress" -export class CaptchaError extends Error{} -export class NoNewMessagesError extends Error{} -export class DockerIsBrockenError extends Error{} +import cliProgress from "cli-progress"; +import { isNull, isUndefined } from "lodash"; +export class CaptchaError extends Error {} +export class NoNewMessagesError extends Error {} +export class DockerIsBrockenError extends Error {} export function randomAB(a: number, b: number) { return Math.floor(Math.random() * (b - a + 1) + a); } -export async function isBannedByClient(client: telegram.TelegramClient, username: string): Promise { - const blockedUsers = (await client.invoke(new telegram.Api.contacts.GetBlocked({ limit: 2147483647 }))).users as telegram.Api.User[]; +export async function isBannedByClient( + client: telegram.TelegramClient, + username: string +): Promise { + const blockedUsers = ( + await client.invoke( + new telegram.Api.contacts.GetBlocked({ limit: 2147483647 }) + ) + ).users as telegram.Api.User[]; for (const blockedUser of blockedUsers) { - if (blockedUser.username !== undefined && blockedUser.username == username.replace('@', '')) { + if ( + blockedUser.username !== undefined && + blockedUser.username == username.replace("@", "") + ) { return true; } - } return false; } -export async function getMessagesByEntity(client: telegram.TelegramClient, chatEntity: telegram.Api.Chat | telegram.Api.User | string, entity: telegram.Api.User | string, params = {}) { - let messages = new telegram.helpers.TotalList; +export async function getMessagesByEntity( + client: telegram.TelegramClient, + chatEntity: telegram.Api.Chat | telegram.Api.User | string, + entity: telegram.Api.User | string, + params = {} +) { + const messages = new telegram.helpers.TotalList(); if (entity instanceof telegram.Api.User) { for (const message of await client.getMessages(chatEntity, params)) { - if ((message.sender as telegram.Api.User).username == entity.username) { + if ( + (message.sender as telegram.Api.User).username == + entity.username + ) { messages.push(message); } } } else { for (const message of await client.getMessages(chatEntity, params)) { - if ((message.sender as telegram.Api.User).username!.includes(entity.replace('@', ''))) { - messages.push(message); + if ( + isNull((message.sender as telegram.Api.User).username) != + true && + isUndefined((message.sender as telegram.Api.User).username) != + true + ) { + if ( + (message.sender as telegram.Api.User).username!.includes( + entity.replace("@", "") + ) + ) { + messages.push(message); + } } } } return messages; } -export function arrayWithoutElementAtIndex(arr: AccountInterface[] | [], index: number) { +export function arrayWithoutElementAtIndex( + arr: AccountInterface[] | [], + index: number +) { return arr.filter(function (value, arrIndex) { return index !== arrIndex; }); @@ -54,13 +86,15 @@ export async function getIP(proxyPort: number): Promise { // https://github.com/ulixee/unblocked/blob/main/plugins/default-browser-emulator/lib/helpers/lookupPublicIp.ts let data: string | PromiseLike | null; try { - data = (await axios.get('http://icanhazip.com/', { - proxy: { - host: '127.0.0.1', - port: proxyPort - }, - timeout: 100000 - })).data; + data = ( + await axios.get("http://icanhazip.com/", { + proxy: { + host: "127.0.0.1", + port: proxyPort, + }, + timeout: 100000, + }) + ).data; } catch (err) { logger.debug(err); return null; @@ -70,92 +104,127 @@ export async function getIP(proxyPort: number): Promise { return null; } return await data; - } -export async function waitNewMessages(client: telegram.TelegramClient, worker: AccountInterface, chatEntity: telegram.Api.Chat | telegram.Api.User | string, idOfLastMessage: number, timeout: number = 20): Promise { - +export async function waitNewMessages( + client: telegram.TelegramClient, + worker: AccountInterface, + chatEntity: telegram.Api.Chat | telegram.Api.User | string, + idOfLastMessage: number, + timeout = 20 +): Promise { const start_time = new Date(); - while ((await getMessagesByEntity(client, chatEntity, chatEntity as telegram.Api.User | string, { minId: idOfLastMessage, limit: 2147483647 })).length == 0) { - if ((+(new Date()) - +start_time) / 1000 >= timeout) { - logger.error(`${worker.phoneNumber} | Bot didnt answer for ${timeout}s`); - throw new NoNewMessagesError('Is bot working?'); + while ( + ( + await getMessagesByEntity( + client, + chatEntity, + chatEntity as telegram.Api.User | string, + { minId: idOfLastMessage, limit: 2147483647 } + ) + ).length == 0 + ) { + if ((+new Date() - +start_time) / 1000 >= timeout) { + logger.error( + `${worker.phoneNumber} | Bot didnt answer for ${timeout}s` + ); + throw new NoNewMessagesError("Is bot working?"); } } logger.debug(`${worker.phoneNumber} | Bot answered`); } -export async function startNewTorDocker(proxyPort: number, socksPort: number, controlPort: number, mainProgressBar: cliProgress.MultiBar, timeout: number = 200): Promise { +export async function startNewTorDocker( + proxyPort: number, + socksPort: number, + controlPort: number, + mainProgressBar: cliProgress.MultiBar, + timeout = 200 +): Promise { timeout *= 2; - let docker = new Docker({ socketPath: '/var/run/docker.sock' }); + const docker = new Docker({ socketPath: "/var/run/docker.sock" }); let isPulled = false; mainLoop: for (const image of await docker.listImages()) { const tags = image.RepoTags; if (tags !== undefined) for (const repoTag of tags) { - if (repoTag.search('dperson/torproxy:latest') != -1) { + if (repoTag.search("dperson/torproxy:latest") != -1) { isPulled = true; break mainLoop; } } } if (isPulled != true) { - await docker.pull('dperson/torproxy:latest'); + await docker.pull("dperson/torproxy:latest"); } // bugy shit const options: Docker.ContainerCreateOptions = { - Image: 'dperson/torproxy', - Env: [ - "PASSWORD=qwerty", - "LOCATION=US", - "TOR_NewCircuitPeriod=50", - ], + Image: "dperson/torproxy", + Env: ["PASSWORD=qwerty", "LOCATION=US", "TOR_NewCircuitPeriod=50"], ExposedPorts: {}, HostConfig: { PortBindings: { - '8118/tcp': [{ - HostPort: `${proxyPort}` - }], - '9050/tcp': [{ - HostPort: `${socksPort}` - }], - '9051/tcp': [{ - HostPort: `${controlPort}` - }] - } + "8118/tcp": [ + { + HostPort: `${proxyPort}`, + }, + ], + "9050/tcp": [ + { + HostPort: `${socksPort}`, + }, + ], + "9051/tcp": [ + { + HostPort: `${controlPort}`, + }, + ], + }, }, Healthcheck: { Interval: 2 * 1000000000, Timeout: 50 * 1000000000, StartPeriod: 50 * 1000000000, // Test:['CMD_SHELL',`curl -sx localhost:8118 'https://check.torproject.org/' | grep -qm1 Congratulations`] - } + }, }; const container = await docker.createContainer(options); await container.start(); - const progressBar = mainProgressBar.create(timeout / 2, 0, { status: `Starting docker${(settings.logLevel == 'debug') ? ` ${proxyPort} ${socksPort} ${controlPort}` : ''}` }); - while ((await container.inspect())!.State.Health!.Status != 'healthy') { + const progressBar = mainProgressBar.create(timeout / 2, 0, { + status: `Starting docker${ + settings.logLevel == "debug" + ? ` ${proxyPort} ${socksPort} ${controlPort}` + : "" + }`, + }); + while ((await container.inspect())!.State.Health!.Status != "healthy") { const state = (await container.inspect())!.State.Health!.Status; if (progressBar.getProgress() >= timeout) { await container.kill(); - progressBar.update(timeout / 2, { status: 'Failed' }); + progressBar.update(timeout / 2, { status: "Failed" }); progressBar.stop(); throw new DockerIsBrockenError(`Docker ${container.id} is broken`); } - if (state == 'unhealthy') { + if (state == "unhealthy") { await container.kill(); - progressBar.update(timeout / 2, { status: 'Docker is unhealthy...' }); + progressBar.update(timeout / 2, { + status: "Docker is unhealthy...", + }); progressBar.stop(); - return await startNewTorDocker(proxyPort, socksPort, controlPort, mainProgressBar, timeout / 2); + return await startNewTorDocker( + proxyPort, + socksPort, + controlPort, + mainProgressBar, + timeout / 2 + ); } progressBar.increment(); await sleep(2000); } - progressBar.update(0, { status: 'Started' }); + progressBar.update(0, { status: "Started" }); progressBar.stop(); return container; - - }