mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-21 18:23:57 +00:00
feat: refactor and new features (#7)
* feat: refactor and new features + Refactored the codebase + OCR support in bots + Server sends training data every minute + Not using collectors for Discord feedback buttons anymore + Fixed grammar mistakes + Configs are now seperated + Tokens are no longer in configs - Like feedback doesn't work for Discord yet * feat: remove feedback button once voted * feat: role blacklist * feat: thread name check * feat: error handler for training * fix: bot crashing when a webhook msg is sent * refactor: remove debugging lines * feat: allow fixing mistake at votes in discord bot
This commit is contained in:
61
apps/bot-telegram/src/commands/train.js
Normal file
61
apps/bot-telegram/src/commands/train.js
Normal file
@@ -0,0 +1,61 @@
|
||||
export default {
|
||||
command: /\/train/,
|
||||
async execute(bot, config, msg) {
|
||||
const admins = await bot.getChatAdministrators(msg.chat.id);
|
||||
const isAdmin = admins.find((admin) => admin.user.id === msg.from.id);
|
||||
|
||||
if (!isAdmin)
|
||||
return bot.sendMessage(msg.chat.id, 'You\'re not an admin.', {
|
||||
message_thread_id: msg.message_thread_id,
|
||||
reply_to_message_id: msg.message_id
|
||||
});
|
||||
|
||||
if (msg.reply_to_message.message_id === msg.message_thread_id)
|
||||
return bot.sendMessage(msg.chat.id, 'Please reply to a message!', {
|
||||
message_thread_id: msg.message_thread_id,
|
||||
reply_to_message_id: msg.message_id
|
||||
});
|
||||
|
||||
const options = [];
|
||||
let arrI = 0;
|
||||
let i = 0;
|
||||
for (const { label } of config.responses) {
|
||||
if (arrI === 0 && i === 0) {
|
||||
options.push([
|
||||
{
|
||||
text: label,
|
||||
callback_data: `label_${label.toLowerCase()}`
|
||||
}
|
||||
]);
|
||||
i++;
|
||||
} else if (i === 2) {
|
||||
options.push([
|
||||
{
|
||||
text: label,
|
||||
callback_data: `label_${label.toLowerCase()}`
|
||||
}
|
||||
]);
|
||||
i = 0;
|
||||
arrI++;
|
||||
} else {
|
||||
options[arrI].push({
|
||||
text: label,
|
||||
callback_data: `label_${label.toLowerCase()}`
|
||||
});
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bot.sendMessage(
|
||||
msg.chat.id,
|
||||
'Please select the corresponding label to train the bot.',
|
||||
{
|
||||
message_thread_id: msg.message_thread_id,
|
||||
reply_to_message_id: msg.reply_to_message.message_id,
|
||||
reply_markup: {
|
||||
inline_keyboard: options
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
26
apps/bot-telegram/src/config.example.json
Normal file
26
apps/bot-telegram/src/config.example.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"server": {
|
||||
"port": 3000,
|
||||
"host": "192.168.1.6"
|
||||
},
|
||||
"responses": [
|
||||
{
|
||||
"label": "revanced_download",
|
||||
"threshold": 0.85,
|
||||
"reply": {
|
||||
"title": "How to download ReVanced?",
|
||||
"desc": "You don't."
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"ocrResponses": [
|
||||
{
|
||||
"regex": "is not installed",
|
||||
"reply": {
|
||||
"title": "Why can't I download videos",
|
||||
"desc": "Because you didn't install the app."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
25
apps/bot-telegram/src/config.json
Normal file
25
apps/bot-telegram/src/config.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"server": {
|
||||
"port": 3000,
|
||||
"host": "127.0.0.1"
|
||||
},
|
||||
"responses": [
|
||||
{
|
||||
"label": "revanced_download",
|
||||
"threshold": 0.85,
|
||||
"reply": {
|
||||
"title": "How to download ReVanced?",
|
||||
"desc": "You don't."
|
||||
}
|
||||
}
|
||||
],
|
||||
"ocrResponses": [
|
||||
{
|
||||
"regex": "is not installed",
|
||||
"reply": {
|
||||
"title": "Why can't I download videos",
|
||||
"desc": "Because you didn't install the app."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
26
apps/bot-telegram/src/events/callbackQuery.js
Normal file
26
apps/bot-telegram/src/events/callbackQuery.js
Normal file
@@ -0,0 +1,26 @@
|
||||
export default {
|
||||
name: 'callback_query',
|
||||
once: false,
|
||||
async execute(bot, helper, cb) {
|
||||
const admins = await bot.getChatAdministrators(cb.message.chat.id);
|
||||
const isAdmin = admins.find((admin) => admin.user.id === cb.from.id);
|
||||
|
||||
if (!isAdmin)
|
||||
return bot.sendMessage(cb.message.chat.id, 'You\'re not an admin.', {
|
||||
message_thread_id: cb.message.message_thread_id,
|
||||
reply_to_message_id: cb.message.message_id
|
||||
});
|
||||
|
||||
helper.sendTrainData(
|
||||
cb.message.reply_to_message.text.toLowerCase(),
|
||||
cb.data.replace('label_', '').toUpperCase()
|
||||
);
|
||||
|
||||
bot.sendMessage(cb.message.chat.id, 'Sent training data to server.', {
|
||||
message_thread_id: cb.message.message_thread_id,
|
||||
reply_to_message_id: cb.message.message_id
|
||||
});
|
||||
|
||||
bot.deleteMessage(cb.message.chat.id, cb.message.message_id);
|
||||
}
|
||||
};
|
||||
15
apps/bot-telegram/src/events/message.js
Normal file
15
apps/bot-telegram/src/events/message.js
Normal file
@@ -0,0 +1,15 @@
|
||||
export default {
|
||||
name: 'message',
|
||||
once: false,
|
||||
async execute(bot, helper, msg) {
|
||||
if (msg.photo) {
|
||||
const fileLink = await bot.getFileLink(msg.photo.at(-1).file_id);
|
||||
helper.scanImage(fileLink, `${msg.chat.id}/${msg.message_thread_id}/${msg.message_id}`)
|
||||
}
|
||||
if (!msg.text) return;
|
||||
helper.scanText(
|
||||
msg.text.toLowerCase(),
|
||||
`${msg.chat.id}/${msg.message_thread_id}/${msg.message_id}`
|
||||
);
|
||||
}
|
||||
};
|
||||
29
apps/bot-telegram/src/helperEvents/aiResponse.js
Normal file
29
apps/bot-telegram/src/helperEvents/aiResponse.js
Normal file
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
name: 'aiResponse',
|
||||
once: false,
|
||||
async execute(bot, config, aiRes) {
|
||||
if (!aiRes.response) return;
|
||||
if (!aiRes.response[0]) return;
|
||||
const ids = aiRes.id.split('/');
|
||||
const intent = aiRes.response.reduce((a, b) =>
|
||||
a.confidence > b.confidence ? a : b
|
||||
);
|
||||
const response = config.responses.find((res) => res.label === intent.name);
|
||||
if (!response) return;
|
||||
if (response.threshold > intent.confidence) return;
|
||||
if (!response.reply) return;
|
||||
|
||||
// Because for some reason the markdown parser in TG is a pain in the ass,
|
||||
// there won't be markdown support for now.
|
||||
bot.sendMessage(
|
||||
ids[0],
|
||||
`## ${response.reply.title}\n\n${response.reply.desc}\n\n_Confidence: ${intent.confidence}_\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`,
|
||||
{
|
||||
message_thread_id: ids[1],
|
||||
reply_to_message_id: ids[2]
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
24
apps/bot-telegram/src/helperEvents/ocrResponse.js
Normal file
24
apps/bot-telegram/src/helperEvents/ocrResponse.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
name: 'ocrResponse',
|
||||
once: false,
|
||||
async execute(bot, config, ocrRes) {
|
||||
const ids = ocrRes.id.split('/');
|
||||
|
||||
for (const ocrReply of config.ocrResponses) {
|
||||
if (ocrRes.ocrText.match(ocrReply.regex)) {
|
||||
// Because for some reason the markdown parser in TG is a pain in the ass,
|
||||
// there won't be markdown support for now.
|
||||
bot.sendMessage(
|
||||
ids[0],
|
||||
`## ${ocrReply.reply.title}\n\n${ocrReply.reply.desc}\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`,
|
||||
{
|
||||
message_thread_id: ids[1],
|
||||
reply_to_message_id: ids[2]
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
66
apps/bot-telegram/src/index.js
Normal file
66
apps/bot-telegram/src/index.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import TelegramBot from 'node-telegram-bot-api';
|
||||
import { readFileSync, readdirSync } from 'node:fs';
|
||||
// Fix __dirname not being defined in ES modules. (https://stackoverflow.com/a/64383997)
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join } from 'node:path';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
import HelperClient from '@revanced-helper/helper-client';
|
||||
import config from './config.json' assert { type: 'json' };
|
||||
|
||||
const helper = new HelperClient(config);
|
||||
helper.connect();
|
||||
|
||||
const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true });
|
||||
|
||||
const commandsPath = join(__dirname, 'commands');
|
||||
const commandFiles = readdirSync(commandsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = join(commandsPath, file);
|
||||
const command = (await import(`file://${filePath}`)).default;
|
||||
if ('command' in command && 'execute' in command) {
|
||||
bot.onText(command.command, (...args) =>
|
||||
command.execute(bot, config, ...args)
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const tgEventsPath = join(__dirname, 'events');
|
||||
const tgEventFiles = readdirSync(tgEventsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
|
||||
for (const file of tgEventFiles) {
|
||||
const filePath = join(tgEventsPath, file);
|
||||
const event = (await import(`file://${filePath}`)).default;
|
||||
if (event.once) {
|
||||
bot.once(event.name, (...args) => event.execute(bot, helper, ...args));
|
||||
} else {
|
||||
bot.on(event.name, (...args) => event.execute(bot, helper, ...args));
|
||||
}
|
||||
}
|
||||
|
||||
// The ReVanced Helper events.
|
||||
|
||||
const helperEventsPath = join(__dirname, 'helperEvents');
|
||||
const helperEventFiles = readdirSync(helperEventsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
|
||||
for (const file of helperEventFiles) {
|
||||
const filePath = join(helperEventsPath, file);
|
||||
const event = (await import(`file://${filePath}`)).default;
|
||||
if (event.once) {
|
||||
helper.once(event.name, (...args) => event.execute(bot, config, ...args));
|
||||
} else {
|
||||
helper.on(event.name, (...args) => event.execute(bot, config, ...args));
|
||||
}
|
||||
}
|
||||
2302
apps/bot-telegram/src/package-lock.json
generated
Normal file
2302
apps/bot-telegram/src/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
apps/bot-telegram/src/package.json
Normal file
17
apps/bot-telegram/src/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "bot-telegram",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Reis Can",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@revanced-helper/helper-client": "file:../../../packages/client",
|
||||
"node-telegram-bot-api": "^0.61.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user