Added README and LICENSE
This commit is contained in:
parent
a3d735ba6c
commit
f3087aa626
|
@ -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.
|
|
@ -0,0 +1,57 @@
|
|||
<div align="center">
|
||||
<h1><b>HK_BOT🤖</b></h1>
|
||||
<a href="https://hits.sh/git.disroot.org/minicx/hk_bot/"><img alt="Hits" src="https://hits.sh/git.disroot.org/minicx/hk_bot.svg"/></a>
|
||||
<a href="https://git.disroot.org/minicx/hk_bot/LiCENSE"><img src="https://shields.io/badge/license-MIT-green" alt='License'/></a>
|
||||
</div>
|
||||
|
||||
# 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`
|
||||
|
||||
<details>
|
||||
<summary>Other commands</summary>
|
||||
|
||||
| Command | Description |
|
||||
| ------- | ------------------------------------------------------------------ |
|
||||
| build | just compile all `.ts` files to `build` directory into `.js` |
|
||||
|
||||
</details>
|
||||
|
||||
# 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**
|
||||
|
||||
* <details>
|
||||
<summary><b>Explanation.json</b></summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"<EMAIL>": {
|
||||
"mail_passphrase": "<PASSWORD OF MAIL>",
|
||||
"faucetpay": {
|
||||
"username": "<USERNAME OF FAUCET ACCOUNT>",
|
||||
"password": "<PASSWORD OF FAUCET ACCOUNT>"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
# Creator and contributors
|
||||
<div align='center'>
|
||||
<img src="https://git.disroot.org/avatars/cf8b3507d9ab93a478052ffd7e750f12" width="100px" style="display:flex;border-radius: 75px;" alt="minicx_pict" >
|
||||
<a href="https://git.disroot.org/minicx"><b>Main devoloper</b></a>
|
||||
</div>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
221
database.ts
221
database.ts
|
@ -1,37 +1,43 @@
|
|||
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:[]
|
||||
}
|
||||
accounts: [],
|
||||
};
|
||||
private json: JsonDB;
|
||||
constructor() {
|
||||
this.json=new JsonDB(new Config('db.json',false,true,'/'));
|
||||
this.json.getData('/').then((result)=>{
|
||||
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)
|
||||
this.json
|
||||
.push("/", this.default, true)
|
||||
.catch((err) => logger.error(`${err} due setting defaults`))
|
||||
.then(() => {
|
||||
logger.info('Setting DB to defaults...');
|
||||
logger.info("Setting DB to defaults...");
|
||||
});
|
||||
this.save();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
async findWallet(walletsFile: string): Promise<interfacesDB.faucetMailInterface | undefined>{
|
||||
const wallets_json=new JsonDB(new Config(walletsFile,true,true,'/'));
|
||||
const wallets=(await wallets_json.getData('/'));
|
||||
async findWallet(
|
||||
walletsFile: string
|
||||
): Promise<interfacesDB.faucetMailInterface | undefined> {
|
||||
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')
|
||||
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;
|
||||
const accounts = await this.getUsers();
|
||||
let faucetWallet: interfacesDB.faucetMailInterface | undefined =
|
||||
undefined;
|
||||
for (const _wallet in wallets) {
|
||||
let flag = false;
|
||||
if (accounts.length > 0) {
|
||||
|
@ -46,32 +52,30 @@ export class Database {
|
|||
faucetWallet = {
|
||||
faucet: {
|
||||
username: wallets[_wallet].faucetpay.username,
|
||||
password:wallets[_wallet].faucetpay.password
|
||||
password: wallets[_wallet].faucetpay.password,
|
||||
},
|
||||
mail: {
|
||||
address: _wallet,
|
||||
password:wallets[_wallet].mail_passphrase
|
||||
}
|
||||
}
|
||||
password: wallets[_wallet].mail_passphrase,
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return faucetWallet;
|
||||
|
||||
}
|
||||
async findRefferal(maxRefferals: number): Promise<number | null> {
|
||||
let refferal: number | null = null;
|
||||
const accounts=(await this.getUsers());
|
||||
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));
|
||||
const _accounts = arrayWithoutElementAtIndex(
|
||||
accounts,
|
||||
accounts.indexOf(mainAccount)
|
||||
);
|
||||
for (const _account of _accounts) {
|
||||
|
||||
if (_account.refferal == mainAccount.telegramID) {
|
||||
counter += 1;
|
||||
}
|
||||
|
@ -81,7 +85,6 @@ export class Database {
|
|||
refferal = Number(mainAccount.telegramID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return refferal;
|
||||
|
@ -90,24 +93,37 @@ export class Database {
|
|||
await this.json.save(true);
|
||||
}
|
||||
async updateUser(account: interfacesDB.AccountInterface) {
|
||||
const index=await this.json.getIndex("/accounts", account.phoneNumber,"phoneNumber")
|
||||
logger.debug(`Index in database is ${index} of ${account.phoneNumber}`)
|
||||
const index = await this.json.getIndex(
|
||||
"/accounts",
|
||||
account.phoneNumber,
|
||||
"phoneNumber"
|
||||
);
|
||||
logger.debug(`Index in database is ${index} of ${account.phoneNumber}`);
|
||||
await this.json.push(`/accounts[${index}]`, account, true);
|
||||
}
|
||||
async addUser(account: Omit<interfacesDB.AccountInterface,
|
||||
'balance' | 'withdraws' | 'completedGroupsTasks' | 'canBeRefferal'
|
||||
| 'browserFingerprint' | 'faucetMail'>,wallets_json: string): Promise<void>{
|
||||
async addUser(
|
||||
account: Omit<
|
||||
interfacesDB.AccountInterface,
|
||||
| "balance"
|
||||
| "withdraws"
|
||||
| "completedGroupsTasks"
|
||||
| "canBeRefferal"
|
||||
| "browserFingerprint"
|
||||
| "faucetMail"
|
||||
>,
|
||||
wallets_json: string
|
||||
): Promise<void> {
|
||||
const fingerprintGenerator = new FingerprintGenerator();
|
||||
const fingerprint = fingerprintGenerator.getFingerprint({
|
||||
devices: ['desktop'],
|
||||
browsers: ['chrome'],
|
||||
|
||||
devices: ["desktop"],
|
||||
browsers: ["chrome"],
|
||||
}).fingerprint;
|
||||
|
||||
const faucet:interfacesDB.faucetMailInterface | undefined=await this.findWallet(wallets_json);
|
||||
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');
|
||||
logger.error("Add new faucet accounts");
|
||||
throw new Error("Add new faucet accounts");
|
||||
} else {
|
||||
const canBeRefferal: boolean = Math.random() < 0.5;
|
||||
|
||||
|
@ -124,100 +140,120 @@ export class Database {
|
|||
completedGroupsTasks: [],
|
||||
canBeRefferal: canBeRefferal,
|
||||
refferal: account.refferal,
|
||||
browserFingerprint:fingerprint
|
||||
}
|
||||
browserFingerprint: fingerprint,
|
||||
};
|
||||
await this.json.push(`/accounts[]`, _account);
|
||||
}
|
||||
await this.save();
|
||||
|
||||
}
|
||||
|
||||
async getUsers(): Promise<interfacesDB.AccountInterface[]> {
|
||||
|
||||
try {
|
||||
return await this.json.getObject<interfacesDB.AccountInterface[]>('/accounts');
|
||||
return await this.json.getObject<interfacesDB.AccountInterface[]>(
|
||||
"/accounts"
|
||||
);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export class Settings implements interfacesSettings.settingsInterface {
|
||||
public readonly default: interfacesSettings.settingsInterface = {
|
||||
logLevel: 'debug',
|
||||
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],
|
||||
},
|
||||
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<interfacesSettings.settingsInterface>('/').then((result) => {
|
||||
this.json = new JsonDB(new Config("settings.json", false, true, "/"));
|
||||
this.json
|
||||
.getObject<interfacesSettings.settingsInterface>("/")
|
||||
.then((result) => {
|
||||
if (Object.keys(result).length == 0) {
|
||||
logger.warn('Setup config first...');
|
||||
logger.warn("Setup config first...");
|
||||
|
||||
this.json.push('/',this.default,true)
|
||||
.catch((err)=> logger.error(`${err} due setting defaults`))
|
||||
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])){
|
||||
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...`)
|
||||
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){
|
||||
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...`)
|
||||
logger.warn(
|
||||
`Setting '${setting}' corrupted. Check out it...`
|
||||
);
|
||||
continue mainLoop;
|
||||
}
|
||||
}
|
||||
|
@ -229,9 +265,8 @@ export class Settings implements interfacesSettings.settingsInterface {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const database = new Database();
|
||||
const settings = new Settings();
|
||||
export {database,settings}
|
||||
export { database, settings };
|
||||
|
|
678
index.ts
678
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 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 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<void> = 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(
|
||||
{
|
||||
if (
|
||||
file.search(".json") != -1 &&
|
||||
file != "db.json" &&
|
||||
file != "settings.json"
|
||||
) {
|
||||
jsonFiles.push({
|
||||
title: file,
|
||||
description: 'json 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({
|
||||
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)
|
||||
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<void> = 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
|
||||
let tor: any;
|
||||
try {
|
||||
tor = new TorControl({
|
||||
host:'127.0.0.1',
|
||||
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
|
||||
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,30 +208,35 @@ const farm: () => Promise<void> = 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
|
||||
userAgent: fingerprint.navigator.userAgent,
|
||||
|
@ -206,18 +244,21 @@ const farm: () => Promise<void> = async () => {
|
|||
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
|
||||
}
|
||||
|
||||
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,208 +266,343 @@ const farm: () => Promise<void> = 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) => {
|
||||
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) {
|
||||
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;
|
||||
let peerChannel: telegram.Api.TypeInputPeer;
|
||||
try {
|
||||
peerChannel = await client.getInputEntity(BigInteger(oldGroup.groupID));
|
||||
}
|
||||
catch (err){
|
||||
return false
|
||||
peerChannel =
|
||||
await client.getInputEntity(
|
||||
BigInteger(oldGroup.groupID)
|
||||
);
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await client.invoke(new telegram.Api.channels.GetParticipant({ channel: peerChannel, participant: 'me' }));
|
||||
await client.invoke(
|
||||
new telegram.Api.channels.GetParticipant(
|
||||
{
|
||||
channel: peerChannel,
|
||||
participant: "me",
|
||||
}
|
||||
)
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.code == 400) {
|
||||
return false
|
||||
return false;
|
||||
} else {
|
||||
logger.error(`Unknown error due GetParticipant | ${worker.phoneNumber}`)
|
||||
return true
|
||||
logger.error(
|
||||
`Unknown error due GetParticipant | ${worker.phoneNumber}`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await client.invoke(
|
||||
new telegram.Api.channels.LeaveChannel({
|
||||
channel: peerChannel
|
||||
})
|
||||
new telegram.Api.channels.LeaveChannel(
|
||||
{
|
||||
channel: peerChannel,
|
||||
}
|
||||
)
|
||||
);
|
||||
} catch (err) {
|
||||
logger.debug(`Cant leave channel | ${worker.phoneNumber}`);
|
||||
logger.debug(
|
||||
`Cant leave channel | ${worker.phoneNumber}`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true
|
||||
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) {
|
||||
try {
|
||||
await client.invoke(new telegram.Api.channels.JoinChannel({ channel: chat }));
|
||||
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
|
||||
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
|
||||
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, {
|
||||
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) {
|
||||
})
|
||||
)[0];
|
||||
if (
|
||||
tasksSelector.message.includes(
|
||||
settings.botMessages.verification
|
||||
) == true
|
||||
) {
|
||||
// vertification
|
||||
logger.warn(`Account ${worker.phoneNumber} is unvertificated`)
|
||||
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, {
|
||||
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];
|
||||
})
|
||||
)[0];
|
||||
}
|
||||
|
||||
try {
|
||||
await doSitesTasks(client,worker,hero,botEntity,tasksSelector);
|
||||
await doChatsTasks(client, worker, hero, botEntity, tasksSelector);
|
||||
await doSitesTasks(
|
||||
client,
|
||||
worker,
|
||||
hero,
|
||||
botEntity,
|
||||
tasksSelector
|
||||
);
|
||||
await doChatsTasks(
|
||||
client,
|
||||
worker,
|
||||
hero,
|
||||
botEntity,
|
||||
tasksSelector
|
||||
);
|
||||
try {
|
||||
await doBotTasks(client, worker, hero, botEntity, tasksSelector);
|
||||
await doBotTasks(
|
||||
client,
|
||||
worker,
|
||||
hero,
|
||||
botEntity,
|
||||
tasksSelector
|
||||
);
|
||||
} catch (err) {
|
||||
await client.sendMessage(botEntity,{message:'/cancel'})
|
||||
throw err
|
||||
await client.sendMessage(botEntity, {
|
||||
message: "/cancel",
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.error(`Some error due doing tasks\n${err}\n${err.stack}`)
|
||||
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)
|
||||
workers.sort(() => Math.random() - 0.5);
|
||||
}
|
||||
let workersGroups: Array<AccountInterface[]> = [];
|
||||
const workersGroups: Array<AccountInterface[]> = [];
|
||||
|
||||
for (const worker of workers) {
|
||||
usedIPs.push({
|
||||
worker: worker,
|
||||
usedIps: [],
|
||||
current: '',
|
||||
})
|
||||
current: "",
|
||||
});
|
||||
}
|
||||
|
||||
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));
|
||||
const _workers = workers.slice(
|
||||
startIndex,
|
||||
startIndex + Math.ceil(workers.length / settings.pararels)
|
||||
);
|
||||
workersGroups.push(_workers);
|
||||
}
|
||||
let pararels: Promise<void>[] = [];
|
||||
const pararels: Promise<void>[] = [];
|
||||
|
||||
const miner = new Miner();
|
||||
await miner.listen({ port: (await findFreePorts(1))[0] });
|
||||
|
@ -439,108 +615,132 @@ const farm: () => Promise<void> = 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<Docker.Container>[] = [];
|
||||
const _containers: Promise<Docker.Container>[] = [];
|
||||
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<Docker.Container>).value });
|
||||
containers = (await Promise.allSettled(_containers)).map((value) => {
|
||||
return (value as PromiseFulfilledResult<Docker.Container>).value;
|
||||
});
|
||||
multibar.stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (let i = 0; i != workersGroups.length; i++) {
|
||||
|
||||
pararels.push(proccesGroup(workersGroups[i], {
|
||||
pararels.push(
|
||||
proccesGroup(workersGroups[i], {
|
||||
http: _ports[i * 3],
|
||||
socks: _ports[i * 3 + 1],
|
||||
control: _ports[i * 3 + 2],
|
||||
minerPort: await miner.port
|
||||
|
||||
}
|
||||
));
|
||||
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) {}
|
||||
|
||||
}
|
||||
await db.save()
|
||||
await db.save();
|
||||
await miner.close(true);
|
||||
}
|
||||
};
|
||||
|
||||
// menu
|
||||
(async () => {
|
||||
while (true) {
|
||||
let accounts: AccountInterface[] = [];
|
||||
try {
|
||||
accounts=(await db.getUsers());
|
||||
accounts = await db.getUsers();
|
||||
} catch (err) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
const answer = await prompt({
|
||||
type: 'select',
|
||||
name: 'menu',
|
||||
message: 'Choose action',
|
||||
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?' }
|
||||
]
|
||||
})
|
||||
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':
|
||||
case "addAccounts":
|
||||
await addAccounts();
|
||||
break;
|
||||
case 'start':
|
||||
case "start":
|
||||
while (true) {
|
||||
try {
|
||||
await farm();
|
||||
const sleepTime=randomAB(settings.sleepTime.afterDoing[0],settings.sleepTime.afterDoing[1]);
|
||||
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}`);
|
||||
logger.error(
|
||||
`Unknown error\n${err.stack}\n${typeof err}`
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
logger.info('Bye bye');
|
||||
logger.info("Bye bye");
|
||||
process.exit();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
process.on("SIGINT", function () {
|
||||
db.save().then(() => {
|
||||
logger.info('Bye bye');
|
||||
logger.info("Bye bye");
|
||||
process.exit();
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
worker: AccountInterface;
|
||||
usedIps: string[];
|
||||
current: string;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
earn: string;
|
||||
balance: string;
|
||||
withdraw: string;
|
||||
};
|
||||
// to join
|
||||
telegramLinks: {
|
||||
botLink: string,
|
||||
groupsToJoin: string[]
|
||||
|
||||
},
|
||||
botLink: string;
|
||||
groupsToJoin: string[];
|
||||
};
|
||||
sleepTime: {
|
||||
afterDoing: number[],
|
||||
betweenSessions: number[]
|
||||
},
|
||||
shuffleAccounts: boolean
|
||||
bypassMode: boolean
|
||||
afterDoing: number[];
|
||||
betweenSessions: number[];
|
||||
};
|
||||
shuffleAccounts: boolean;
|
||||
bypassMode: boolean;
|
||||
}
|
||||
|
||||
|
|
13
logger.ts
13
logger.ts
|
@ -1,18 +1,19 @@
|
|||
import winston = require("winston")
|
||||
import winston = require("winston");
|
||||
const logger = winston.createLogger({
|
||||
level: 'debug',
|
||||
level: "debug",
|
||||
format: winston.format.combine(
|
||||
winston.format.colorize(),
|
||||
winston.format.printf((info) => {
|
||||
return `${new Date().toLocaleTimeString()} | ${info.level} - ${info.message} `
|
||||
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;
|
||||
|
|
|
@ -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",
|
||||
|
@ -44,5 +44,5 @@
|
|||
"crypto"
|
||||
],
|
||||
"author": "minicx",
|
||||
"license": "ISC"
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
177
utils.ts
177
utils.ts
|
@ -1,14 +1,14 @@
|
|||
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"
|
||||
import cliProgress from "cli-progress";
|
||||
import { isNull, isUndefined } from "lodash";
|
||||
export class CaptchaError extends Error {}
|
||||
export class NoNewMessagesError extends Error {}
|
||||
|
@ -17,39 +17,67 @@ 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<boolean> {
|
||||
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<boolean> {
|
||||
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<telegram.Api.Message>;
|
||||
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<telegram.Api.Message>();
|
||||
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 (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('@', ''))) {
|
||||
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;
|
||||
});
|
||||
|
@ -58,13 +86,15 @@ export async function getIP(proxyPort: number): Promise<string | null> {
|
|||
// https://github.com/ulixee/unblocked/blob/main/plugins/default-browser-emulator/lib/helpers/lookupPublicIp.ts
|
||||
let data: string | PromiseLike<string | null> | null;
|
||||
try {
|
||||
data = (await axios.get('http://icanhazip.com/', {
|
||||
data = (
|
||||
await axios.get("http://icanhazip.com/", {
|
||||
proxy: {
|
||||
host: '127.0.0.1',
|
||||
port: proxyPort
|
||||
host: "127.0.0.1",
|
||||
port: proxyPort,
|
||||
},
|
||||
timeout: 100000
|
||||
})).data;
|
||||
timeout: 100000,
|
||||
})
|
||||
).data;
|
||||
} catch (err) {
|
||||
logger.debug(err);
|
||||
return null;
|
||||
|
@ -74,92 +104,127 @@ export async function getIP(proxyPort: number): Promise<string | null> {
|
|||
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<void> {
|
||||
|
||||
export async function waitNewMessages(
|
||||
client: telegram.TelegramClient,
|
||||
worker: AccountInterface,
|
||||
chatEntity: telegram.Api.Chat | telegram.Api.User | string,
|
||||
idOfLastMessage: number,
|
||||
timeout = 20
|
||||
): Promise<void> {
|
||||
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<Docker.Container> {
|
||||
export async function startNewTorDocker(
|
||||
proxyPort: number,
|
||||
socksPort: number,
|
||||
controlPort: number,
|
||||
mainProgressBar: cliProgress.MultiBar,
|
||||
timeout = 200
|
||||
): Promise<Docker.Container> {
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue