Merge pull request from playground

Reviewed-on: #10
This commit is contained in:
minicx 2022-12-14 17:58:32 +00:00
commit 0c7f8c9e6c
12 changed files with 1824 additions and 1086 deletions

2
.gitignore vendored
View File

@ -10,4 +10,4 @@ data.json
settings.json settings.json
yarn-error.log yarn-error.log
yarn.lock yarn.lock
db.json1 db.json1

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,237 +1,272 @@
import {JsonDB,Config} from "node-json-db" import { JsonDB, Config } from "node-json-db";
import {FingerprintGenerator} from "fingerprint-generator" import { FingerprintGenerator } from "fingerprint-generator";
import logger from "./logger" import logger from "./logger";
import * as interfacesDB from "./interfaces/databaseInterface" import * as interfacesDB from "./interfaces/databaseInterface";
import * as interfacesSettings from "./interfaces/settingsInterface" import * as interfacesSettings from "./interfaces/settingsInterface";
import { arrayWithoutElementAtIndex } from "./utils" import { arrayWithoutElementAtIndex } from "./utils";
export class Database { export class Database {
public readonly default: interfacesDB.DatabaseInterface={ public readonly default: interfacesDB.DatabaseInterface = {
accounts:[] accounts: [],
} };
private json: JsonDB; private json: JsonDB;
constructor (){ constructor() {
this.json=new JsonDB(new Config('db.json',false,true,'/')); this.json = new JsonDB(new Config("db.json", false, true, "/"));
this.json.getData('/').then((result)=>{ this.json.getData("/").then((result) => {
if (Object.keys(result).length==0){ if (Object.keys(result).length == 0) {
this.json.push('/',this.default,true) this.json
.catch((err) => logger.error(`${err} due setting defaults`)) .push("/", this.default, true)
.then(() => { .catch((err) => logger.error(`${err} due setting defaults`))
logger.info('Setting DB to defaults...'); .then(() => {
}); logger.info("Setting DB to defaults...");
});
this.save(); this.save();
} }
}) });
} }
async findWallet(walletsFile: string): Promise<interfacesDB.faucetMailInterface | undefined>{ async findWallet(
const wallets_json=new JsonDB(new Config(walletsFile,true,true,'/')); walletsFile: string
const wallets=(await wallets_json.getData('/')); ): Promise<interfacesDB.faucetMailInterface | undefined> {
if (Object.keys(wallets).length==0){ const wallets_json = new JsonDB(
logger.error('File which you choose doesnt have anything'); new Config(walletsFile, true, true, "/")
throw new Error('File which you choose doesnt have anything') );
} const wallets = await wallets_json.getData("/");
const accounts=(await this.getUsers()); if (Object.keys(wallets).length == 0) {
let faucetWallet:interfacesDB.faucetMailInterface | undefined=undefined; logger.error("File which you choose doesnt have anything");
for (const _wallet in wallets){ throw new Error("File which you choose doesnt have anything");
let flag=false; }
if (accounts.length>0){ const accounts = await this.getUsers();
for (const account of accounts){ let faucetWallet: interfacesDB.faucetMailInterface | undefined =
if (account.faucetMail.mail.address==_wallet ){ undefined;
flag=true; for (const _wallet in wallets) {
let flag = false;
if (accounts.length > 0) {
for (const account of accounts) {
if (account.faucetMail.mail.address == _wallet) {
flag = true;
break; break;
} }
} }
} }
if (flag==false){ if (flag == false) {
faucetWallet={ faucetWallet = {
faucet: { faucet: {
username:wallets[_wallet].faucetpay.username, username: wallets[_wallet].faucetpay.username,
password:wallets[_wallet].faucetpay.password password: wallets[_wallet].faucetpay.password,
}, },
mail: { mail: {
address:_wallet, address: _wallet,
password:wallets[_wallet].mail_passphrase password: wallets[_wallet].mail_passphrase,
} },
} };
break; break;
} }
} }
return faucetWallet; return faucetWallet;
} }
async findRefferal(maxRefferals: number): Promise<number | null>{ async findRefferal(maxRefferals: number): Promise<number | null> {
let refferal: number | null=null; let refferal: number | null = null;
const accounts=(await this.getUsers()); const accounts = await this.getUsers();
if (accounts.length>0){ if (accounts.length > 0) {
for (const mainAccount of accounts){ for (const mainAccount of accounts) {
let counter = 0;
if (mainAccount.canBeRefferal == true) {
let counter=0; const _accounts = arrayWithoutElementAtIndex(
if (mainAccount.canBeRefferal==true){ accounts,
let _accounts=arrayWithoutElementAtIndex(accounts,accounts.indexOf(mainAccount)); accounts.indexOf(mainAccount)
for (const _account of _accounts){ );
for (const _account of _accounts) {
if (_account.refferal==mainAccount.telegramID){ if (_account.refferal == mainAccount.telegramID) {
counter+=1; counter += 1;
} }
} }
if (counter<maxRefferals){ if (counter < maxRefferals) {
refferal=Number(mainAccount.telegramID); refferal = Number(mainAccount.telegramID);
} }
} }
} }
} }
return refferal; return refferal;
} }
async save(){ async save() {
await this.json.save(true); await this.json.save(true);
} }
async updateUser(account:interfacesDB.AccountInterface){ async updateUser(account: interfacesDB.AccountInterface) {
const index=await this.json.getIndex("/accounts", account.phoneNumber,"phoneNumber") const index = await this.json.getIndex(
logger.debug(`Index in database is ${index} of ${account.phoneNumber}`) "/accounts",
await this.json.push(`/accounts[${index}]`,account,true); 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, async addUser(
'balance' | 'withdraws' | 'completedGroupsTasks' | 'canBeRefferal' account: Omit<
| 'browserFingerprint' | 'faucetMail'>,wallets_json: string): Promise<void>{ interfacesDB.AccountInterface,
| "balance"
| "withdraws"
| "completedGroupsTasks"
| "canBeRefferal"
| "browserFingerprint"
| "faucetMail"
>,
wallets_json: string
): Promise<void> {
const fingerprintGenerator = new FingerprintGenerator(); const fingerprintGenerator = new FingerprintGenerator();
const fingerprint=fingerprintGenerator.getFingerprint({ const fingerprint = fingerprintGenerator.getFingerprint({
devices: ['desktop'], devices: ["desktop"],
browsers: ['chrome'], browsers: ["chrome"],
}).fingerprint; }).fingerprint;
const faucet:interfacesDB.faucetMailInterface | undefined=await this.findWallet(wallets_json); const faucet: interfacesDB.faucetMailInterface | undefined =
if (faucet === undefined){ await this.findWallet(wallets_json);
logger.error('Add new faucet accounts'); if (faucet === undefined) {
throw new Error('Add new faucet accounts'); logger.error("Add new faucet accounts");
}else { throw new Error("Add new faucet accounts");
const canBeRefferal: boolean=Math.random() < 0.5; } else {
const canBeRefferal: boolean = Math.random() < 0.5;
const _account: interfacesDB.AccountInterface={
phoneNumber:account.phoneNumber, const _account: interfacesDB.AccountInterface = {
telegramID:account.telegramID, phoneNumber: account.phoneNumber,
apiID:account.apiID, telegramID: account.telegramID,
apiHash:account.apiHash, apiID: account.apiID,
password:account.password, apiHash: account.apiHash,
faucetMail:faucet, password: account.password,
stringSession:account.stringSession, faucetMail: faucet,
balance:0.0, stringSession: account.stringSession,
withdraws:[], balance: 0.0,
completedGroupsTasks:[], withdraws: [],
canBeRefferal:canBeRefferal, completedGroupsTasks: [],
refferal:account.refferal, canBeRefferal: canBeRefferal,
browserFingerprint:fingerprint refferal: account.refferal,
} browserFingerprint: fingerprint,
await this.json.push(`/accounts[]`,_account); };
await this.json.push(`/accounts[]`, _account);
} }
await this.save(); await this.save();
} }
async getUsers(): Promise<interfacesDB.AccountInterface[]>{ async getUsers(): Promise<interfacesDB.AccountInterface[]> {
try { try {
return await this.json.getObject<interfacesDB.AccountInterface[]>('/accounts'); return await this.json.getObject<interfacesDB.AccountInterface[]>(
"/accounts"
);
} catch { } catch {
return []; return [];
} }
}
}
} }
export class Settings implements interfacesSettings.settingsInterface { export class Settings implements interfacesSettings.settingsInterface {
public readonly default: interfacesSettings.settingsInterface={ public readonly default: interfacesSettings.settingsInterface = {
logLevel: 'debug', logLevel: "debug",
pararels: 2, pararels: 2,
mainCrypto: 'TRX', mainCrypto: "TRX",
minimalToWithdraw: 0.0003, minimalToWithdraw: 0.0003,
maxRefferals: 3, maxRefferals: 3,
botMessages: { botMessages: {
verification: 'To continue using this bot,', verification: "To continue using this bot,",
tasksSelector: 'Choose an option to start earning your TRX', tasksSelector: "Choose an option to start earning your TRX",
taskOver: 'Sorry, there are no new ads available.', taskOver: "Sorry, there are no new ads available.",
taskComplete: 'Success, ', taskComplete: "Success, ",
notInGroup: 'not entered the chat', notInGroup: "not entered the chat",
oldMessage: 'forwarded is old' oldMessage: "forwarded is old",
}, },
botButtons: { botButtons: {
earn: '❇️ Earn cryptocurrency', earn: "❇️ Earn cryptocurrency",
balance: '💰 Balance', balance: "💰 Balance",
withdraw: '📤 Withdraw' withdraw: "📤 Withdraw",
}, },
telegramLinks: { telegramLinks: {
botLink: '@hkearn_trx_bot', botLink: "@hkearn_trx_bot",
groupsToJoin: ['@hkearn_transactions', '@hkearn_updates'] groupsToJoin: ["@hkearn_transactions", "@hkearn_updates"],
}, },
bypassMode: false, bypassMode: false,
sleepTime: { sleepTime: {
afterDoing: [1*3600,2*3600], afterDoing: [1 * 3600, 2 * 3600],
betweenSessions: [35,70], betweenSessions: [35, 70],
}, },
shuffleAccounts: true shuffleAccounts: true,
} };
logLevel: "debug" | "info" | "error"; logLevel: "debug" | "info" | "error";
mainCrypto: "TRX"; mainCrypto: "TRX";
minimalToWithdraw: number; minimalToWithdraw: number;
maxRefferals: number; maxRefferals: number;
botMessages: { verification: string; tasksSelector: string; taskOver: string, taskComplete: string, notInGroup: string, oldMessage: string}; botMessages: {
botButtons: { earn: string; balance: string; withdraw: string; }; verification: string;
telegramLinks: { botLink: string; groupsToJoin: string[]; }; tasksSelector: string;
bypassMode: boolean taskOver: string;
pararels: number taskComplete: string;
notInGroup: string;
oldMessage: string;
};
botButtons: { earn: string; balance: string; withdraw: string };
telegramLinks: { botLink: string; groupsToJoin: string[] };
bypassMode: boolean;
pararels: number;
sleepTime: { sleepTime: {
afterDoing: number[], afterDoing: number[];
betweenSessions: number[], betweenSessions: number[];
} };
shuffleAccounts: boolean shuffleAccounts: boolean;
private json: JsonDB; private json: JsonDB;
constructor (){ constructor() {
this.json=new JsonDB(new Config('settings.json',false,true,'/')); this.json = new JsonDB(new Config("settings.json", false, true, "/"));
this.json.getObject<interfacesSettings.settingsInterface>('/').then((result) => { this.json
if (Object.keys(result).length==0){ .getObject<interfacesSettings.settingsInterface>("/")
logger.warn('Setup config first...'); .then((result) => {
if (Object.keys(result).length == 0) {
this.json.push('/',this.default,true) logger.warn("Setup config first...");
.catch((err)=> logger.error(`${err} due setting defaults`))
.then(()=>{ this.json
this.json.save(true).then(()=>{ .push("/", this.default, true)
throw new Error("Config doesn't setup"); .catch((err) =>
}) logger.error(`${err} due setting defaults`)
}); )
} else { .then(() => {
mainLoop: this.json.save(true).then(() => {
for (const setting of Object.keys(this.default)){ throw new Error("Config doesn't setup");
if (result[setting]===undefined || typeof(result[setting])!=typeof(this.default[setting])){ });
this[setting]=this.default[setting]; });
logger.warn(`Setting '${setting}' corrupted or undefined. Check out it...`) } else {
} else { mainLoop: for (const setting of Object.keys(this.default)) {
if (typeof(result[setting])=='object'){ if (
for (const attr of Object.keys(this.default[setting])){ result[setting] === undefined ||
if (Object.keys(result[setting]).indexOf(attr)==-1){ typeof result[setting] !=
this[setting] = this.default[setting]; typeof this.default[setting]
logger.warn(`Setting '${setting}' corrupted. Check out it...`) ) {
continue mainLoop; this[setting] = this.default[setting];
logger.warn(
`Setting '${setting}' corrupted or undefined. Check out it...`
);
} else {
if (typeof result[setting] == "object") {
for (const attr of Object.keys(
this.default[setting]
)) {
if (
Object.keys(result[setting]).indexOf(
attr
) == -1
) {
this[setting] = this.default[setting];
logger.warn(
`Setting '${setting}' corrupted. Check out it...`
);
continue mainLoop;
}
} }
} }
this[setting] = result[setting];
} }
this[setting]=result[setting];
} }
logger.level = this.logLevel;
} }
logger.level=this.logLevel; });
} }
});
}
} }
const database=new Database(); const database = new Database();
const settings=new Settings(); const settings = new Settings();
export {database,settings} export { database, settings };

836
index.ts

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,35 @@
import {Fingerprint} from "fingerprint-generator" import { Fingerprint } from "fingerprint-generator";
export interface faucetMailInterface { export interface faucetMailInterface {
faucet: { faucet: {
username: string, username: string;
password: string password: string;
} };
mail: { mail: {
address: string, address: string;
password: string password: string;
} };
} }
export interface AccountCompletedGroupsTasksInterface { export interface AccountCompletedGroupsTasksInterface {
timeToLeave: number, timeToLeave: number;
groupID: string groupID: string;
} }
export interface AccountWithdrawInterface { export interface AccountWithdrawInterface {}
}
export interface AccountInterface { export interface AccountInterface {
phoneNumber: string, phoneNumber: string;
telegramID: number, telegramID: number;
apiID: number, apiID: number;
apiHash: string, apiHash: string;
password: string, password: string;
faucetMail: faucetMailInterface, faucetMail: faucetMailInterface;
stringSession: string, stringSession: string;
balance: number, balance: number;
withdraws:AccountWithdrawInterface[], withdraws: AccountWithdrawInterface[];
completedGroupsTasks:AccountCompletedGroupsTasksInterface[], completedGroupsTasks: AccountCompletedGroupsTasksInterface[];
canBeRefferal: boolean, canBeRefferal: boolean;
browserFingerprint:Fingerprint, browserFingerprint: Fingerprint;
refferal:number | null refferal: number | null;
} }
export interface DatabaseInterface { export interface DatabaseInterface {
accounts: AccountInterface[] accounts: AccountInterface[];
} }

View File

@ -1,22 +1,20 @@
import * as telegram from 'telegram'; import * as telegram from "telegram";
import {AccountInterface} from './databaseInterface' import { AccountInterface } from "./databaseInterface";
export interface prevTaskInterface { export interface prevTaskInterface {
task: telegram.Api.Message, task: telegram.Api.Message;
lastMessage:telegram.Api.Message lastMessage: telegram.Api.Message;
} }
export interface portsInterface { export interface portsInterface {
http: number, http: number;
socks: number, socks: number;
control:number, control: number;
minerPort?:number minerPort?: number;
} }
export interface usedIPInterface{ export interface usedIPInterface {
worker: AccountInterface, worker: AccountInterface;
usedIps: string[], usedIps: string[];
current: string current: string;
} }

View File

@ -1,37 +1,33 @@
export interface settingsInterface { export interface settingsInterface {
logLevel: "debug" | "info" | "error";
logLevel: 'debug' | 'info' | 'error', pararels: number;
pararels: number, mainCrypto: "TRX";
mainCrypto: 'TRX', minimalToWithdraw: number;
minimalToWithdraw: number, maxRefferals: number;
maxRefferals: number,
// to find // to find
botMessages: { botMessages: {
verification: string, verification: string;
tasksSelector: string, tasksSelector: string;
taskOver: string, taskOver: string;
taskComplete: string, taskComplete: string;
notInGroup: string, notInGroup: string;
oldMessage: string oldMessage: string;
} };
// to send // to send
botButtons:{ botButtons: {
earn: string, earn: string;
balance: string, balance: string;
withdraw: string withdraw: string;
}, };
// to join // to join
telegramLinks:{ telegramLinks: {
botLink: string, botLink: string;
groupsToJoin: string[] groupsToJoin: string[];
};
},
sleepTime: { sleepTime: {
afterDoing: number[], afterDoing: number[];
betweenSessions: number[] betweenSessions: number[];
}, };
shuffleAccounts: boolean shuffleAccounts: boolean;
bypassMode: boolean bypassMode: boolean;
} }

View File

@ -1,18 +1,19 @@
import winston = require("winston") import winston = require("winston");
const logger=winston.createLogger({ const logger = winston.createLogger({
level: 'debug', level: "debug",
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize(), winston.format.colorize(),
winston.format.printf((info)=>{ winston.format.printf((info) => {
return `${new Date().toLocaleTimeString()} | ${info.level} - ${info.message} ` return `${new Date().toLocaleTimeString()} | ${info.level} - ${
info.message
} `;
}) })
), ),
transports: [ transports: [
new winston.transports.Console(), new winston.transports.Console(),
new winston.transports.File({ filename: 'errors.log', level: 'error' }), new winston.transports.File({ filename: "errors.log", level: "error" }),
new winston.transports.File({ filename: 'info.log' }), new winston.transports.File({ filename: "info.log" }),
], ],
}); });
export default logger; export default logger;

View File

@ -19,7 +19,7 @@
}, },
"name": "hk_bot", "name": "hk_bot",
"version": "0.0.1", "version": "0.0.1",
"description": "test", "description": "Script which allow earn some crypto via telegram",
"main": "/build/index.js", "main": "/build/index.js",
"devDependencies": { "devDependencies": {
"@types/cli-progress": "^3.11.0", "@types/cli-progress": "^3.11.0",
@ -35,7 +35,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://notabug.org/minicx/hk_bot.git" "url": "https://git.disroot.org/minicx/hk_bot.git"
}, },
"keywords": [ "keywords": [
"telegram", "telegram",
@ -44,5 +44,5 @@
"crypto" "crypto"
], ],
"author": "minicx", "author": "minicx",
"license": "ISC" "license": "MIT"
} }

189
utils.ts
View File

@ -1,51 +1,83 @@
import Docker from "dockerode"; import Docker from "dockerode";
import logger from "./logger"; import logger from "./logger";
import {database as db,settings} from './database'; import { settings } from "./database";
// import Hero from "@ulixee/hero"; // import Hero from "@ulixee/hero";
// import Miner from "@ulixee/miner"; // import Miner from "@ulixee/miner";
import { sleep } from "telegram/Helpers"; import { sleep } from "telegram/Helpers";
import { AccountInterface } from "./interfaces/databaseInterface"; import { AccountInterface } from "./interfaces/databaseInterface";
import * as telegram from 'telegram'; import * as telegram from "telegram";
import axios from "axios"; import axios from "axios";
import cliProgress from "cli-progress" import cliProgress from "cli-progress";
export class CaptchaError extends Error{} import { isNull, isUndefined } from "lodash";
export class NoNewMessagesError extends Error{} export class CaptchaError extends Error {}
export class DockerIsBrockenError extends Error{} export class NoNewMessagesError extends Error {}
export class DockerIsBrockenError extends Error {}
export function randomAB(a: number, b: number) { export function randomAB(a: number, b: number) {
return Math.floor(Math.random() * (b - a + 1) + a); return Math.floor(Math.random() * (b - a + 1) + a);
} }
export async function isBannedByClient(client: telegram.TelegramClient, username: string): Promise<boolean> { export async function isBannedByClient(
const blockedUsers = (await client.invoke(new telegram.Api.contacts.GetBlocked({ limit: 2147483647 }))).users as telegram.Api.User[]; 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) { for (const blockedUser of blockedUsers) {
if (blockedUser.username !== undefined && blockedUser.username == username.replace('@', '')) { if (
blockedUser.username !== undefined &&
blockedUser.username == username.replace("@", "")
) {
return true; return true;
} }
} }
return false; return false;
} }
export async function getMessagesByEntity(client: telegram.TelegramClient, chatEntity: telegram.Api.Chat | telegram.Api.User | string, entity: telegram.Api.User | string, params = {}) { export async function getMessagesByEntity(
let messages = new telegram.helpers.TotalList<telegram.Api.Message>; 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) { if (entity instanceof telegram.Api.User) {
for (const message of await client.getMessages(chatEntity, params)) { 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); messages.push(message);
} }
} }
} else { } else {
for (const message of await client.getMessages(chatEntity, params)) { for (const message of await client.getMessages(chatEntity, params)) {
if ((message.sender as telegram.Api.User).username!.includes(entity.replace('@', ''))) { if (
messages.push(message); 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; return messages;
} }
export function arrayWithoutElementAtIndex(arr: AccountInterface[] | [], index: number) { export function arrayWithoutElementAtIndex(
arr: AccountInterface[] | [],
index: number
) {
return arr.filter(function (value, arrIndex) { return arr.filter(function (value, arrIndex) {
return index !== arrIndex; return index !== arrIndex;
}); });
@ -54,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 // https://github.com/ulixee/unblocked/blob/main/plugins/default-browser-emulator/lib/helpers/lookupPublicIp.ts
let data: string | PromiseLike<string | null> | null; let data: string | PromiseLike<string | null> | null;
try { try {
data = (await axios.get('http://icanhazip.com/', { data = (
proxy: { await axios.get("http://icanhazip.com/", {
host: '127.0.0.1', proxy: {
port: proxyPort host: "127.0.0.1",
}, port: proxyPort,
timeout: 100000 },
})).data; timeout: 100000,
})
).data;
} catch (err) { } catch (err) {
logger.debug(err); logger.debug(err);
return null; return null;
@ -70,92 +104,127 @@ export async function getIP(proxyPort: number): Promise<string | null> {
return null; return null;
} }
return await data; 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(); const start_time = new Date();
while ((await getMessagesByEntity(client, chatEntity, chatEntity as telegram.Api.User | string, { minId: idOfLastMessage, limit: 2147483647 })).length == 0) { while (
if ((+(new Date()) - +start_time) / 1000 >= timeout) { (
logger.error(`${worker.phoneNumber} | Bot didnt answer for ${timeout}s`); await getMessagesByEntity(
throw new NoNewMessagesError('Is bot working?'); 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`); 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; timeout *= 2;
let docker = new Docker({ socketPath: '/var/run/docker.sock' }); const docker = new Docker({ socketPath: "/var/run/docker.sock" });
let isPulled = false; let isPulled = false;
mainLoop: for (const image of await docker.listImages()) { mainLoop: for (const image of await docker.listImages()) {
const tags = image.RepoTags; const tags = image.RepoTags;
if (tags !== undefined) if (tags !== undefined)
for (const repoTag of tags) { for (const repoTag of tags) {
if (repoTag.search('dperson/torproxy:latest') != -1) { if (repoTag.search("dperson/torproxy:latest") != -1) {
isPulled = true; isPulled = true;
break mainLoop; break mainLoop;
} }
} }
} }
if (isPulled != true) { if (isPulled != true) {
await docker.pull('dperson/torproxy:latest'); await docker.pull("dperson/torproxy:latest");
} }
// bugy shit // bugy shit
const options: Docker.ContainerCreateOptions = { const options: Docker.ContainerCreateOptions = {
Image: 'dperson/torproxy', Image: "dperson/torproxy",
Env: [ Env: ["PASSWORD=qwerty", "LOCATION=US", "TOR_NewCircuitPeriod=50"],
"PASSWORD=qwerty",
"LOCATION=US",
"TOR_NewCircuitPeriod=50",
],
ExposedPorts: {}, ExposedPorts: {},
HostConfig: { HostConfig: {
PortBindings: { PortBindings: {
'8118/tcp': [{ "8118/tcp": [
HostPort: `${proxyPort}` {
}], HostPort: `${proxyPort}`,
'9050/tcp': [{ },
HostPort: `${socksPort}` ],
}], "9050/tcp": [
'9051/tcp': [{ {
HostPort: `${controlPort}` HostPort: `${socksPort}`,
}] },
} ],
"9051/tcp": [
{
HostPort: `${controlPort}`,
},
],
},
}, },
Healthcheck: { Healthcheck: {
Interval: 2 * 1000000000, Interval: 2 * 1000000000,
Timeout: 50 * 1000000000, Timeout: 50 * 1000000000,
StartPeriod: 50 * 1000000000, StartPeriod: 50 * 1000000000,
// Test:['CMD_SHELL',`curl -sx localhost:8118 'https://check.torproject.org/' | grep -qm1 Congratulations`] // Test:['CMD_SHELL',`curl -sx localhost:8118 'https://check.torproject.org/' | grep -qm1 Congratulations`]
} },
}; };
const container = await docker.createContainer(options); const container = await docker.createContainer(options);
await container.start(); await container.start();
const progressBar = mainProgressBar.create(timeout / 2, 0, { status: `Starting docker${(settings.logLevel == 'debug') ? ` ${proxyPort} ${socksPort} ${controlPort}` : ''}` }); const progressBar = mainProgressBar.create(timeout / 2, 0, {
while ((await container.inspect())!.State.Health!.Status != 'healthy') { 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; const state = (await container.inspect())!.State.Health!.Status;
if (progressBar.getProgress() >= timeout) { if (progressBar.getProgress() >= timeout) {
await container.kill(); await container.kill();
progressBar.update(timeout / 2, { status: 'Failed' }); progressBar.update(timeout / 2, { status: "Failed" });
progressBar.stop(); progressBar.stop();
throw new DockerIsBrockenError(`Docker ${container.id} is broken`); throw new DockerIsBrockenError(`Docker ${container.id} is broken`);
} }
if (state == 'unhealthy') { if (state == "unhealthy") {
await container.kill(); await container.kill();
progressBar.update(timeout / 2, { status: 'Docker is unhealthy...' }); progressBar.update(timeout / 2, {
status: "Docker is unhealthy...",
});
progressBar.stop(); progressBar.stop();
return await startNewTorDocker(proxyPort, socksPort, controlPort, mainProgressBar, timeout / 2); return await startNewTorDocker(
proxyPort,
socksPort,
controlPort,
mainProgressBar,
timeout / 2
);
} }
progressBar.increment(); progressBar.increment();
await sleep(2000); await sleep(2000);
} }
progressBar.update(0, { status: 'Started' }); progressBar.update(0, { status: "Started" });
progressBar.stop(); progressBar.stop();
return container; return container;
} }