Added README and LICENSE

This commit is contained in:
minicx 2022-12-14 20:24:32 +03:00
parent a3d735ba6c
commit f3087aa626
12 changed files with 1812 additions and 1092 deletions

23
LICENSE Normal file
View File

@ -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.

57
README.md Normal file
View File

@ -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

View File

@ -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
View File

@ -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();
})
});
});

View File

@ -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[];
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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
View File

@ -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;
}