feat: training and replies changed

This commit is contained in:
GramingFoxTeam
2023-03-20 21:28:52 +03:00
parent 1909e2c421
commit 715aa918cf
16 changed files with 187 additions and 106 deletions

View File

@@ -27,7 +27,10 @@
{
"label": "DOWNLOAD",
"threshold": 0.85,
"text": "the download?"
"reply": {
"title": "download??",
"desc": "the download?"
}
}
]
}

View File

@@ -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}`
);
}
};

View File

@@ -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);
}
}
};

View File

@@ -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);
};

View File

@@ -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();
}

View File

@@ -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;
}
};

View File

@@ -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)
);
}
}
}
};

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -66,4 +66,4 @@ export default async () => {
helper.on(event.name, (...args) => event.execute(bot, config, ...args));
}
}
}
};

View File

@@ -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",

View File

@@ -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.

View File

@@ -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();

View File

@@ -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
View 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;
}

View File

@@ -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;