Add User Installable App

This commit is contained in:
Raven 2024-10-02 01:01:19 -04:00
parent a20e8c182f
commit a58353b9c3
3 changed files with 212 additions and 2 deletions

View File

@ -45,7 +45,7 @@ app.use((req, res, next) => {
conversationHistory[req.clientIp] = [{
role: 'system',
content: `My name is: ${name}, We are chatting inside ${guild} a Discord Server. ` + prompt
content: `My name is: ${name}, my Discord ID is ${req.clientIp}, We are chatting inside ${guild} a Discord Server. ` + prompt
}];
} else {
@ -553,7 +553,7 @@ app.post('/api/v1/reset-conversation', (req, res) => {
conversationHistory[req.clientIp] = [{
role: 'system',
content: `My name is: ${name}, We are chatting inside ${guild} a Discord Server. ` + prompt
content: `My name is: ${name}, my Discord ID is: ${req.clientIp}, We are chatting inside ${guild} a Discord Server. ` + prompt
}];
} else {

207
bot/installableApp.js Normal file
View File

@ -0,0 +1,207 @@
const { Client, GatewayIntentBits, REST, Routes, EmbedBuilder, SlashCommandBuilder } = require('discord.js');
const axios = require('axios');
const he = require('he');
const fs = require('fs');
require('dotenv').config();
const { userResetMessages } = require('./assets/messages.js');
const client = new Client({
intents: [GatewayIntentBits.Guilds]
});
// Load or initialize the user privacy settings
const userPrivacyFilePath = './userPrivacySettings.json';
let userPrivacySettings = {};
if (fs.existsSync(userPrivacyFilePath)) {
userPrivacySettings = JSON.parse(fs.readFileSync(userPrivacyFilePath));
}
// Save the user privacy settings
function saveUserPrivacySettings() {
fs.writeFileSync(userPrivacyFilePath, JSON.stringify(userPrivacySettings, null, 2));
}
// Define the commands
const commands = [
new SlashCommandBuilder().setName('reset').setDescription('Reset the conversation'),
new SlashCommandBuilder().setName('restartcore').setDescription('Restart the core service'),
new SlashCommandBuilder().setName('chat').setDescription('Send a chat message')
.addStringOption(option =>
option.setName('message')
.setDescription('Message to send')
.setRequired(true)),
new SlashCommandBuilder().setName('privacy').setDescription('Toggle between ephemeral and standard responses')
].map(command => {
const commandJSON = command.toJSON();
const extras = {
"integration_types": [0, 1], // 0 for guild, 1 for user
"contexts": [0, 1, 2] // 0 for guild, 1 for app DMs, 2 for GDMs and other DMs
};
Object.keys(extras).forEach(key => commandJSON[key] = extras[key]);
return commandJSON;
});
// Register commands with Discord
const rest = new REST({ version: '10' }).setToken(process.env.THE_TOKEN_2);
client.once('ready', async () => {
try {
console.log(`Logged in as ${client.user.tag}!`);
await rest.put(Routes.applicationCommands(process.env.DISCORD_CLIENT_ID), { body: commands });
console.log('Successfully registered application commands with extras.');
} catch (error) {
console.error('Error registering commands: ', error);
}
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName, options } = interaction;
if (commandName === 'reset') {
return await resetConversation(interaction);
} else if (commandName === 'restartcore') {
await restartCore(interaction);
} else if (commandName === 'chat') {
const content = options.getString('message');
await handleUserMessage(interaction, content);
} else if (commandName === 'privacy') {
await togglePrivacy(interaction);
}
});
// Toggle privacy for the user
async function togglePrivacy(interaction) {
const userId = interaction.user.id;
const currentSetting = userPrivacySettings[userId] || false;
userPrivacySettings[userId] = !currentSetting; // Toggle the setting
saveUserPrivacySettings();
const message = userPrivacySettings[userId]
? 'Your responses are now set to ephemeral (visible only to you).'
: 'Your responses are now standard (visible to everyone).';
await interaction.reply({ content: message, ephemeral: true });
}
// Check if the user's responses should be ephemeral
function isEphemeral(userId) {
return userPrivacySettings[userId] || false; // Default to false (standard response) if not set
}
async function handleUserMessage(interaction, content) {
const encodedMessage = he.encode(content);
// Start typing indicator
await interaction.deferReply({ ephemeral: isEphemeral(interaction.user.id) });
try {
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': interaction.user.id,
'x-forwarded-for-name': interaction.user.username
}
});
const data = response.data;
await sendLongMessage(interaction, data.content);
} catch (error) {
if (error.response && error.response.status === 429) {
try {
await interaction.editReply({ content: 'I am currently busy. Please try again later.', ephemeral: isEphemeral(interaction.user.id) });
} catch (dmError) {
console.error('Failed to send DM:', dmError);
interaction.editReply({ content: 'I am currently busy. Please try again later.', ephemeral: isEphemeral(interaction.user.id) });
}
} else {
interaction.editReply({ content: 'Error: ' + error.message, ephemeral: isEphemeral(interaction.user.id) });
}
}
}
async function resetConversation(interaction) {
try {
const response = await axios.post(`${process.env.API_PATH}/reset-conversation`, {}, {
headers: {
'Content-Type': 'application/json',
'x-forwarded-for-id': interaction.user.id,
'x-forwarded-for-name': interaction.user.username
}
});
console.log(response.status);
interaction.reply({ content: 'Conversation reset successfully.', ephemeral: isEphemeral(interaction.user.id) });
} catch (error) {
console.log(error);
interaction.reply({ content: 'Failed to reset the conversation.', ephemeral: isEphemeral(interaction.user.id) });
}
}
async function restartCore(interaction) {
try {
await axios.post(`${process.env.API_PATH}/restart-core`);
interaction.reply({ content: 'Core service restarted successfully.', ephemeral: isEphemeral(interaction.user.id) });
} catch (error) {
console.log(error);
interaction.reply({ content: 'Failed to restart the core.', ephemeral: isEphemeral(interaction.user.id) });
}
}
async function sendLongMessage(interaction, responseText) {
const limit = 8096;
if (responseText.length > limit) {
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 interaction.reply({ content: "Response chunks too large. Try again", ephemeral: isEphemeral(interaction.user.id) });
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const embed = new EmbedBuilder()
.setDescription(chunk)
.setColor("#3498DB")
.setTimestamp();
setTimeout(() => {
interaction.followUp({
embeds: [embed],
ephemeral: isEphemeral(interaction.user.id)
});
}, i * (process.env.OVERFLOW_DELAY || 3) * 1000);
}
} else {
const embed = new EmbedBuilder()
.setDescription(responseText)
.setColor("#3498DB")
.setTimestamp();
interaction.editReply({
embeds: [embed],
ephemeral: isEphemeral(interaction.user.id)
});
}
}
// Log in the bot
client.login(process.env.THE_TOKEN_2);

View File

@ -0,0 +1,3 @@
{
"342128351638585344": true
}