hk_bot/index.ts

328 lines
12 KiB
TypeScript

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} from './utils';
import {connect, disconnect, tor} from "node-tor-control";
import Miner from '@ulixee/miner';
import Hero from '@ulixee/hero';
import {ipInterface} from "./interfaces/otherInterfaces"
import { vertification } from './automatization';
const addAccounts: ()=>Promise<void>=async ()=>{
let apiId: number=0
let apiHash: string= '';
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?'
});
if (usePrevData.confirmed==true){
apiId=accounts[accounts.length-1].apiID;
apiHash=accounts[accounts.length-1].apiHash;
}
}
if (apiId==0 && apiHash==''){
const api=await prompt([
{
type:'number',
name:'apiId',
message:'ApiId?'
},
{
type:'text',
name:'apiHash',
message:'ApiHash?'
}
]);
apiId=Number(api.apiId);
apiHash=api.apiHash;
}
let jsonFiles: prompt.Choice[]=[];
fs.readdirSync("./").forEach((file)=>{
if (file.search('.json')!=-1 && file!='db.json' && file!='settings.json'){
jsonFiles.push(
{
title: file,
description:'json file',
value:file,
}
);
}
});
const walletsFile=(await prompt({
type: 'select',
name: 'file',
message: 'Choose wallets json file',
choices: jsonFiles
})).file
await db.findWallet(walletsFile);
mainLoop:
while (true){
accounts=await db.getUsers();
const answers=await prompt([
{
type:'text',
name:'number',
message:'Phone number?'
},
{
type:'text',
name:'password',
message:'2FA Password?'
}
]);
for (const account of accounts){
if (account.phoneNumber==answers.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'});
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(),
onError: (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));
if (account instanceof telegram.Api.User ){
await db.addUser({
password: answers.password,
phoneNumber: answers.number,
apiHash: apiHash,
telegramID: Number(account.id),
apiID: apiId,
stringSession: String(client.session.save()),
refferal: await db.findRefferal(settings.maxRefferals)
},walletsFile)
} else {
logger.error("Wrong type of account?");
}
} else {
logger.error('Client not authorized');
}
if ((await prompt({
type: 'confirm',
name: 'continue',
message: 'continue?'
})).continue!=true){
return;
}
}
}
const farm: ()=>Promise<void>=async ()=>{
const proccesGroup=async (workers_group:AccountInterface[],ports: number[])=>{
const container=await startNewTorDocker(ports[0],ports[1],ports[2]);
const ip: ipInterface={
prev:[''],
current:''
}
for (const worker of workers_group){
logger.debug(`Current worker:${worker.phoneNumber}\nBalance:${worker.balance}`);
while (ip.prev.indexOf(ip.current)!=-1){
const torConnection = await connect({
host: '127.0.0.1',
port:ports[2],
password: 'qwerty',
});
await tor.signalNewNYM(torConnection);
ip.current=(await getIP(ports[0]))!;
}
ip.prev.push(ip.current)
const miner = new Miner();
await miner.listen({port: ports[-1]});
const fingerprint=worker.browserFingerprint
let hero: Omit<Hero, "then">;
while (true){
try {
hero = await new Hero({
userProfile:{
deviceProfile: {
deviceMemory:fingerprint.navigator.deviceMemory,
}
},
name:`${worker.telegramID}`,
connectionToCore: { host:`ws://${await miner.address}` },
disableDevtools: true, // to bypass hk site
showChrome:true, // to debug
userAgent:fingerprint.navigator.userAgent,
viewport:fingerprint.screen,
locale:fingerprint.navigator.language,
upstreamProxyUrl:`socks5://127.0.0.1:${ports[1]}`,
});
break;
} catch (err){
logger.warn(`Some error due openning Hero. Trying again...\n${err}`);
continue
}
}
const client=new telegram.TelegramClient(
new telegram.sessions.StringSession(worker.stringSession),
worker.apiID,
worker.apiHash,
{deviceModel:'Samsung SM-G980',connectionRetries: 5,systemVersion: '10'}
);
client.setLogLevel(LogLevel.ERROR);
await client.connect();
if ((await client.checkAuthorization())==false){
logger.error(`Account ${worker.phoneNumber} is not authorizated`);
continue
} else {
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
const botEntity=await client.getEntity(settings.telegramLinks.botLink) as telegram.Api.User;
for (const chat of settings.telegramLinks.groupsToJoin){
try{
await client.invoke(new telegram.Api.channels.GetParticipant({channel:chat,participant:'me'}));
} catch(err){
if (err.code==400){
await client.invoke(new telegram.Api.channels.JoinChannel({channel:chat}));
} else{
logger.error(`${worker.phoneNumber} | Unknown error due GetParticipant`)
throw err;
}
}
}
if ((await getMessagesByEntity(client,botEntity,botEntity)).length==0){
if (worker.refferal!==null){
await client.sendMessage(botEntity,{message:`/start ${worker.refferal}`});
logger.debug(`${worker.phoneNumber} | First start of ${botEntity.username} via refferal link of ${worker.refferal}`);
}else {
await client.sendMessage(botEntity,{message:`/start`});
logger.debug(`${worker.phoneNumber} | First start of ${botEntity.username}`);
}
}
logger.info(`${worker.phoneNumber} | Sending earn message...`);
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,
// search: settings.botMessages.tasksSelector,
}))[0];
if (tasksSelector.message.includes(settings.botMessages.verification)==true){
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,{
minId:requestTasksMessage.id,
// search: settings.botMessages.tasksSelector,
}))[0];
}
await hero.close();
await miner.close();
}
}
container.kill();
}
const workers=await db.getUsers();
let workers_groups: Array<AccountInterface[]>=[];
for (let i=0;i!=settings.pararels+1;i+=settings.pararels){
const _workers=workers.slice(i,i+settings.pararels);
if (_workers.length!=0){
workers_groups.push(_workers);
} else {
break;
}
}
if (workers_groups.length!=Math.ceil(workers.length/settings.pararels)){
logger.warn(`There is strange thing with workers_group\n${workers_groups.length} ${Math.ceil(workers.length/settings.pararels)}`);
}
let pararels: Promise<void>[] =[]
let _ports=await findFreePorts(settings.pararels*4);
for (let i=0;i!=settings.pararels;i++){
}
for (let i=0;i!=workers_groups.length;i++){
pararels.push(proccesGroup(workers_groups[i],_ports.slice(i*4,i*4+4)));
}
await Promise.all(pararels);
}
// menu
(async ()=> {
mainLoop:
while (true){
const answer=await prompt({
type: 'select',
name: 'menu',
message: 'Choose action',
choices: [
((await db.getUsers()).length>0) ? { title: 'Start',description: 'Starting farm', value: 'start' } : { title: 'Start',description: 'Add accounts first...', value: 'start' ,disabled: true},
{ title: 'Add accounts', description: 'Adds accounts', value: 'addAccounts' },
{ title: 'Check balances', value: 'checkBalances', disabled: true },
{ title: 'Withdraw', value: 'withdraw', disabled: true },
{ title: 'Exit',description: 'You realy dont know what it mean?'}
]
})
switch (answer.menu) {
case 'addAccounts':
await addAccounts();
break;
case 'start':
while (true){
try{
await farm();
} catch (err){
logger.error(`Unknown error\n${err}`)
break;
}
}
break;
default:
logger.info('Bye bye');
break mainLoop;
}
}
})();