mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-11 13:56:15 +00:00
feat: training and replies changed
This commit is contained in:
@@ -27,7 +27,10 @@
|
||||
{
|
||||
"label": "DOWNLOAD",
|
||||
"threshold": 0.85,
|
||||
"text": "the download?"
|
||||
"reply": {
|
||||
"title": "download??",
|
||||
"desc": "the download?"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ export default {
|
||||
once: false,
|
||||
execute(helper, _, msg) {
|
||||
if (!msg.content || msg.author.bot) return;
|
||||
helper.scanText(msg.content.toLowerCase().replace(/<.*?>/g, ''), `${msg.channelId}/${msg.id}`);
|
||||
helper.scanText(
|
||||
msg.content.toLowerCase().replace(/<.*?>/g, ''),
|
||||
`${msg.channelId}/${msg.id}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -23,19 +23,26 @@ export default {
|
||||
message = channel.messages.cache.get(ids[1]);
|
||||
}
|
||||
|
||||
const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b);
|
||||
const response = config.responses.find((res) => res.label === intent.name);
|
||||
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.threshold > intent.confidence) return;
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('You have asked a Frequently Asked Question')
|
||||
.setDescription(response.text)
|
||||
.setFooter({ text: `Confidence: ${intent.confidence}` });
|
||||
if (!response.reply) return;
|
||||
|
||||
message.reply({ embeds: [embed]});
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(response.reply.title)
|
||||
.setDescription(response.reply.desc)
|
||||
.setColor(14908858)
|
||||
.setFooter({ text: `Confidence: ${intent.confidence}` });
|
||||
|
||||
message.reply({ embeds: [embed] });
|
||||
|
||||
return;
|
||||
} catch (e) {console.log(e)}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,75 +8,78 @@ const __dirname = dirname(__filename);
|
||||
import HelperClient from '../../client/index.js';
|
||||
|
||||
export default async () => {
|
||||
const config = JSON.parse(readFileSync('./config.json', 'utf-8'));
|
||||
const config = JSON.parse(readFileSync('./config.json', 'utf-8'));
|
||||
|
||||
const helper = new HelperClient(config);
|
||||
const helper = new HelperClient(config);
|
||||
|
||||
helper.connect();
|
||||
helper.connect();
|
||||
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent
|
||||
]
|
||||
});
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent
|
||||
]
|
||||
});
|
||||
|
||||
client.commands = new Collection();
|
||||
client.commands = new Collection();
|
||||
|
||||
const commandsPath = join(__dirname, 'commands');
|
||||
const commandFiles = readdirSync(commandsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
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 ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
} else {
|
||||
console.log(
|
||||
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
|
||||
);
|
||||
for (const file of commandFiles) {
|
||||
const filePath = join(commandsPath, file);
|
||||
const command = (await import(`file://${filePath}`)).default;
|
||||
if ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
} else {
|
||||
console.log(
|
||||
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const discordEventsPath = join(__dirname, 'events/discord');
|
||||
const discordEventFiles = readdirSync(discordEventsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
const discordEventsPath = join(__dirname, 'events/discord');
|
||||
const discordEventFiles = readdirSync(discordEventsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
|
||||
for (const file of discordEventFiles) {
|
||||
const filePath = join(discordEventsPath, file);
|
||||
const event = (await import(`file://${filePath}`)).default;
|
||||
if (event.once) {
|
||||
client.once(event.name, (...args) =>
|
||||
event.execute(helper, config, ...args)
|
||||
);
|
||||
} else {
|
||||
client.on(event.name, (...args) => event.execute(helper, config, ...args));
|
||||
for (const file of discordEventFiles) {
|
||||
const filePath = join(discordEventsPath, file);
|
||||
const event = (await import(`file://${filePath}`)).default;
|
||||
if (event.once) {
|
||||
client.once(event.name, (...args) =>
|
||||
event.execute(helper, config, ...args)
|
||||
);
|
||||
} else {
|
||||
client.on(event.name, (...args) =>
|
||||
event.execute(helper, config, ...args)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The ReVanced Helper events.
|
||||
// The ReVanced Helper events.
|
||||
|
||||
const helperEventsPath = join(__dirname, 'events/helper');
|
||||
const helperEventFiles = readdirSync(helperEventsPath).filter((file) =>
|
||||
file.endsWith('.js')
|
||||
);
|
||||
const helperEventsPath = join(__dirname, 'events/helper');
|
||||
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(client, config, ...args)
|
||||
);
|
||||
} else {
|
||||
helper.on(event.name, (...args) => event.execute(client, config, ...args));
|
||||
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(client, config, ...args)
|
||||
);
|
||||
} else {
|
||||
helper.on(event.name, (...args) =>
|
||||
event.execute(client, config, ...args)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.login(config.discord.token);
|
||||
|
||||
}
|
||||
client.login(config.discord.token);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { readdirSync } from 'node:fs';
|
||||
|
||||
const botFolders = readdirSync('./', { withFileTypes: true })
|
||||
.filter(dirent => dirent.isDirectory())
|
||||
.map(dirent => dirent.name);
|
||||
.filter((dirent) => dirent.isDirectory())
|
||||
.map((dirent) => dirent.name);
|
||||
|
||||
const runBotOnly = process.argv[2] ? process.argv[2] : null;
|
||||
for (const botFolder of botFolders) {
|
||||
if (botFolder === 'node_modules') continue;
|
||||
if (runBotOnly && runBotOnly !== botFolder) continue;
|
||||
const botIndex = await import(`./${botFolder}/index.js`);
|
||||
botIndex.default();
|
||||
}
|
||||
if (botFolder === 'node_modules') continue;
|
||||
if (runBotOnly && runBotOnly !== botFolder) continue;
|
||||
const botIndex = await import(`./${botFolder}/index.js`);
|
||||
botIndex.default();
|
||||
}
|
||||
|
||||
@@ -6,23 +6,33 @@ export default {
|
||||
if (!aiRes.response[0]) return;
|
||||
const ids = aiRes.id.split('/');
|
||||
|
||||
const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b);
|
||||
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.threshold > intent.confidence) return;
|
||||
if (!response.reply) return;
|
||||
|
||||
switch (ids[0]) {
|
||||
case 'comment': {
|
||||
client.getComment(ids[1]).reply(`${response.text}\n\n*Confidence: ${intent.confidence}*`);
|
||||
break;
|
||||
}
|
||||
case 'comment': {
|
||||
client
|
||||
.getComment(ids[1])
|
||||
.reply(
|
||||
`## ${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.`
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'post': {
|
||||
client.getSubmission(ids[1]).reply(`${response.text}\n\n*Confidence: ${intent.confidence}*`);
|
||||
break;
|
||||
}
|
||||
case 'post': {
|
||||
client
|
||||
.getSubmission(ids[1])
|
||||
.reply(
|
||||
`## ${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.`
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,7 +97,9 @@ export default async () => {
|
||||
event.execute(client, config, ...args)
|
||||
);
|
||||
} else {
|
||||
helper.on(event.name, (...args) => event.execute(client, config, ...args));
|
||||
helper.on(event.name, (...args) =>
|
||||
event.execute(client, config, ...args)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ export default {
|
||||
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,
|
||||
|
||||
@@ -5,15 +5,22 @@ export default {
|
||||
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 intent = aiRes.response.reduce((a, b) =>
|
||||
a.confidence > b.confidence ? a : b
|
||||
);
|
||||
const response = config.responses.find((res) => res.label === intent.name);
|
||||
if (response.threshold > intent.confidence) return;
|
||||
if (!response.reply) return;
|
||||
|
||||
bot.sendMessage(ids[0], `${response.text}\n\n*Confidence: ${intent.confidence}*`, {
|
||||
message_thread_id: ids[1],
|
||||
reply_to_message_id: ids[2],
|
||||
parse_mode: 'HTML'
|
||||
});
|
||||
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],
|
||||
parse_mode: 'Markdown'
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,4 +66,4 @@ export default async () => {
|
||||
helper.on(event.name, (...args) => event.execute(bot, config, ...args));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/reisxd/revanced-helper#readme",
|
||||
"scripts": {
|
||||
"lint": "prettier --write . && eslint --fix ."
|
||||
"lint": "prettier --write . && eslint --fix .",
|
||||
"installPackages": "cd bots && npm i && cd ../client && npm i && cd ../server && npm i",
|
||||
"start": "cd bots && node . & cd ../server && node ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.27.0",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The server uses TCP for connection and BSON for messages, so you need to serialize and deserialize the messages.
|
||||
|
||||
# AI
|
||||
## AI
|
||||
|
||||
Sending the server this JSON (BSON) will send you back the AI predictions.
|
||||
|
||||
@@ -20,11 +20,28 @@ And the server would return something like this:
|
||||
{
|
||||
"op": 2,
|
||||
"id": "String",
|
||||
"response": "I think the term afn is just a generic slang term for the app that allows you to modify the behavior of Dalvik based android application..."
|
||||
"response": [
|
||||
{
|
||||
"confidence": 0.99,
|
||||
"id": "String",
|
||||
"name": "revanced_download"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Training the AI
|
||||
|
||||
To train the AI, send the server a JSON (BSON) like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 3,
|
||||
"label": "revanced_download",
|
||||
"text": "how to download revanced"
|
||||
}
|
||||
```
|
||||
|
||||
# OCR
|
||||
## OCR
|
||||
|
||||
Sending the server this JSON (BSON) will send you back the read text.
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { serialize } from 'bson';
|
||||
|
||||
export default async function runAI(client, data, config) {
|
||||
const witAIReq = await fetch(`https://api.wit.ai/message?v20230319&q=${encodeURI(data.text)}`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${config.authToken}`
|
||||
const witAIReq = await fetch(
|
||||
`https://api.wit.ai/message?v20230319&q=${encodeURI(data.text)}`,
|
||||
{
|
||||
headers: {
|
||||
authorization: `Bearer ${config.authToken}`
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
const response = await witAIReq.json();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import runAI from './ai.js';
|
||||
import runOCR from './ocr.js';
|
||||
import trainAI from './train.js';
|
||||
|
||||
export { runAI, runOCR };
|
||||
export { runAI, runOCR, trainAI };
|
||||
|
||||
18
server/events/train.js
Normal file
18
server/events/train.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export default async function runAI(data, config) {
|
||||
fetch('https://api.wit.ai/utterances', {
|
||||
headers: {
|
||||
authorization: `Bearer ${config.authToken}`
|
||||
},
|
||||
body: JSON.stringify([
|
||||
{
|
||||
text: data.text,
|
||||
intent: data.label,
|
||||
entities: [],
|
||||
traits: []
|
||||
}
|
||||
]),
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ const config = JSON.parse(readFileSync('./config.json', 'utf-8'));
|
||||
|
||||
import { createServer } from 'node:net';
|
||||
import { deserialize } from 'bson';
|
||||
import { runAI, runOCR } from './events/index.js';
|
||||
import { runAI, runOCR, trainAI } from './events/index.js';
|
||||
|
||||
const server = createServer(async (client) => {
|
||||
client.on('data', async (data) => {
|
||||
@@ -17,6 +17,11 @@ const server = createServer(async (client) => {
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
trainAI(eventData, config.witAI);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
runOCR(client, eventData);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user