rayai/bot/discord-bot-groq.js
2024-10-04 21:06:44 -04:00

201 lines
7.0 KiB
JavaScript

const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');
const axios = require('axios');
const he = require('he');
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
const { userResetMessages } = require('./assets/messages.js');
const cheerio = require('cheerio');
require('dotenv').config();
const channelIDs = process.env.CHANNEL_IDS.split(',');
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent]
});
const MAX_CONTENT_LENGTH = process.env.MAX_CONTENT_LENGTH || 8000;
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async message => {
if (message.guildId == "1192181551526584380") return
if (message.content.includes("[LOG]")) return
console.log(`Received message: ${message.content}, from ${message.author.tag}, in channel: ${message.channel.name}`);
console.log(message.guildId)
// Function to send a random message from any array
async function sendRand(array) {
const arrayChoice = array[Math.floor(Math.random() * array.length)];
console.log(`Sending random response: ${arrayChoice}`);
await message.channel.send(arrayChoice); // give a notification of reset using a human-like response.
}
if (message.author.bot) return;
// Only respond in the specified channels
if (!channelIDs.includes(message.channel.id)) {
console.log(`Ignoring message from channel: ${message.channel.id}, not in the specified channels.`);
return;
}
const content = message.content.trim();
let additionalContent = '';
if (content === '!r' || content === '!reset') {
console.log("Reset command received.");
await resetConversation(message);
// Handle conversation reset
return await sendRand(userResetMessages);
}
if (content === '!restartCore') {
console.log("Restart core command received.");
// Handle core restart
return await restartCore(message);
}
console.log(`Handling user message: ${content}`);
await handleUserMessage(message, content, additionalContent);
});
async function handleUserMessage(message, content, additionalContent) {
const encodedMessage = he.encode(content + additionalContent);
console.log(`Encoded message: ${encodedMessage}`);
const typingInterval = setInterval(() => {
message.channel.sendTyping();
}, 9000);
message.channel.sendTyping(); // Initial typing indicator
try {
console.log(`Sending message to API at: http://${process.env.ROOT_IP}:${process.env.ROOT_PORT}/api/v1/chat`);
const response = await axios.post(`http://${process.env.ROOT_IP}:${process.env.ROOT_PORT}/api/v1/chat`, {
message: encodedMessage,
max_tokens: Number(process.env.MAX_TOKENS),
repeat_penalty: Number(process.env.REPEAT_PENALTY)
}, {
headers: {
'Content-Type': 'application/json',
'x-forwarded-for-id': message.author.id,
'x-forwarded-for-name': message.author.username,
'x-forwarded-for-guild': message.guild.name
}
});
console.log("API response received:", response.data);
// If response.data is a string (no 'content' property), use it directly
const responseText = typeof response.data === 'string' ? response.data : response.data.content;
if (!responseText) {
console.error("No content found in API response.");
return message.channel.send("Oops, something went wrong. No response content.");
}
clearInterval(typingInterval); // Stop typing indicator
await sendLongMessage(message, responseText);
} catch (error) {
console.error("Error during API call:", error.message);
clearInterval(typingInterval); // Stop typing indicator
if (error.response && error.response.status === 429) {
console.log("API rate limited, trying to send DM.");
try {
await message.author.send('I am currently busy. Please try again later.');
} catch (dmError) {
console.error('Failed to send DM:', dmError);
message.reply('I am currently busy. Please try again later.');
}
} else {
message.reply('Error: ' + error.message);
}
}
}
async function resetConversation(message) {
try {
console.log("Resetting conversation...");
const response = await axios.post(
`${process.env.API_PATH}/reset-conversation`, {}, {
headers: {
'Content-Type': 'application/json',
'x-forwarded-for-id': message.author.id,
'x-forwarded-for-name': message.author.username,
'x-forwarded-for-guild': message.guild.name
}
}
);
console.log(`Reset conversation status: ${response.status}`);
} catch (error) {
console.error("Error during reset conversation:", error);
}
}
async function restartCore(message) {
try {
console.log("Restarting core...");
const response = await axios.post(`${process.env.API_PATH}/restart-core`);
console.log(`Core restart status: ${response.status}`);
} catch (error) {
console.error("Error during core restart:", error);
}
}
async function sendLongMessage(message, responseText) {
console.log(`Preparing to send response. Length: ${responseText ? responseText.length : 'undefined'}`);
const limit = 8096;
if (!responseText) {
console.error("Response text is undefined or null.");
return message.channel.send("Oops, I didn't get any response. Please try again.");
}
if (responseText.length > limit) {
console.log("Response too long, splitting into chunks...");
const lines = responseText.split('\n');
const chunks = [];
let currentChunk = '';
for (const line of lines) {
if (currentChunk.length + line.length > limit) {
chunks.push(currentChunk);
currentChunk = '';
}
currentChunk += line + '\n';
}
if (currentChunk.trim() !== '') {
chunks.push(currentChunk.trim());
}
if (chunks.length >= 80) return await message.channel.send("Response chunks too large. Try again");
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const embed = new EmbedBuilder()
.setDescription(chunk) // Wraps the chunk in a code block
.setColor("#3498DB")
.setTimestamp();
console.log(`Sending chunk ${i + 1}/${chunks.length}`);
setTimeout(() => {
message.channel.send({
embeds: [embed]
});
}, i * (process.env.OVERFLOW_DELAY || 3) * 1000);
}
} else {
console.log("Response fits within limit, sending single message.");
const embed = new EmbedBuilder()
.setDescription(responseText) // Wraps the response in a code block
.setColor("#3498DB")
.setTimestamp();
message.channel.send({
embeds: [embed]
});
}
}
client.login(process.env.THE_TOKEN);