V3
This commit is contained in:
parent
9341181f99
commit
236ca371bb
39 changed files with 659 additions and 1531 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
.env
|
||||
node_modules
|
||||
node_modules
|
||||
package-lock.json
|
||||
dist
|
||||
.env
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:latest
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
CMD ["node", "bot.js"]
|
||||
CMD ["npm", "run", "start"]
|
24
README.md
Normal file
24
README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Discord JS template in Typescript
|
||||
|
||||
## Installation
|
||||
|
||||
- Clone the repository
|
||||
- Run `npm i` and `npm i -g typescript tsx` to install all dependences
|
||||
- Change `.envExemple` file to `.env`
|
||||
- Enter your bot token and bot id in `.env` file
|
||||
|
||||
## Developpement
|
||||
|
||||
- You can copy the ping.ts file in `/src/commands/default` to start creating your own commands
|
||||
- You can modify the files in `/src/events` to use events as you would
|
||||
|
||||
## NPM commands
|
||||
|
||||
- Run `npm run dev` to run the dev mode
|
||||
- Tun `npm run build` to build the project
|
||||
- Run `npm run start` to run the compiled code
|
||||
|
||||
## Docker configuration
|
||||
|
||||
- Change the service name and the full path to your bot in `docker-compose.yml` file
|
||||
- Run `docker compose up` to run the container
|
87
bot.js
87
bot.js
|
@ -1,87 +0,0 @@
|
|||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const {
|
||||
Client,
|
||||
Collection,
|
||||
GatewayIntentBits,
|
||||
Partials,
|
||||
REST,
|
||||
Routes,
|
||||
} = require("discord.js");
|
||||
require("dotenv").config();
|
||||
const { sendLog } = require("./libs/logs.js");
|
||||
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.DirectMessages,
|
||||
GatewayIntentBits.MessageContent,
|
||||
],
|
||||
partials: [Partials.Channel, Partials.Message],
|
||||
});
|
||||
|
||||
client.commands = new Collection();
|
||||
const commands = [];
|
||||
const foldersPath = path.join(__dirname, "commands");
|
||||
const commandFolders = fs.readdirSync(foldersPath);
|
||||
|
||||
for (const folder of commandFolders) {
|
||||
const commandsPath = path.join(foldersPath, folder);
|
||||
const commandFiles = fs
|
||||
.readdirSync(commandsPath)
|
||||
.filter((file) => file.endsWith(".js"));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
const command = require(filePath);
|
||||
if ("data" in command && "execute" in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
commands.push(command.data.toJSON());
|
||||
} else {
|
||||
console.log(
|
||||
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log(
|
||||
`Started refreshing ${commands.length} application (/) commands.`
|
||||
);
|
||||
sendLog(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(process.env.BOT_ID),
|
||||
{ body: commands }
|
||||
);
|
||||
|
||||
console.log(
|
||||
`Successfully reloaded ${data.length} application (/) commands.`
|
||||
);
|
||||
sendLog(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
|
||||
const eventsPath = path.join(__dirname, "events");
|
||||
const eventFiles = fs
|
||||
.readdirSync(eventsPath)
|
||||
.filter((file) => file.endsWith(".js"));
|
||||
|
||||
for (const file of eventFiles) {
|
||||
const filePath = path.join(eventsPath, file);
|
||||
const event = require(filePath);
|
||||
if (event.once) {
|
||||
client.once(event.name, (...args) => event.execute(...args));
|
||||
} else {
|
||||
client.on(event.name, (...args) => event.execute(...args));
|
||||
}
|
||||
}
|
||||
|
||||
client.login(process.env.DISCORD_TOKEN);
|
|
@ -1,11 +0,0 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("ping")
|
||||
.setDescription("Replies with Pong!"),
|
||||
async execute(interaction) {
|
||||
console.log("ping command executed");
|
||||
await interaction.reply("Pong!");
|
||||
},
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
const {
|
||||
SlashCommandBuilder,
|
||||
EmbedBuilder,
|
||||
ButtonBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonStyle,
|
||||
PermissionsBitField,
|
||||
} = require("discord.js");
|
||||
const { errorEmbed } = require("../../libs/embeds.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("addhub")
|
||||
.setDescription("Add a conversation hub to the database.")
|
||||
.setDMPermission(false),
|
||||
async execute(interaction) {
|
||||
if (
|
||||
!interaction.member.permissions.has(
|
||||
PermissionsBitField.Flags.Administrator
|
||||
)
|
||||
) {
|
||||
const embed = errorEmbed(
|
||||
"You need the administrator permission to use this command."
|
||||
);
|
||||
return interaction.reply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("Conversation hub")
|
||||
.setDescription("Click on the button below to create a conversation.")
|
||||
.setColor("#F6C6F9")
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId("create_conversation")
|
||||
.setLabel("Create conversation")
|
||||
.setStyle(ButtonStyle.Success);
|
||||
|
||||
const actionRow = new ActionRowBuilder().addComponents(button);
|
||||
|
||||
await interaction.reply({ embeds: [embed], components: [actionRow] });
|
||||
},
|
||||
};
|
|
@ -1,37 +0,0 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
const { getConv, removeConv } = require("../../libs/mysql.js");
|
||||
const { errorEmbed } = require("../../libs/embeds.js");
|
||||
const { sendLog } = require("../../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("closeconv")
|
||||
.setDescription("Close the current conversation.")
|
||||
.setDMPermission(false),
|
||||
async execute(interaction) {
|
||||
const conv = await getConv(interaction.channelId).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your conversation data."
|
||||
);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
if (!conv[0]) {
|
||||
const embed = errorEmbed("This channel is not a conversation.");
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
if (conv[0].userid != interaction.user.id) {
|
||||
const embed = errorEmbed("You are not the owner of this conversation.");
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
var channel = interaction.guild.channels.cache.get(interaction.channelId);
|
||||
|
||||
await removeConv(channel.id);
|
||||
await channel.delete();
|
||||
},
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
//const { sendConv } = require("../../libs/mistralAiFunctions");
|
||||
//const data = require("../../data.json");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("mistral")
|
||||
.setDescription("Talk to Mistral AI")
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand
|
||||
.setName("medium")
|
||||
.setDescription("Talk to Mistral AI using the medium model")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("message")
|
||||
.setDescription("What do you want to say to Mistral AI?")
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
async execute(interaction) {
|
||||
/*if (interaction.options.getSubcommand() === "medium") {
|
||||
const message = interaction.options.getString("message");
|
||||
messages = [
|
||||
{ role: system, text: data.prompt },
|
||||
{ role: user, text: message },
|
||||
];
|
||||
const chatResponse = await sendConv(messages);
|
||||
console.log(chatResponse);
|
||||
await interaction.reply(chatResponse);
|
||||
}*/
|
||||
},
|
||||
};
|
|
@ -1,31 +0,0 @@
|
|||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||
const { getQuotasSum } = require("../../libs/mysql.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("botinfo")
|
||||
.setDescription("Get information about the bot."),
|
||||
async execute(interaction) {
|
||||
const quotasSum = await getQuotasSum();
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor("#F6C6F9")
|
||||
.setTitle("Bot Info")
|
||||
.setDescription("Information about the bot.")
|
||||
.addFields(
|
||||
{
|
||||
name: "Guilds",
|
||||
value: interaction.client.guilds.cache.size.toString(),
|
||||
inline: false,
|
||||
},
|
||||
{
|
||||
name: "Total quota",
|
||||
value: `${quotasSum[0]["SUM(quota)"]}$`,
|
||||
inline: false,
|
||||
}
|
||||
)
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
|
||||
interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
|
@ -1,36 +0,0 @@
|
|||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||
const { getUser } = require("../../libs/mysql.js");
|
||||
const { errorEmbed } = require("../../libs/embeds.js");
|
||||
const { sendLog } = require("../../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("getquota")
|
||||
.setDescription("Get your current quota.")
|
||||
.setDMPermission(false),
|
||||
async execute(interaction) {
|
||||
const user = await getUser(interaction.user.id).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your user data."
|
||||
);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
const embed = errorEmbed("You don't have any quota yet.");
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor("#F6C6F9")
|
||||
.setTitle("Quota")
|
||||
.setDescription(`You have ${0.4 - user[0].quota}$ of credits left.`)
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("help")
|
||||
.setDescription("Get help about the bot."),
|
||||
async execute(interaction) {
|
||||
const helpMessage = `
|
||||
**Single requests:**
|
||||
- **/quickgpt**: Make a single request to the GPT-3.5 Turbo model.
|
||||
- **/gptrequest**: Make a single request to the GPT-4 model.
|
||||
|
||||
**Conversations:**
|
||||
- **/addhub**: Add a conversation hub to the channel, user needs to have the ADMINISTRATOR permission and the channel needs to be a forum channel or a normal text channel.
|
||||
- **/closeconv**: Close the conversation in your channel, user needs to be the creator of the conversation.
|
||||
|
||||
**Others:**
|
||||
- **/getquota**: Display your quota, you can use a total of 0.4$ of quota per month.
|
||||
- **/botinfo**: Display information about the bot.
|
||||
|
||||
**Links:**
|
||||
- [Invite the bot](https://discord.com/api/oauth2/authorize?client_id=1059559067846189067&permissions=326417632256&scope=bot)
|
||||
- [Support server](https://discord.gg/WcZPz3nm5p)
|
||||
`;
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor("#F6C6F9")
|
||||
.setTitle("Help")
|
||||
.setDescription(helpMessage)
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
|
||||
interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
|
@ -1,107 +0,0 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
const {
|
||||
getUser,
|
||||
registerUser,
|
||||
incrementQuota,
|
||||
} = require("../../libs/mysql.js");
|
||||
const { answerQuestion } = require("../../libs/openAi.js");
|
||||
const { checkLastResetDate } = require("../../libs/quotaReset.js");
|
||||
const { requestResponseEmbed, errorEmbed } = require("../../libs/embeds.js");
|
||||
const { sendLog } = require("../../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("gptrequest")
|
||||
.setDescription("Make a single request to the GPT-4 API.")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("prompt")
|
||||
.setDescription("The prompt to send to the API.")
|
||||
.setRequired(true)
|
||||
),
|
||||
async execute(interaction) {
|
||||
interaction.deferReply();
|
||||
await checkLastResetDate();
|
||||
user = await getUser(interaction.user.id).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your user data."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
await registerUser(interaction.user.username, interaction.user.id).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to register you in our database."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
);
|
||||
|
||||
user = await getUser(interaction.user.id).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your user data."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
}
|
||||
|
||||
if (user[0].quota >= 0.4) {
|
||||
const embed = errorEmbed(
|
||||
"You don't have enough quota to use this command."
|
||||
);
|
||||
|
||||
return await interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
response = await answerQuestion(
|
||||
interaction.options.getString("prompt")
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to send the request to the API."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
const prompt_usage = (response.data.usage.prompt_tokens * 0.01) / 1000;
|
||||
const completion_usage =
|
||||
(response.data.usage.completion_tokens * 0.03) / 1000;
|
||||
|
||||
await incrementQuota(
|
||||
interaction.user.id,
|
||||
prompt_usage + completion_usage
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to increment your quota."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
const embed = requestResponseEmbed(
|
||||
interaction.user,
|
||||
interaction.options.getString("prompt"),
|
||||
response.data.choices[0].message.content,
|
||||
user[0].quota,
|
||||
prompt_usage,
|
||||
completion_usage
|
||||
);
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
},
|
||||
};
|
|
@ -1,107 +0,0 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
const {
|
||||
getUser,
|
||||
registerUser,
|
||||
incrementQuota,
|
||||
} = require("../../libs/mysql.js");
|
||||
const { quickAnswer } = require("../../libs/openAi.js");
|
||||
const { checkLastResetDate } = require("../../libs/quotaReset.js");
|
||||
const { requestResponseEmbed, errorEmbed } = require("../../libs/embeds.js");
|
||||
const { sendLog } = require("../../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("quickgpt")
|
||||
.setDescription("Make a single request to the GPT-3.5-turbo API.")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("prompt")
|
||||
.setDescription("The prompt to send to the API.")
|
||||
.setRequired(true)
|
||||
),
|
||||
async execute(interaction) {
|
||||
await interaction.deferReply();
|
||||
await checkLastResetDate();
|
||||
user = await getUser(interaction.user.id).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your user data."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
await registerUser(interaction.user.username, interaction.user.id).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to register you in our database."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
);
|
||||
|
||||
user = await getUser(interaction.user.id).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your user data."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
}
|
||||
|
||||
if (user[0].quota >= 0.4) {
|
||||
const embed = errorEmbed(
|
||||
"You don't have enough quota to use this command."
|
||||
);
|
||||
|
||||
return await interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
response = await quickAnswer(interaction.options.getString("prompt")).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to send the request to the API."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
);
|
||||
|
||||
const prompt_usage = (response.data.usage.prompt_tokens * 0.001) / 1000;
|
||||
const completion_usage =
|
||||
(response.data.usage.completion_tokens * 0.002) / 1000;
|
||||
|
||||
await incrementQuota(
|
||||
interaction.user.id,
|
||||
prompt_usage + completion_usage
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to increment your quota."
|
||||
);
|
||||
|
||||
return interaction.editReply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
const embed = requestResponseEmbed(
|
||||
interaction.user,
|
||||
interaction.options.getString("prompt"),
|
||||
response.data.choices[0].message.content,
|
||||
user[0].quota,
|
||||
prompt_usage,
|
||||
completion_usage
|
||||
);
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
},
|
||||
};
|
3
config.json
Normal file
3
config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"defaultPrompt": "You are an helpful assistant, you always answer in the language of the user."
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"prompt": "Tu es un bot discord s'appelant NekoSuru, tu es une catgirl futuriste. Tu es amicale et tutois les utilisateurs."
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
const {
|
||||
Events,
|
||||
ButtonBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonStyle,
|
||||
} = require("discord.js");
|
||||
const { addConv, removeConv, getConv } = require("../libs/mysql.js");
|
||||
const {
|
||||
errorEmbed,
|
||||
convBeginEmbed,
|
||||
convCreatedEmbed,
|
||||
} = require("../libs/embeds.js");
|
||||
const { sendLog } = require("../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
name: Events.InteractionCreate,
|
||||
async execute(interaction) {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
console.error(
|
||||
`No command matching ${interaction.commandName} was found.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
} catch (error) {
|
||||
sendLog(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.isButton()) {
|
||||
if (interaction.customId == "create_conversation") {
|
||||
var channel = interaction.guild.channels.cache.get(
|
||||
interaction.message.channelId
|
||||
);
|
||||
|
||||
if (channel.type == 11) {
|
||||
channel = interaction.guild.channels.cache.get(channel.parentId);
|
||||
}
|
||||
|
||||
const embed = convBeginEmbed();
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId("close_conversation")
|
||||
.setLabel("Close conversation")
|
||||
.setStyle(ButtonStyle.Danger);
|
||||
|
||||
const actionRow = new ActionRowBuilder().addComponents(button);
|
||||
|
||||
channel = await channel.threads
|
||||
.create({
|
||||
name: interaction.user.username + "'s conversation",
|
||||
message: {
|
||||
embeds: [embed],
|
||||
components: [actionRow],
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
sendLog(err);
|
||||
});
|
||||
|
||||
const embed2 = convCreatedEmbed(channel.id);
|
||||
|
||||
await addConv(
|
||||
interaction.user.id,
|
||||
channel.id,
|
||||
interaction.guild.id
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while creating the conversation."
|
||||
);
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
await interaction.reply({ embeds: [embed2], ephemeral: true });
|
||||
} else if (interaction.customId == "close_conversation") {
|
||||
const conv = await getConv(interaction.message.channelId).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while closing the conversation."
|
||||
);
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
);
|
||||
|
||||
if (conv[0].userid != interaction.user.id) {
|
||||
const embed = errorEmbed("You can't close this conversation.");
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
}
|
||||
|
||||
var channel = interaction.guild.channels.cache.get(
|
||||
interaction.message.channelId
|
||||
);
|
||||
|
||||
await removeConv(channel.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while closing the conversation."
|
||||
);
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
|
||||
await channel.delete().catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while closing the conversation."
|
||||
);
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
|
@ -1,315 +0,0 @@
|
|||
const { Events, EmbedBuilder } = require("discord.js");
|
||||
const {
|
||||
getConv,
|
||||
getUser,
|
||||
registerUser,
|
||||
incrementQuota,
|
||||
} = require("../libs/mysql.js");
|
||||
const { sendQuickConv, quickAnswer } = require("../libs/openAi.js");
|
||||
const { checkLastResetDate } = require("../libs/quotaReset.js");
|
||||
const prompt = require("../data/prompt.json").prompt;
|
||||
require("dotenv").config();
|
||||
const { errorEmbed } = require("../libs/embeds.js");
|
||||
const { sendLog } = require("../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
name: Events.MessageCreate,
|
||||
async execute(message) {
|
||||
conv = await getConv(message.channel.id);
|
||||
|
||||
if (!message.guildId && message.author.id != "1059559067846189067") {
|
||||
await checkLastResetDate();
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
await registerUser(message.author.username, message.author.id).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to register you in the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
}
|
||||
);
|
||||
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
}
|
||||
|
||||
if (user[0].quota >= 0.4)
|
||||
return await message.reply({
|
||||
content: "You don't have enough quota to talk with the bot.",
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
discordMessages = await message.channel.messages.fetch().catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to fetch the messages from the channel."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
discordMessages.filter((message) => message.content);
|
||||
messages = [];
|
||||
var i = 0;
|
||||
discordMessages.forEach(async (message) => {
|
||||
if (i == 6) return;
|
||||
if (message.author.id == "1059559067846189067") {
|
||||
messages.push({ role: "assistant", content: message.content });
|
||||
i++;
|
||||
} else {
|
||||
messages.push({ role: "user", content: message.content });
|
||||
i++;
|
||||
}
|
||||
});
|
||||
messages.reverse();
|
||||
messages.unshift({ role: "system", content: prompt });
|
||||
|
||||
message.channel.sendTyping().catch((err) => {
|
||||
sendLog(err);
|
||||
});
|
||||
|
||||
const response = await sendQuickConv(messages).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to send the request to the API."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
const prompt_usage = (response.data.usage.prompt_tokens * 0.001) / 1000;
|
||||
const completion_usage =
|
||||
(response.data.usage.completion_tokens * 0.002) / 1000;
|
||||
|
||||
await incrementQuota(
|
||||
message.author.id,
|
||||
prompt_usage + completion_usage
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to increment your quota."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (response.data.choices[0].message.content.length <= 2000) {
|
||||
await message.reply(response.data.choices[0].message.content);
|
||||
} else {
|
||||
let paragraphs = response.data.choices[0].message.content.split("\n");
|
||||
messageText = "";
|
||||
|
||||
paragraphs.forEach((paragraph) => {
|
||||
if (`${messageText}${paragraph}`.length > 2000) {
|
||||
message.reply(messageText);
|
||||
messageText = `${paragraph}\n`;
|
||||
} else {
|
||||
messageText += `${paragraph}\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
message.content.includes(`<@${process.env.BOT_ID}>`) ||
|
||||
(message.mentions.repliedUser &&
|
||||
message.mentions.repliedUser.id == process.env.BOT_ID)
|
||||
) {
|
||||
await checkLastResetDate();
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
await registerUser(message.author.username, message.author.id).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to register you in the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
}
|
||||
);
|
||||
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
}
|
||||
|
||||
if (user[0].quota >= 0.4)
|
||||
return await message.reply({
|
||||
content: "You don't have enough quota to use this command.",
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
message.channel.sendTyping().catch((err) => {
|
||||
sendLog(err);
|
||||
});
|
||||
|
||||
response = await quickAnswer(message.content).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to send the request to the API."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
const prompt_usage = (response.data.usage.prompt_tokens * 0.01) / 1000;
|
||||
const completion_usage =
|
||||
(response.data.usage.completion_tokens * 0.03) / 1000;
|
||||
|
||||
await incrementQuota(
|
||||
message.author.id,
|
||||
prompt_usage + completion_usage
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to increment your quota."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (response.data.choices[0].message.content.length <= 2000) {
|
||||
await message.reply({
|
||||
content: response.data.choices[0].message.content,
|
||||
});
|
||||
} else {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("Answer")
|
||||
.setDescription(response.data.choices[0].message.content)
|
||||
.setColor("#F6C6F9")
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
|
||||
await message.reply({ embeds: [embed] });
|
||||
}
|
||||
} else if (
|
||||
conv[0] &&
|
||||
message.author.id != "1059559067846189067" &&
|
||||
conv[0].userid == message.author.id
|
||||
) {
|
||||
await checkLastResetDate();
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (!user[0]) {
|
||||
await registerUser(message.author.username, message.author.id).catch(
|
||||
(err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to register you in the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
}
|
||||
);
|
||||
|
||||
user = await getUser(message.author.id).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to get your data from the database."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
}
|
||||
|
||||
if (user[0].quota >= 0.4)
|
||||
return await message.reply({
|
||||
content: "You don't have enough quota to talk with the bot.",
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
discordMessages = await message.channel.messages.fetch().catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to fetch the messages from the channel."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
discordMessages.filter(
|
||||
(message) =>
|
||||
(message.author.id == "1059559067846189067" ||
|
||||
message.author.id == conv[0].userid) &&
|
||||
message.content
|
||||
);
|
||||
messages = [];
|
||||
var i = 0;
|
||||
discordMessages.forEach(async (message) => {
|
||||
if (i == 6) return;
|
||||
if (message.author.id == "1059559067846189067") {
|
||||
messages.push({ role: "assistant", content: message.content });
|
||||
i++;
|
||||
} else if (message.author.id == conv[0].userid) {
|
||||
messages.push({ role: "user", content: message.content });
|
||||
i++;
|
||||
}
|
||||
});
|
||||
messages.reverse();
|
||||
messages.unshift({ role: "system", content: prompt });
|
||||
|
||||
message.channel.sendTyping().catch((err) => {
|
||||
sendLog(err);
|
||||
});
|
||||
|
||||
const response = await sendQuickConv(messages).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to send the request to the API."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
const prompt_usage = (response.data.usage.prompt_tokens * 0.001) / 1000;
|
||||
const completion_usage =
|
||||
(response.data.usage.completion_tokens * 0.002) / 1000;
|
||||
|
||||
await incrementQuota(
|
||||
message.author.id,
|
||||
prompt_usage + completion_usage
|
||||
).catch((err) => {
|
||||
sendLog(err);
|
||||
const embed = errorEmbed(
|
||||
"An error occured while trying to increment your quota."
|
||||
);
|
||||
return message.reply({ embeds: [embed] });
|
||||
});
|
||||
|
||||
if (response.data.choices[0].message.content.length <= 2000) {
|
||||
await message.reply(response.data.choices[0].message.content);
|
||||
} else {
|
||||
let paragraphs = response.data.choices[0].message.content.split("\n");
|
||||
messageText = "";
|
||||
|
||||
paragraphs.forEach((paragraph) => {
|
||||
if (`${messageText}${paragraph}`.length > 2000) {
|
||||
message.reply(messageText);
|
||||
messageText = `${paragraph}\n`;
|
||||
} else {
|
||||
messageText += `${paragraph}\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
const { Events } = require("discord.js");
|
||||
const { sendLog } = require("../libs/logs.js");
|
||||
|
||||
module.exports = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
execute(client) {
|
||||
console.log(`Ready! Logged in as ${client.user.tag}`);
|
||||
sendLog(`Ready! Logged in as ${client.user.tag}`);
|
||||
|
||||
client.user.setPresence({
|
||||
activities: [{ name: client.guilds.cache.size + " servers !", type: 3 }],
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
client.user.setPresence({
|
||||
activities: [
|
||||
{ name: client.guilds.cache.size + " servers !", type: 3 },
|
||||
],
|
||||
});
|
||||
}, 10000);
|
||||
},
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
const { EmbedBuilder } = require("discord.js");
|
||||
|
||||
function errorEmbed(error) {
|
||||
return new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(error)
|
||||
.setColor("#F6C6F9")
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
}
|
||||
|
||||
function convBeginEmbed() {
|
||||
return new EmbedBuilder()
|
||||
.setTitle("Conversation beginning")
|
||||
.setDescription(
|
||||
"Click on the button below or use the command **/closeconv** to close the conversation."
|
||||
)
|
||||
.setColor("#F6C6F9")
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
}
|
||||
|
||||
function convCreatedEmbed(channelId) {
|
||||
return new EmbedBuilder()
|
||||
.setTitle("Conversation created")
|
||||
.setDescription(`Your conversation has been created at <#${channelId}>.`)
|
||||
.setColor("#F6C6F9")
|
||||
.setFooter({ text: "Bot by @ninja_jambon" });
|
||||
}
|
||||
|
||||
function requestResponseEmbed(
|
||||
user,
|
||||
prompt,
|
||||
response,
|
||||
quota,
|
||||
prompt_usage,
|
||||
completion_usage
|
||||
) {
|
||||
return new EmbedBuilder()
|
||||
.setAuthor({
|
||||
name: user.username,
|
||||
iconURL:
|
||||
"https://cdn.discordapp.com/avatars/" +
|
||||
user.id +
|
||||
"/" +
|
||||
user.avatar +
|
||||
".jpeg",
|
||||
})
|
||||
.setTitle(prompt)
|
||||
.setDescription(response)
|
||||
.setFooter({
|
||||
text: `Quota used ${prompt_usage + completion_usage}$ | New quota: ${
|
||||
quota + prompt_usage + completion_usage
|
||||
}$ | Quota remaining : ${0.4 - prompt_usage - completion_usage}$`,
|
||||
})
|
||||
.setColor("#F6C6F9");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
errorEmbed,
|
||||
convBeginEmbed,
|
||||
convCreatedEmbed,
|
||||
requestResponseEmbed,
|
||||
};
|
20
libs/logs.js
20
libs/logs.js
|
@ -1,20 +0,0 @@
|
|||
const { EmbedBuilder, WebhookClient } = require("discord.js");
|
||||
|
||||
const webhookClient = new WebhookClient({
|
||||
url: `https://discord.com/api/webhooks/1187067107054202961/M7bsyOwFPMXQTMB8tvrWZu-gLT9rSjl1NASOBrz-z4lwvbwQ9To_yAywE_4aj5oGBP0D`,
|
||||
});
|
||||
|
||||
function sendLog(message) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("Log")
|
||||
.setDescription(message)
|
||||
.setColor(0x00ffff);
|
||||
|
||||
webhookClient.send({
|
||||
embeds: [embed],
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sendLog,
|
||||
};
|
110
libs/mysql.js
110
libs/mysql.js
|
@ -1,110 +0,0 @@
|
|||
var mysql = require("mysql");
|
||||
require("dotenv").config();
|
||||
|
||||
var con = mysql.createConnection({
|
||||
host: process.env.MYSQL_HOST,
|
||||
user: process.env.MYSQL_USER,
|
||||
password: process.env.MYSQL_PASSWORD,
|
||||
database: process.env.MYSQL_DATABASE,
|
||||
});
|
||||
|
||||
function registerUser(username, userid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`INSERT INTO users (username, userid, quota) VALUES ("${username}", "${userid}", 0)`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getUser(userid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`SELECT * FROM users WHERE userid = "${userid}"`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function incrementQuota(user, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`UPDATE users SET quota = quota + ${value} WHERE userid = "${user}"`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function addConv(userid, channelid, guildid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`INSERT INTO convs (userid, channelid, guildid) VALUES ("${userid}", "${channelid}", "${guildid}")`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function removeConv(channelid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`DELETE FROM convs WHERE channelid = "${channelid}"`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getConv(channelid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(
|
||||
`SELECT * FROM convs WHERE channelid = "${channelid}"`,
|
||||
(err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getQuotasSum() {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(`SELECT SUM(quota) FROM users`, (err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuotas() {
|
||||
return new Promise((resolve, reject) => {
|
||||
con.query(`UPDATE users SET quota = 0`, (err, result) => {
|
||||
if (err) reject(err);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerUser,
|
||||
getUser,
|
||||
incrementQuota,
|
||||
addConv,
|
||||
removeConv,
|
||||
getConv,
|
||||
getQuotasSum,
|
||||
resetQuotas,
|
||||
};
|
|
@ -1,84 +0,0 @@
|
|||
const { Configuration, OpenAIApi } = require("openai");
|
||||
const prompt = require("../data/prompt.json").prompt;
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: process.env.OPENAI,
|
||||
});
|
||||
|
||||
const openai = new OpenAIApi(configuration);
|
||||
|
||||
async function answerQuestion(query) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openai
|
||||
.createChatCompletion({
|
||||
model: "gpt-4-1106-preview",
|
||||
messages: [
|
||||
{ role: "system", content: prompt },
|
||||
{ role: "user", content: query },
|
||||
],
|
||||
temperature: 0.9,
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function quickAnswer(query) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openai
|
||||
.createChatCompletion({
|
||||
model: "gpt-3.5-turbo-1106",
|
||||
messages: [
|
||||
{ role: "system", content: prompt },
|
||||
{ role: "user", content: query },
|
||||
],
|
||||
temperature: 0.9,
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function sendConv(messages) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openai
|
||||
.createChatCompletion({
|
||||
model: "gpt-4-1106-preview",
|
||||
messages: messages,
|
||||
temperature: 0.9,
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function sendQuickConv(messages) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openai
|
||||
.createChatCompletion({
|
||||
model: "gpt-3.5-turbo-1106",
|
||||
messages: messages,
|
||||
temperature: 0.9,
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { answerQuestion, sendConv, quickAnswer, sendQuickConv };
|
|
@ -1,23 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const { resetQuotas } = require("./mysql.js");
|
||||
|
||||
function getLastResetDate() {
|
||||
const data = fs.readFileSync("./data/lastReset", "utf8");
|
||||
return parseInt(data);
|
||||
}
|
||||
|
||||
function checkLastResetDate() {
|
||||
const lastResetDate = getLastResetDate();
|
||||
const now = Date.now();
|
||||
|
||||
if (now - lastResetDate > 1000 * 60 * 60 * 24 * 30) {
|
||||
fs.writeFileSync("./data/lastReset", now.toString());
|
||||
return resetQuotas();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkLastResetDate,
|
||||
};
|
425
package-lock.json
generated
425
package-lock.json
generated
|
@ -1,123 +1,154 @@
|
|||
{
|
||||
"name": "chaise_bot_2.0",
|
||||
"version": "1.0.0",
|
||||
"name": "chaise_bot_3.0",
|
||||
"version": "3.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "chaise_bot_2.0",
|
||||
"version": "1.0.0",
|
||||
"name": "chaise_bot_3.0",
|
||||
"version": "3.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.7",
|
||||
"discord.js": "^14.12.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"mysql": "^2.18.1",
|
||||
"openai": "^3.3.0"
|
||||
"@mistralai/mistralai": "^0.1.3",
|
||||
"@types/mysql": "^2.15.26",
|
||||
"discord.js": "^14.14.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"mysql": "^2.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.4.tgz",
|
||||
"integrity": "sha512-ARFKvmAkLhfkQQiNxqi0YIWqwUExvBRtvdtMFVJXvJoibsGkFrB/DWTf9byU7BTVUfsmW8w7NM55tYXR5S/iSg==",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
|
||||
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.3.1",
|
||||
"@discordjs/util": "^1.0.0",
|
||||
"@sapphire/shapeshift": "^3.9.2",
|
||||
"discord-api-types": "^0.37.50",
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/shapeshift": "^3.9.3",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.3",
|
||||
"tslib": "^2.6.1"
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.2.tgz",
|
||||
"integrity": "sha512-LDplPy8SPbc8MYkuCdnLRGWqygAX97E8NH7gA9uz+NZ/hXknUKJHuxsOmhC6pmHnF9Zmg0kvfwrDjGsRIljt9g==",
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
|
||||
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz",
|
||||
"integrity": "sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==",
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
|
||||
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.37.41"
|
||||
"discord-api-types": "0.37.61"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.0.tgz",
|
||||
"integrity": "sha512-CW9ldfzsRzUbHcS4Oqu5+Moo+yrQ5qQ9groKNxPOzcoq2nuXa/fXOXkuQtQHcTeSVXsC9cmJ56M8gBDBUyLgGA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
|
||||
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^1.5.2",
|
||||
"@discordjs/util": "^1.0.0",
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@sapphire/snowflake": "^3.5.1",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "^0.37.50",
|
||||
"magic-bytes.js": "^1.0.15",
|
||||
"tslib": "^2.6.1",
|
||||
"undici": "^5.22.1"
|
||||
"discord-api-types": "0.37.61",
|
||||
"magic-bytes.js": "^1.5.0",
|
||||
"tslib": "^2.6.2",
|
||||
"undici": "5.27.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.0.tgz",
|
||||
"integrity": "sha512-U2Iiab0mo8cFe+o4ZY4GROoAetGjFYA1PhhxiXEW82LuPUjOU/seHZDtVjDpOf6n3rz4IRm84wNtgHdpqRY5CA==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
|
||||
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.0.tgz",
|
||||
"integrity": "sha512-POiImjuQJzwCxjJs4JCtDcTjzvjVsVQbnsaoW/F03yTVdrj/xSpmgv4383AnpNEYXI+CA6ggkz37phZDsZQ1NQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
|
||||
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^1.5.2",
|
||||
"@discordjs/rest": "^2.0.0",
|
||||
"@discordjs/util": "^1.0.0",
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@types/ws": "^8.5.5",
|
||||
"@types/ws": "^8.5.9",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "^0.37.50",
|
||||
"tslib": "^2.6.1",
|
||||
"ws": "^8.13.0"
|
||||
"discord-api-types": "0.37.61",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@mistralai/mistralai": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-0.1.3.tgz",
|
||||
"integrity": "sha512-WUHxC2xdeqX9PTXJEqdiNY54vT2ir72WSJrZTTBKRnkfhX6zIfCYA24faRlWjUB5WTpn+wfdGsTMl3ArijlXFA==",
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz",
|
||||
"integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==",
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz",
|
||||
"integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "3.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.2.tgz",
|
||||
"integrity": "sha512-YRbCXWy969oGIdqR/wha62eX8GNHsvyYi0Rfd4rNW6tSVVa8p0ELiMEuOH/k8rgtvRoM+EMV7Csqz77YdwiDpA==",
|
||||
"version": "3.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.6.tgz",
|
||||
"integrity": "sha512-4+Na/fxu2SEepZRb9z0dbsVh59QtwPuBg/UVaDib3av7ZY14b14+z09z6QVn0P6Dv6eOU2NDTsjIi0mbtgP56g==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
"node": ">=v18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
|
@ -129,43 +160,39 @@
|
|||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mysql": {
|
||||
"version": "2.15.26",
|
||||
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz",
|
||||
"integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz",
|
||||
"integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q=="
|
||||
"version": "20.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
|
||||
"integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz",
|
||||
"integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==",
|
||||
"version": "8.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
|
||||
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vladfrangu/async_event_emitter": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz",
|
||||
"integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==",
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz",
|
||||
"integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
|
||||
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.4",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
|
||||
|
@ -174,79 +201,49 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"dependencies": {
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.37.53",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.53.tgz",
|
||||
"integrity": "sha512-N6uUgv50OyP981Mfxrrt0uxcqiaNr0BDaQIoqfk+3zM2JpZtwU9v7ce1uaFAP53b2xSDvcbrk80Kneui6XJgGg=="
|
||||
"version": "0.37.61",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
|
||||
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw=="
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.12.1",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.12.1.tgz",
|
||||
"integrity": "sha512-gGjhTkauIPgFXxpBl0UZgyehrKhDe90cIS8Hn1xFBYQ63EuUAkKoUqRNmc/pcla6DD16s4cUz5tAbdSpXivnxw==",
|
||||
"version": "14.14.1",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
|
||||
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.6.4",
|
||||
"@discordjs/collection": "^1.5.2",
|
||||
"@discordjs/formatters": "^0.3.1",
|
||||
"@discordjs/rest": "^2.0.0",
|
||||
"@discordjs/util": "^1.0.0",
|
||||
"@discordjs/ws": "^1.0.0",
|
||||
"@sapphire/snowflake": "^3.5.1",
|
||||
"@types/ws": "^8.5.5",
|
||||
"discord-api-types": "^0.37.50",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"tslib": "^2.6.1",
|
||||
"undici": "^5.22.1",
|
||||
"ws": "^8.13.0"
|
||||
"@discordjs/builders": "^1.7.0",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@discordjs/ws": "^1.0.2",
|
||||
"@sapphire/snowflake": "3.5.1",
|
||||
"@types/ws": "8.5.9",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"tslib": "2.6.2",
|
||||
"undici": "5.27.2",
|
||||
"ws": "8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.3.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
|
||||
"integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
|
||||
"version": "16.4.5",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
||||
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
|
@ -254,38 +251,6 @@
|
|||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
||||
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
|
@ -307,28 +272,9 @@
|
|||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
|
||||
},
|
||||
"node_modules/magic-bytes.js": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.0.15.tgz",
|
||||
"integrity": "sha512-bpRmwbRHqongRhA+mXzbLWjVy7ylqmfMBYaQkSs6pac0z6hBTvsgrH0r4FBYd/UYVJBmS6Rp/O+oCCQVLzKV1g=="
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
|
||||
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
|
||||
},
|
||||
"node_modules/mysql": {
|
||||
"version": "2.18.1",
|
||||
|
@ -344,21 +290,23 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-3.3.0.tgz",
|
||||
"integrity": "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==",
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"axios": "^0.26.0",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/openai/node_modules/axios": {
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
|
@ -366,11 +314,6 @@
|
|||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
|
@ -398,14 +341,6 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
|
@ -414,36 +349,60 @@
|
|||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
|
||||
"integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ=="
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
||||
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
|
||||
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.23.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz",
|
||||
"integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==",
|
||||
"version": "5.27.2",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
|
||||
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
|
||||
"dependencies": {
|
||||
"busboy": "^1.6.0"
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||
"version": "8.14.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
|
||||
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
|
|
22
package.json
22
package.json
|
@ -1,19 +1,21 @@
|
|||
{
|
||||
"name": "chaise_bot",
|
||||
"version": "2.0.0",
|
||||
"name": "chaise_bot_3.0",
|
||||
"version": "3.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "nodemon bot.js",
|
||||
"start": "node bot.js"
|
||||
"dev": "tsx watch src",
|
||||
"build": "tsc",
|
||||
"start": "node dist"
|
||||
},
|
||||
"author": "Ninja Jambon",
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.7",
|
||||
"discord.js": "^14.12.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"mysql": "^2.18.1",
|
||||
"openai": "^3.3.0"
|
||||
"@mistralai/mistralai": "^0.1.3",
|
||||
"@types/mysql": "^2.15.26",
|
||||
"discord.js": "^14.14.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"mysql": "^2.18.1"
|
||||
}
|
||||
}
|
||||
|
|
7
src/@types/discord.d.ts
vendored
Normal file
7
src/@types/discord.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import type { Client } from 'discord.js'
|
||||
|
||||
declare module 'discord.js' {
|
||||
export interface Client extends Client {
|
||||
commands: Collection<unknown, any>
|
||||
}
|
||||
}
|
10
src/commands/default/ping.ts
Normal file
10
src/commands/default/ping.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { SlashCommandBuilder, CommandInteraction } from "discord.js";
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("ping")
|
||||
.setDescription("Replies with Pong!"),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
await interaction.reply("Pong!");
|
||||
},
|
||||
};
|
57
src/commands/singleRequests/ask.ts
Normal file
57
src/commands/singleRequests/ask.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { SlashCommandBuilder, ChatInputCommandInteraction } from "discord.js";
|
||||
import { getChatResponse, MistralMessage, Models, InputPrice, OutputPrice, ReturnedValue } from "../../libs/mistralai";
|
||||
import { User, connectToDb, addUser, getUser, incrementQuota } from "../../libs/mysql";
|
||||
|
||||
const data = require("../../../config.json");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("ask")
|
||||
.setDescription("Make a single request to mistral API")
|
||||
.setDMPermission(false)
|
||||
.addStringOption(option =>
|
||||
option.setName("prompt").setDescription("The prompt to send to the API").setRequired(true)
|
||||
),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
if (interaction.member?.user.id != '372437660167438337') {
|
||||
return interaction.reply("you are not allowed to use this command");
|
||||
}
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
const connection = await connectToDb();
|
||||
|
||||
var user: User[] = await getUser(connection, interaction.member?.user.id);
|
||||
|
||||
if (!user[0]) {
|
||||
await addUser(connection, interaction.member?.user.username, interaction.member?.user.id);
|
||||
user = await getUser(connection, interaction.member?.user.id);
|
||||
}
|
||||
|
||||
if (user[0].quota > 0.4) {
|
||||
interaction.editReply("You have exceed your quota.")
|
||||
connection.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const prompt: string | null = interaction.options.getString("prompt");
|
||||
|
||||
const messages: MistralMessage[] = [
|
||||
{
|
||||
role: "system",
|
||||
content: data.defaultPrompt
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: prompt ? prompt : ""
|
||||
},
|
||||
]
|
||||
|
||||
const response: ReturnedValue = await getChatResponse(messages, Models.multi_tiny);
|
||||
|
||||
await incrementQuota(connection, interaction.member?.user.id, InputPrice.multi_tiny * response.promptUsage + OutputPrice.multi_tiny * response.responseUsage);
|
||||
connection.end();
|
||||
|
||||
interaction.editReply(response.message);
|
||||
},
|
||||
};
|
1
src/data/lastreset.txt
Normal file
1
src/data/lastreset.txt
Normal file
|
@ -0,0 +1 @@
|
|||
1709247600
|
21
src/events/interactionCreate.ts
Normal file
21
src/events/interactionCreate.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Events, Interaction } from "discord.js";
|
||||
|
||||
module.exports = {
|
||||
name: Events.InteractionCreate,
|
||||
async execute(interaction: Interaction) {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
return console.error(`No command matching ${interaction.commandName} was found.`);
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
43
src/events/messageCreate.ts
Normal file
43
src/events/messageCreate.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { Events, Message } from "discord.js";
|
||||
import { getChatResponse, MistralMessage, Models, InputPrice, OutputPrice, ReturnedValue } from "../libs/mistralai";
|
||||
import { User, connectToDb, addUser, getUser, incrementQuota } from "../libs/mysql";
|
||||
import { getMessages } from "../libs/discord";
|
||||
|
||||
module.exports = {
|
||||
name: Events.MessageCreate,
|
||||
async execute(message: Message) {
|
||||
if (!message.guildId && message.author.id != process.env.BOT_ID) {
|
||||
const prompt: string = message.content;
|
||||
|
||||
if (message.author.id != '372437660167438337') {
|
||||
return message.reply("you are not allowed to use this command");
|
||||
}
|
||||
|
||||
const connection = await connectToDb();
|
||||
|
||||
var user: User[] = await getUser(connection, message.author.id);
|
||||
|
||||
if (!user[0]) {
|
||||
await addUser(connection, message.author.username, message.author.id);
|
||||
user = await getUser(connection, message.author.id);
|
||||
}
|
||||
|
||||
if (user[0].quota > 0.4) {
|
||||
message.reply("You have exceed your quota.")
|
||||
connection.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const messages: MistralMessage[] = await getMessages(message, message.channelId, message.author.id);
|
||||
|
||||
await message.channel.sendTyping();
|
||||
|
||||
const response: ReturnedValue = await getChatResponse(messages, Models.multi_tiny);
|
||||
|
||||
await incrementQuota(connection, message.author.id, InputPrice.multi_tiny * response.promptUsage + OutputPrice.multi_tiny * response.responseUsage);
|
||||
connection.end();
|
||||
|
||||
message.reply(response.message);
|
||||
}
|
||||
},
|
||||
};
|
14
src/events/ready.ts
Normal file
14
src/events/ready.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { Events, Client } from "discord.js";
|
||||
import { checkReset } from "../libs/quotaReset";
|
||||
|
||||
module.exports = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
execute(client: Client) {
|
||||
console.log(`Ready! Logged in as ${client.user?.tag}`);
|
||||
|
||||
setInterval(async () => {
|
||||
await checkReset();
|
||||
}, 10 * 60 * 1000);
|
||||
},
|
||||
};
|
77
src/index.ts
Normal file
77
src/index.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import "dotenv/config";
|
||||
import { Client, Collection, REST, Routes, RESTPutAPIApplicationCommandsResult, GatewayIntentBits, Partials } from 'discord.js';
|
||||
|
||||
const client: Client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent,
|
||||
GatewayIntentBits.DirectMessages,
|
||||
],
|
||||
partials: [
|
||||
Partials.Channel,
|
||||
Partials.Message,
|
||||
]
|
||||
})
|
||||
|
||||
client.commands = new Collection();
|
||||
const commands = [];
|
||||
const foldersPath = path.join(__dirname, "commands");
|
||||
const commandFolders = fs.readdirSync(foldersPath);
|
||||
|
||||
for (const folder of commandFolders) {
|
||||
const commandsPath = path.join(foldersPath, folder);
|
||||
const commandFiles = fs
|
||||
.readdirSync(commandsPath)
|
||||
.filter((file) => file.endsWith(".ts") || file.endsWith(".js"));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
const command = require(filePath);
|
||||
if ("data" in command && "execute" in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
commands.push(command.data.toJSON());
|
||||
}
|
||||
else {
|
||||
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rest = new REST().setToken(process.env.DISCORD_TOKEN ? process.env.DISCORD_TOKEN : "");
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(process.env.BOT_ID ? process.env.BOT_ID : ""),
|
||||
{ body: commands }
|
||||
);
|
||||
|
||||
console.log(`Successfully reloaded ${commands.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
|
||||
const eventsPath = path.join(__dirname, "events");
|
||||
const eventFiles = fs
|
||||
.readdirSync(eventsPath)
|
||||
.filter((file) => file.endsWith(".ts") || file.endsWith(".js"));
|
||||
|
||||
for (const file of eventFiles) {
|
||||
const filePath = path.join(eventsPath, file);
|
||||
const event = require(filePath);
|
||||
|
||||
if (event.once) {
|
||||
client.once(event.name, (...args) => event.execute(...args));
|
||||
}
|
||||
else {
|
||||
client.on(event.name, (...args) => event.execute(...args));
|
||||
}
|
||||
}
|
||||
|
||||
client.login(process.env.DISCORD_TOKEN);
|
27
src/libs/discord.ts
Normal file
27
src/libs/discord.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { Events, Message, Collection } from "discord.js";
|
||||
import { getChatResponse, MistralMessage, Models, InputPrice, OutputPrice, ReturnedValue } from "../libs/mistralai";
|
||||
import { User, connectToDb, addUser, getUser, incrementQuota } from "../libs/mysql";
|
||||
|
||||
const data = require("../../config.json");
|
||||
|
||||
export async function getMessages(message: Message, channelid: string, userid: string): Promise<MistralMessage[]> {
|
||||
var discordMessages = await message.channel.messages.fetch({ limit: 7 })
|
||||
discordMessages.filter((m) => m.content && (m.author.id == message.author.id || m.author.id == process.env.BOT_ID))
|
||||
discordMessages.reverse();
|
||||
|
||||
var messages: MistralMessage[] = [
|
||||
{
|
||||
role: "system",
|
||||
content: data.defaultPrompt
|
||||
}
|
||||
]
|
||||
|
||||
discordMessages.forEach(discordMessage => {
|
||||
messages.push({
|
||||
role: discordMessage.author.id == process.env.BOT_ID ? "assistant" : "user",
|
||||
content: discordMessage.content,
|
||||
})
|
||||
})
|
||||
|
||||
return messages;
|
||||
}
|
54
src/libs/mistralai.ts
Normal file
54
src/libs/mistralai.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import MistralClient from '@mistralai/mistralai';
|
||||
import "dotenv/config";
|
||||
|
||||
export interface MistralMessage {
|
||||
role: string,
|
||||
content: string,
|
||||
}
|
||||
|
||||
export enum Models {
|
||||
tiny = "open-mistral-7b",
|
||||
multi_tiny = "open-mixtral-8x7b",
|
||||
small = "mistral-small-latest",
|
||||
medium = "mistral-medium-latest",
|
||||
large = "mistral-large-latest",
|
||||
}
|
||||
|
||||
export enum InputPrice {
|
||||
tiny = 0.25 / 1000000,
|
||||
multi_tiny = 0.7 / 1000000,
|
||||
small = 2 / 1000000,
|
||||
medium = 2.7 / 1000000,
|
||||
large = 8 / 1000000,
|
||||
}
|
||||
|
||||
export enum OutputPrice {
|
||||
tiny = 0.25 / 1000000,
|
||||
multi_tiny = 0.7 / 1000000,
|
||||
small = 6 / 1000000,
|
||||
medium = 8.1 / 1000000,
|
||||
large = 24 / 1000000,
|
||||
}
|
||||
|
||||
export interface ReturnedValue {
|
||||
message: string,
|
||||
promptUsage: number,
|
||||
responseUsage: number,
|
||||
}
|
||||
|
||||
const apiKey = process.env.MISTRAL_API_KEY;
|
||||
|
||||
const client = new MistralClient(apiKey);
|
||||
|
||||
export async function getChatResponse(messages: MistralMessage[], model: Models): Promise<ReturnedValue> {
|
||||
const chatResponse = await client.chat({
|
||||
model: model,
|
||||
messages: messages,
|
||||
});
|
||||
|
||||
return {
|
||||
message: chatResponse.choices[0].message.content,
|
||||
promptUsage: chatResponse.usage.prompt_tokens,
|
||||
responseUsage: chatResponse.usage.completion_tokens,
|
||||
};
|
||||
}
|
75
src/libs/mysql.ts
Normal file
75
src/libs/mysql.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
import * as mysql from "mysql";
|
||||
|
||||
export interface User {
|
||||
id: number,
|
||||
username: string,
|
||||
userid: string,
|
||||
quota: number,
|
||||
}
|
||||
|
||||
export async function connectToDb(): Promise<mysql.Connection> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const connection: mysql.Connection = mysql.createConnection({
|
||||
host: process.env.MYSQL_HOST,
|
||||
user: process.env.MYSQL_USER,
|
||||
password: process.env.MYSQL_PASSWORD,
|
||||
database: process.env.MYSQL_DATABASE,
|
||||
})
|
||||
|
||||
connection.connect((error) => {
|
||||
if (error) {
|
||||
reject(error)
|
||||
}
|
||||
|
||||
resolve(connection);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export async function addUser(connection: mysql.Connection, username: string, userid: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.query(`INSERT INTO users (username, userid, quota) VALUES ("${username}", "${userid}", 0)`, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function getUser(connection: mysql.Connection, userid: string): Promise<User[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.query(`SELECT * FROM users WHERE userid = "${userid}"`, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function incrementQuota(connection: mysql.Connection, userid: string, value: number): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.query(`UPDATE users SET quota = quota + ${value} WHERE userid = "${userid}"`, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function resetQuota(connection: mysql.Connection) {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.query(`UPDATE users SET quota = 0`, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
})
|
||||
})
|
||||
}
|
26
src/libs/quotaReset.ts
Normal file
26
src/libs/quotaReset.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import * as fs from "fs";
|
||||
import { connectToDb, resetQuota } from "./mysql";
|
||||
|
||||
function getLastResetDate(): number {
|
||||
const data: string = fs.readFileSync("../data/lastreset.txt", "utf8");
|
||||
return parseInt(data);
|
||||
}
|
||||
|
||||
export async function checkReset() {
|
||||
const lastResetDate = getLastResetDate();
|
||||
const now = Date.now() / 1000;
|
||||
|
||||
if (now - lastResetDate > 1000 * 60 * 60 * 24 * 30) {
|
||||
fs.writeFileSync("../data/lastreset.txt", now.toString());
|
||||
|
||||
const connection = await connectToDb();
|
||||
|
||||
await resetQuota(connection);
|
||||
|
||||
connection.end();
|
||||
|
||||
return;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"outDir": "./dist",
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": true,
|
||||
},
|
||||
"include": ["src"],
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue