hk_bot/automatization.ts

933 lines
38 KiB
TypeScript

import Hero from "@ulixee/hero";
import * as telegram from "telegram";
import { sleep } from "telegram/Helpers";
import { AccountInterface } from "./interfaces/databaseInterface";
import { prevTaskInterface } from "./interfaces/otherInterfaces";
import logger from "./logger";
import {
CaptchaError,
getMessagesByEntity,
NoNewMessagesError,
waitNewMessages,
} from "./utils";
import { settings } from "./database";
import { isNull } from "lodash";
export const vertification = async function (hero: Hero, url: string) {
await hero.goto(url, { timeoutMs: 2_000_000 });
await hero.waitForLoad("AllContentLoaded", { timeoutMs: 1180_000 });
const captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
if (captchaButton != null) {
let verify = hero.document.querySelector("body > section > h2");
while (
isNull(verify) != true &&
(await verify.textContent)!.includes("All right!") == false
) {
const isCaptchaPassed = hero.document.querySelector(
"input[id='recaptcha-token']"
);
if (
isNull(isCaptchaPassed) ||
(await isCaptchaPassed.$isVisible) == false
) {
await hero.interact({
click: {
element: captchaButton,
verification: "exactElement",
},
});
await sleep(5000);
verify = hero.document.querySelector("body > section > h2");
} else {
logger.error("Captcha detected");
throw new CaptchaError("Auhtung captcha detected");
}
}
} else {
throw new Error("Cant find captcha button");
}
};
export const doSitesTasks = async function (
client: telegram.TelegramClient,
worker: AccountInterface,
hero: Hero,
botEntity: telegram.Api.Chat | telegram.Api.User,
tasksSelector: telegram.Api.Message
) {
const taskSitesButton = tasksSelector.buttons![1][0];
const prevTask: prevTaskInterface = {
task: tasksSelector,
lastMessage: tasksSelector,
};
mainLoop: while (true) {
await sleep(2000);
await taskSitesButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const task = (
await client.getMessages(botEntity, {
minId: prevTask.lastMessage.id,
// search: (await settings.botMessages()).tasksSelector,
})
)[0];
if (task.buttonCount == 2) {
logger.debug(`New ad task | ${worker.phoneNumber}`);
const urlButton = task.buttons![0][0];
const skipButton = task.buttons![0][1];
await hero.goto(urlButton.url!, { timeoutMs: 2_000_000 });
await hero.waitForLoad("AllContentLoaded", { timeoutMs: 1180_000 });
let captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
if (
isNull(captchaButton) &&
(await hero.activeTab.url).includes("hkbots")
) {
if (prevTask.task.message == task.message) {
logger.warn(
`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`
);
await skipButton.click({ sharePhone: false });
await waitNewMessages(client, worker, botEntity, task.id);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
} else {
prevTask.task = task;
logger.warn(
`Captcha isnt detected... | ${worker.phoneNumber}`
);
}
} else {
prevTask.task = task;
if ((await hero.activeTab.url).includes("hkbots")) {
if ((await captchaButton.$isClickable) != true) {
// timer page
logger.warn(`Found timer... | ${worker.phoneNumber}`);
if (settings.bypassMode == true) {
logger.warn(
`Bypassing timer... | ${worker.phoneNumber}`
);
try {
await hero.executeJs(
"document.getElementById('form').setAttribute('style', '')"
);
} catch (err) {
logger.error(`Something went wrong due bypass`);
}
} else {
while (
hero.document.querySelector("i[id='timer']") !=
null &&
(await captchaButton.$isClickable) != true
) {
await sleep(1000);
}
}
}
const now = new Date();
while ((await hero.activeTab.url) == urlButton.url!) {
if ((+new Date() - +now) / 1000 > 2 * 60) {
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
task.id
);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
logger.warn(
`Anomaly activity in browser. Please checkout`
);
continue mainLoop;
} else {
const isCaptchaPassed = hero.document.querySelector(
"input[id='recaptcha-token']"
);
if (
isNull(isCaptchaPassed) ||
(await isCaptchaPassed.$isVisible) == false
) {
if (await captchaButton.$isClickable) {
try {
await hero.interact({
click: {
element: captchaButton,
verification: "exactElement",
},
});
} catch (err) {
logger.warn(
`Some error due clicking | ${worker.phoneNumber}`
);
continue mainLoop;
}
}
await sleep(1000);
captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
} else {
logger.error(
`Captcha detected | ${worker.phoneNumber}`
);
throw new Error("Captcha detected");
}
}
}
}
await waitNewMessages(client, worker, botEntity, task.id);
const afterTask: telegram.Api.Message = (
await client.getMessages(botEntity, {
minId: task.id,
limit: 100,
})
).filter((value) => {
return value.message.includes(
settings.botMessages.taskComplete
);
})[0];
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
if (afterTask != null) {
// need update
if (
afterTask.message.includes(
settings.botMessages.taskComplete
) == true
) {
logger.info(
`Site task complete | ${worker.phoneNumber}`
);
continue;
}
}
}
} else if (
task.message.includes(settings.botMessages.taskOver) == true
) {
logger.info(`Ad tasks completed | ${worker.phoneNumber}`);
break;
} else {
logger.error(`Check out last message of ${worker.phoneNumber}`);
throw new Error(`Check out last message of ${worker.phoneNumber}`);
}
}
};
export const doChatsTasks = async function (
client: telegram.TelegramClient,
worker: AccountInterface,
hero: Hero,
botEntity: telegram.Api.Chat | telegram.Api.User,
tasksSelector: telegram.Api.Message
) {
const taskChatsButton = tasksSelector.buttons![1][1];
const prevTask: prevTaskInterface = {
task: tasksSelector,
lastMessage: tasksSelector,
};
mainLoop: while (true) {
await sleep(2000);
await taskChatsButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const task = (
await client.getMessages(botEntity, {
minId: prevTask.lastMessage.id,
// search: (await settings.botMessages()).tasksSelector,
})
)[0];
if (task.buttonCount == 3) {
logger.info(`New chat task | ${worker.phoneNumber}`);
const urlButton = task.buttons![0][0];
const confirmButton = task.buttons![0][1];
const skipButton = task.buttons![0][2];
let groupLink = "";
if (urlButton.url?.includes("hkbot") == true) {
await hero.goto(urlButton.url, { timeoutMs: 2_000_000 });
await hero.waitForLoad("AllContentLoaded", {
timeoutMs: 1180_000,
});
let captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
if (isNull(captchaButton)) {
if (prevTask.task.message == task.message) {
logger.warn(
`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`
);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
task.id
);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
} else {
prevTask.task = task;
prevTask.lastMessage = task;
logger.warn(
`Captcha isnt detected... | ${worker.phoneNumber}`
);
}
continue mainLoop;
}
const now = new Date();
while (
captchaButton != null &&
(await hero.activeTab.url) == urlButton.url!
) {
if ((+new Date() - +now) / 1000 > 2 * 60) {
if ((await captchaButton.$isClickable) == false) {
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
task.id
);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
continue mainLoop;
}
logger.warn(
`Anomaly activity in browser. Please checkout`
);
await hero.reload();
}
const isCaptchaPassed = hero.document.querySelector(
"input[id='recaptcha-token']"
);
if (
isCaptchaPassed == null ||
(await isCaptchaPassed.$isVisible) == false
) {
if (await captchaButton.$isClickable) {
try {
await hero.interact({
click: {
element: captchaButton,
verification: "exactElement",
},
});
} catch (err) {
logger.warn(
`Some error due clicking | ${worker.phoneNumber}`
);
continue mainLoop;
}
}
await sleep(1000);
captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
} else {
logger.error("Captcha detected");
throw new CaptchaError("Auhtung captcha detected");
}
}
groupLink = await hero.url;
} else {
groupLink = urlButton.url!;
}
// https://gram.js.org/tl/messages/GetFullChat
// hash checking
let group: telegram.Api.Channel | undefined;
if (
!/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)([\w-]+)/i.test(
groupLink
)
) {
groupLink = groupLink.replace(
/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i,
""
);
try {
group = (
(await client.invoke(
new telegram.Api.channels.JoinChannel({
channel: groupLink,
})
)) as telegram.Api.Updates
).chats[0] as telegram.Api.Channel;
} catch (err: unknown) {
if (err instanceof telegram.errors.RPCError) {
switch (err.errorMessage) {
case "CHANNELS_TOO_MUCH":
logger.warn(
`Too much groups | ${worker.phoneNumber}`
);
return;
case "USER_ALREADY_PARTICIPANT":
logger.warn(
`Already in group | ${worker.phoneNumber}`
);
group = (
await client.invoke(
new telegram.Api.channels.GetChannels({
id: [groupLink],
})
)
)[0];
break;
default:
logger.warn(
`Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}`
);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
task.id
);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
continue mainLoop;
}
}
}
} else {
// hash
groupLink = groupLink.replace(
/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\/(joinchat\/|\+)/i,
""
);
try {
group = (
(await client.invoke(
new telegram.Api.messages.ImportChatInvite({
hash: groupLink,
})
)) as telegram.Api.Updates
).chats[0] as telegram.Api.Channel;
} catch (err: unknown) {
if (err instanceof telegram.errors.RPCError) {
switch (err.errorMessage) {
case "CHANNELS_TOO_MUCH":
logger.warn(
`Too much groups | ${worker.phoneNumber}`
);
return;
case "USER_ALREADY_PARTICIPANT":
logger.warn(
`Already in group | ${worker.phoneNumber}`
);
group = (
(await client.invoke(
new telegram.Api.messages.CheckChatInvite(
{
hash: groupLink,
}
)
)) as telegram.Api.ChatInviteAlready
).chat as telegram.Api.Channel;
break;
default:
logger.warn(
`Something wrong with chat ${err.errorMessage} | ${worker.phoneNumber}`
);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
task.id
);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
continue mainLoop;
}
}
}
}
await confirmButton.click({ sharePhone: false });
await waitNewMessages(client, worker, botEntity, task.id);
const afterTask = (
await client.getMessages(botEntity, {
minId: task.id,
limit: 100,
})
).filter((value) => {
if (
value.message.includes(settings.botMessages.notInGroup) ||
value.message.includes(settings.botMessages.taskComplete)
) {
return true;
} else {
return false;
}
})[0];
const lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
})
)[0];
prevTask.task = task;
prevTask.lastMessage =
lastMessage !== undefined ? lastMessage : afterTask;
if (
afterTask.message.includes(settings.botMessages.taskComplete) ==
true
) {
worker.completedGroupsTasks.push({
timeToLeave:
+new Date() +
Number(afterTask.message.replace(/\D/g, "")) *
3600 *
1_000,
groupID: await client.getPeerId(group!),
});
logger.info(`Chat task complete | ${worker.phoneNumber}`);
continue;
} else if (
afterTask.message.includes(settings.botMessages.notInGroup) ==
true
) {
logger.warn(`User joined but hk says not. Skipping...`);
await skipButton.click({ sharePhone: false });
await waitNewMessages(client, worker, botEntity, task.id);
prevTask.task = task;
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: task.id,
// search: (await settings.botMessages()).tasksSelector,
})
)[0];
worker.completedGroupsTasks.push({
timeToLeave: 1,
groupID: await client.getPeerId(group!),
});
} else {
logger.debug(`Anomaly | ${worker.phoneNumber}`);
logger.debug(task.message);
}
} else if (
task.message.includes(settings.botMessages.taskOver) == true
) {
logger.info(`Chats tasks completed | ${worker.phoneNumber}`);
break;
} else {
logger.error(`Check out last message of ${worker.phoneNumber}`);
throw new Error(`Check out last message of ${worker.phoneNumber}`);
}
}
};
export const doBotTasks = async function (
client: telegram.TelegramClient,
worker: AccountInterface,
hero: Hero,
botEntity: telegram.Api.Chat | telegram.Api.User,
tasksSelector: telegram.Api.Message
) {
const taskBotsButton = tasksSelector.buttons![1][2];
const prevTask: prevTaskInterface = {
task: tasksSelector,
lastMessage: tasksSelector,
};
mainLoop: while (true) {
await sleep(2000);
await taskBotsButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
let task: telegram.Api.Message;
[prevTask.lastMessage, task] = await client.getMessages(botEntity, {
minId: prevTask.lastMessage.id,
limit: 2,
});
if (task === undefined) {
task = prevTask.lastMessage;
}
if (task.buttonCount == 3) {
logger.info(`New bot task | ${worker.phoneNumber}`);
const urlButton = task.buttons![0][0];
const skipButton = task.buttons![0][1];
let botLink = "@";
if (urlButton.url?.includes("hkbot") == true) {
await hero.goto(urlButton.url, { timeoutMs: 2_000_000 });
await hero.waitForLoad("AllContentLoaded", {
timeoutMs: 1180_000,
});
let captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
if (isNull(captchaButton)) {
if (prevTask.task.message == task.message) {
logger.warn(
`Same tasks detected on ${worker.phoneNumber}... Skipping due captcha isnt detected......`
);
await skipButton.click({ sharePhone: false });
} else {
logger.warn(
`Captcha isnt detected... | ${worker.phoneNumber}`
);
}
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const cancelMessage = await client.sendMessage(botEntity, {
message: "/cancel",
});
await waitNewMessages(
client,
worker,
botEntity,
cancelMessage.id
);
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
continue mainLoop;
}
const now = new Date();
while (
captchaButton != null &&
(await hero.activeTab.url) == urlButton.url!
) {
if ((+new Date() - +now) / 1000 > 2 * 60) {
if ((await captchaButton.$isClickable) == false) {
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const cancelMessage = await client.sendMessage(
botEntity,
{ message: "/cancel" }
);
await waitNewMessages(
client,
worker,
botEntity,
cancelMessage.id
);
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
continue mainLoop;
}
logger.warn(
`Anomaly activity in browser. Please checkout`
);
await hero.reload();
}
const isCaptchaPassed = hero.document.querySelector(
"input[id='recaptcha-token']"
);
if (
isCaptchaPassed == null ||
(await isCaptchaPassed.$isVisible) == false
) {
if (await captchaButton.$isClickable) {
try {
await hero.interact({
click: {
element: captchaButton,
verification: "exactElement",
},
});
} catch (err) {
logger.warn(
`Some error due clicking | ${worker.phoneNumber}`
);
continue mainLoop;
}
}
await sleep(1000);
captchaButton = hero.document.querySelector(
"button.g-recaptcha.btn.btn-primary"
);
} else {
logger.error("Captcha detected");
throw new CaptchaError("Auhtung captcha detected");
}
}
botLink += (await hero.url)
.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i, "")!
.replace(/(?:\?start=)[A-Za-z0-9]+/i, "")!;
} else {
botLink += urlButton.url
?.replace(/(^\w+:|^)\/\/(?:t|telegram)\.(?:me|dog)\//i, "")!
.replace(/(?:\?start=)[A-Za-z0-9]+/i, "")!;
}
await client.invoke(
new telegram.Api.contacts.Unblock({
id: botLink,
})
);
try {
await waitNewMessages(
client,
worker,
botLink,
(
await client.sendMessage(botLink, { message: "/start" })
).id
);
} catch (err) {
if (err instanceof NoNewMessagesError) {
logger.warn(
`Target bot doesnt work | ${worker.phoneNumber}`
);
logger.debug(err.message);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const cancelMessage = await client.sendMessage(botEntity, {
message: "/cancel",
});
await waitNewMessages(
client,
worker,
botEntity,
cancelMessage.id
);
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
continue mainLoop;
} else {
throw err;
}
}
let forwardMessage: telegram.Api.Message;
try {
forwardMessage = (await (
await getMessagesByEntity(client, botLink, botLink, {
limit: 1000,
})
)[0].forwardTo(botEntity))![0];
} catch (err) {
if (err instanceof telegram.errors.RPCError) {
client.invoke(
new telegram.Api.messages.DeleteHistory({
justClear: true,
peer: botLink,
})
);
client.invoke(
new telegram.Api.contacts.Block({
id: botLink,
})
);
logger.warn(
`Error when forwarding a message. Skipping task... | ${worker.phoneNumber}`
);
logger.debug(err.message);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const cancelMessage = await client.sendMessage(botEntity, {
message: "/cancel",
});
await waitNewMessages(
client,
worker,
botEntity,
cancelMessage.id
);
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
continue mainLoop;
} else {
throw err;
}
}
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const afterTask = (
await client.getMessages(botEntity, {
minId: prevTask.lastMessage.id,
limit: 10,
})
).filter((value) => {
if (
value.message.includes(settings.botMessages.taskComplete) ||
value.message.includes(settings.botMessages.oldMessage)
) {
return true;
} else {
return false;
}
})[0];
if (afterTask !== undefined) {
if (
afterTask.message.includes(
settings.botMessages.taskComplete
) == true
) {
await client.invoke(
new telegram.Api.messages.DeleteHistory({
justClear: true,
peer: botLink,
})
);
await client.invoke(
new telegram.Api.contacts.Block({
id: botLink,
})
);
logger.info(`Bot task complete | ${worker.phoneNumber}`);
} else if (
afterTask.message.includes(settings.botMessages.oldMessage)
) {
logger.warn(
`Forwarded message was old | ${worker.phoneNumber}`
);
}
} else {
client.invoke(
new telegram.Api.messages.DeleteHistory({
justClear: true,
peer: botLink,
})
);
client.invoke(
new telegram.Api.contacts.Block({
id: botLink,
})
);
logger.warn(
`Message that i found is unknown | ${worker.phoneNumber}`
);
await skipButton.click({ sharePhone: false });
await waitNewMessages(
client,
worker,
botEntity,
prevTask.lastMessage.id
);
const cancelMessage = await client.sendMessage(botEntity, {
message: "/cancel",
});
await waitNewMessages(
client,
worker,
botEntity,
cancelMessage.id
);
prevTask.lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
continue mainLoop;
}
const cancelMessage = await client.sendMessage(botEntity, {
message: "/cancel",
});
await waitNewMessages(client, worker, botEntity, cancelMessage.id);
const lastMessage = (
await client.getMessages(botEntity, {
minId: cancelMessage.id,
})
)[0];
prevTask.task = task;
prevTask.lastMessage =
lastMessage !== undefined ? lastMessage : afterTask;
continue;
} else if (
task.message.includes(settings.botMessages.taskOver) == true
) {
logger.info(`Bots tasks completed | ${worker.phoneNumber}`);
break;
} else {
logger.error(`Check out last message of ${worker.phoneNumber}`);
throw new Error(`Check out last message of ${worker.phoneNumber}`);
}
}
};