AI_botter/events/messageCreate.js
DeathbotGaming 961f8b00d1
Ai-Bot
V1.0.0
2024-03-01 02:09:57 -09:00

372 lines
No EOL
14 KiB
JavaScript

const Discord = require('discord.js');
const openAI = require('openai');
const chalk = require('chalk');
const ms = require('ms');
const fs = require('node:fs');
const func = require('../utils/functions');
const settings = require('../utils/settings');
const config = require('../configs/config.json');
const { moderation } = require('../configs/moderation');
const { chatbot } = require('../configs/chatbot');
const conversations = new Map();
module.exports = async (client, message) => {
if (message.channel.type === Discord.ChannelType.DM || message.author.bot || message.system) return;
// Auto Moderation
if (moderation.State && !moderation.IgnoredChannels.includes(message.channelId) && !moderation.IgnoredUsers.includes(message.author.id)) {
const logChannel = client.channels.cache.get(moderation.LogChannel);
if (logChannel?.permissionsFor(message.guild.members.me).has("ViewChannel", "SendMessages", "EmbedLinks")) {
const openai = new openAI.OpenAI({ apiKey: config.OpenAIapiKey });
openai.moderations.create({
model: 'text-moderation-stable',
input: message.content
}).then(async (response) => {
const data = response.results[0];
if (data.flagged) {
const flags = func.flagCheck(data.categories);
const trueFlags = Object.keys(flags.flags).filter(key => flags.flags[key]);
const sameFlagsWithAutoDelete = trueFlags.filter(key => moderation.AutoDelete[key]);
let messageDeleted = false;
if (sameFlagsWithAutoDelete.length) {
if (message.channel?.permissionsFor(message.guild.members.me).has("ManageMessages")) {
await message.delete().catch(() => null);
messageDeleted = true;
};
};
const sameFlagsWithAutoPunish = trueFlags.filter(key => moderation.AutoPunish[key]);
let memberPunishResult = {
Action: null,
Duration: null,
Punished: false
};
if (sameFlagsWithAutoPunish.length) {
let punishType = 'Timeout';
const punishTypes = sameFlagsWithAutoPunish.map(key => moderation.AutoPunishType[key]);
if (punishTypes.includes('Ban')) punishType = 'Ban';
else if (punishTypes.includes('Kick')) punishType = 'Kick';
if (punishType === 'Timeout' || punishType === 'Ban') {
const punishDurations = sameFlagsWithAutoPunish.filter(key => moderation.AutoPunishType[key] === punishType).map(key => moderation.AutoPunishDuration[key]);
let duration;
if (punishDurations.length > 1) {
const mappedDurations = punishDurations.map(d => ms(d));
duration = Math.max(...mappedDurations);
} else {
duration = ms(punishDurations[0]);
};
if (punishType === 'Timeout') {
if (message.member.moderatable) {
try {
await message.member.timeout(duration, 'Auto Mod');
memberPunishResult = {
Action: punishType,
Duration: duration,
Punished: true
};
} catch (error) {
console.error(chalk.bold.redBright(error));
};
};
} else if (punishType === 'Ban') {
if (message.member.bannable) {
try {
await message.member.ban({ deleteMessageSeconds: duration / 1000, reason: 'Auto Mod' });
memberPunishResult = {
Action: punishType,
Duration: duration,
Punished: true
};
} catch (error) {
console.error(chalk.bold.redBright(error));
};
};
};
} else if (punishType === 'Kick') {
if (message.member.kickable) {
try {
await message.member.kick('Auto Mod');
memberPunishResult = {
Action: punishType,
Duration: null,
Punished: true
};
} catch (error) {
console.error(chalk.bold.redBright(error));
};
};
};
};
const logEmbed = new Discord.EmbedBuilder()
.setColor(moderation.LogColor)
.setAuthor({
name: message.author.tag,
iconURL: message.author.displayAvatarURL()
})
.setDescription(`||${message.content}||`)
.setFields(
{
name: 'User:',
value: func.userInfo(message.author)
},
{
name: 'Channel:',
value: func.channelInfo(message.channel)
},
{
name: 'Flags:',
value: flags.allFlags
}
);
if (messageDeleted) {
logEmbed.addFields({
name: 'Message Action:',
value: `Message deleted automatically.`
});
};
let buttons = [];
if (memberPunishResult.Punished) {
let fieldValue;
if (memberPunishResult.Action === 'Timeout') fieldValue = `${message.author.tag} timed out automatically for ${ms(memberPunishResult.Duration, { long: true })}`;
else if (memberPunishResult.Action === 'Ban') fieldValue = `${message.author.tag} banned automatically and all their messages in the last ${ms(memberPunishResult.Duration, { long: true })} were deleted.`;
else if (memberPunishResult.Action === 'Kick') fieldValue = `${message.author.tag} kicked automatically `;
logEmbed.addFields({
name: 'Punish Action:',
value: fieldValue
});
if (!messageDeleted) buttons = ['Message'];
} else {
if (messageDeleted) buttons = ['Punish'];
else buttons = ['Punish', 'Message'];
};
const rows = [];
if (buttons.includes('Punish')) {
const timeoutButton = new Discord.ButtonBuilder()
.setLabel('Timeout')
.setStyle(Discord.ButtonStyle.Danger)
.setCustomId(`timeout-${message.author.id}`);
const kickButton = new Discord.ButtonBuilder()
.setLabel('Kick')
.setStyle(Discord.ButtonStyle.Danger)
.setCustomId(`kick-${message.author.id}`);
const banButton = new Discord.ButtonBuilder()
.setLabel('Ban')
.setStyle(Discord.ButtonStyle.Danger)
.setCustomId(`ban-${message.author.id}`);
const punishRow = new Discord.ActionRowBuilder()
.addComponents([
timeoutButton,
kickButton,
banButton
]);
rows.push(punishRow);
};
if (buttons.includes('Message')) {
const deleteMessageButton = new Discord.ButtonBuilder()
.setLabel(`Delete Flagged Message`)
.setStyle(Discord.ButtonStyle.Danger)
.setCustomId(`deleteMessage-${message.channelId}-${message.id}`);
const jumpButton = new Discord.ButtonBuilder()
.setLabel(`Jump to Flagged Message`)
.setStyle(Discord.ButtonStyle.Link)
.setURL(message.url);
const messageRow = new Discord.ActionRowBuilder()
.addComponents([
deleteMessageButton,
jumpButton
]);
rows.push(messageRow);
};
await logChannel.send({
embeds: [logEmbed],
components: rows
});
};
}).catch(async (error) => {
console.error(chalk.bold.redBright(error));
});
};
};
// ChatBot
if (chatbot.State && chatbot.AllowedChannels.includes(message.channel.name) && !chatbot.IgnoredUsers.includes(message.author.id)) {
await message.channel.sendTyping();
const openai = new openAI.OpenAI({ apiKey: config.OpenAIapiKey });
const question = message.content;
const completionPrompt = fs.readFileSync("./utils/prompts/completion.txt", "utf-8");
const prompt = completionPrompt.replaceAll('{botUsername}', client.user.username);
let messages = [{
"role": "system",
"content": prompt
}];
let oldMessages;
if (conversations.has(message.author.id)) oldMessages = conversations.get(message.author.id);
if (oldMessages) {
// If there are old messages, check if they exceed token limit
while (func.tokenizer('gpt-3.5-turbo-0125', oldMessages).tokens >= 512) {
let sliceLength = oldMessages.length * -0.5;
if (sliceLength % 2 !== 0) sliceLength--;
oldMessages = oldMessages.slice(sliceLength);
// Update the conversation history in the map
conversations.set(message.author.id, oldMessages);
}
// Concatenate old messages with the current message
messages = messages.concat(oldMessages);
}
messages.push({
"role": "user",
"content": question
});
openai.chat.completions.create({
model: 'gpt-3.5-turbo-0125',
messages: messages,
max_tokens: func.tokenizer('gpt-3.5-turbo-0125', messages).maxTokens,
temperature: settings.completion.temprature,
top_p: settings.completion.top_p,
frequency_penalty: settings.completion.frequency_penalty,
presence_penalty: settings.completion.presence_penalty,
stream: true
}).then(async (response) => {
// Initialize an array to hold all response parts
let responseParts = [];
for await (const part of response) {
// Accumulate response parts
responseParts.push(part.choices[0]?.delta?.content || '');
}
// Combine all response parts into a single string
let fullAnswer = responseParts.join('');
// Trim the response content to fit within the maximum embed description length
if (fullAnswer.length > 4096) {
fullAnswer = fullAnswer.slice(0, 4093) + '...';
}
// Send the combined response as an embed
const embed = {
color: 0x0099ff,
title: 'Assisto',
description: fullAnswer
};
// Send the embed
await message.channel.send({ embeds: [embed] });
// Update the conversation history in the map with the new message
conversations.set(message.author.id, messages.concat([{ "role": "assistant", "content": fullAnswer }]));
}).catch(async (error) => {
console.error(chalk.bold.redBright(error));
if (error.response) await message.reply({ content: error.response.error.message.length > 4000 ? error.response.error.message.substring(0, 3097) + "..." : error.response.error.message });
else if (error.message) await message.reply({ content: error.message.length > 4000 ? error.message.substring(0, 3097) + "..." : error.message });
});
}
// Command Handler
if (message.content.toLowerCase().startsWith(config.Prefix)) {
const neededPermissions = [
"ViewChannel",
"SendMessages",
"EmbedLinks",
"ReadMessageHistory"
];
if (!message.channel.permissionsFor(message.guild.members.me).has(neededPermissions)) return;
const args = message.content.slice(config.Prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.MessageCommands.get(cmd) || client.MessageCommands.find(c => c.aliases && c.aliases.map(a => a.toLowerCase()).includes(cmd));
if (command) {
try {
command.execute(client, message, args, cmd);
} catch (error) {
console.error(chalk.bold.redBright(error));
};
};
};
};