Add User Installable App
This commit is contained in:
parent
a20e8c182f
commit
a58353b9c3
@ -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
207
bot/installableApp.js
Normal 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);
|
3
bot/userPrivacySettings.json
Normal file
3
bot/userPrivacySettings.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"342128351638585344": true
|
||||
}
|
Loading…
Reference in New Issue
Block a user