fix user installable bot - if no container is running let the user know
This commit is contained in:
parent
b9e5f78e14
commit
243128e925
55
user-bot.js
55
user-bot.js
@ -3,9 +3,10 @@ import jsonfile from 'jsonfile';
|
|||||||
import unirest from 'unirest';
|
import unirest from 'unirest';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import mysql from 'mysql2';
|
import mysql from 'mysql2';
|
||||||
const userWorkingDirectories = new Map();
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import cmd from 'cmd-promise';
|
import cmd from 'cmd-promise';
|
||||||
|
|
||||||
|
const userWorkingDirectories = new Map();
|
||||||
let sshSurfID; // Variable to store the user ID from the database
|
let sshSurfID; // Variable to store the user ID from the database
|
||||||
|
|
||||||
// Paths to config and tokens files
|
// Paths to config and tokens files
|
||||||
@ -99,10 +100,10 @@ async function makeApiRequest(endpoint, token, interaction, method = 'get', body
|
|||||||
}
|
}
|
||||||
|
|
||||||
return request.then(response => {
|
return request.then(response => {
|
||||||
if (response.error) {
|
if (response.error || !response.body) {
|
||||||
console.error('API Error:', response.error);
|
console.error('API Error:', response.error || 'No response body');
|
||||||
sendSexyEmbed("Error", "An error occurred while communicating with the API.", interaction);
|
sendSexyEmbed("Error", "An error occurred while communicating with the API.", interaction);
|
||||||
throw response.error;
|
throw new Error('API request failed');
|
||||||
}
|
}
|
||||||
return response.body;
|
return response.body;
|
||||||
});
|
});
|
||||||
@ -177,7 +178,7 @@ const commands = [
|
|||||||
.addStringOption(option => option.setName('command').setDescription('Command to execute').setRequired(true)),
|
.addStringOption(option => option.setName('command').setDescription('Command to execute').setRequired(true)),
|
||||||
new SlashCommandBuilder().setName('notify').setDescription('Send a notification to Discord')
|
new SlashCommandBuilder().setName('notify').setDescription('Send a notification to Discord')
|
||||||
.addStringOption(option => option.setName('message').setDescription('Message to send').setRequired(true)),
|
.addStringOption(option => option.setName('message').setDescription('Message to send').setRequired(true)),
|
||||||
new SlashCommandBuilder().setName('privacy').setDescription('Toggle ephemeral responses') // New command to toggle privacy
|
new SlashCommandBuilder().setName('privacy').setDescription('Toggle ephemeral responses')
|
||||||
];
|
];
|
||||||
|
|
||||||
// Register commands with Discord
|
// Register commands with Discord
|
||||||
@ -201,10 +202,10 @@ const rest = new REST({ version: '10' }).setToken(config.token);
|
|||||||
return jsonCommand;
|
return jsonCommand;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register commands with Discord, making sure all commands are sent in an array
|
// Register commands with Discord
|
||||||
const data = await rest.put(
|
await rest.put(
|
||||||
Routes.applicationCommands(config.clientId),
|
Routes.applicationCommands(config.clientId),
|
||||||
{ body: commandsWithExtras } // Send all commands in one array
|
{ body: commandsWithExtras }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('Successfully reloaded application (/) commands.');
|
console.log('Successfully reloaded application (/) commands.');
|
||||||
@ -216,13 +217,14 @@ const rest = new REST({ version: '10' }).setToken(config.token);
|
|||||||
// Handle bot interactions
|
// Handle bot interactions
|
||||||
client.on('interactionCreate', async interaction => {
|
client.on('interactionCreate', async interaction => {
|
||||||
if (!interaction.isCommand()) return;
|
if (!interaction.isCommand()) return;
|
||||||
|
|
||||||
// Check if the command is /privacy, always make it ephemeral
|
// Check if the command is /privacy, always make it ephemeral
|
||||||
const isPrivacyCommand = interaction.commandName === 'privacy';
|
const isPrivacyCommand = interaction.commandName === 'privacy';
|
||||||
|
|
||||||
// Defer the reply based on whether it's the privacy command or not
|
// Defer the reply based on whether it's the privacy command or not
|
||||||
await interaction.deferReply({ ephemeral: isPrivacyCommand || isEphemeral(interaction.user.id) });
|
await interaction.deferReply({ ephemeral: isPrivacyCommand || isEphemeral(interaction.user.id) });
|
||||||
|
|
||||||
// First, we fetch the sshSurfID from the database using interaction.user.id
|
// Fetch the sshSurfID from the database using interaction.user.id
|
||||||
let sshSurfID = await new Promise((resolve, reject) => {
|
let sshSurfID = await new Promise((resolve, reject) => {
|
||||||
connection.query(
|
connection.query(
|
||||||
"SELECT uid FROM users WHERE discord_id = ?",
|
"SELECT uid FROM users WHERE discord_id = ?",
|
||||||
@ -251,7 +253,7 @@ client.on('interactionCreate', async interaction => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once sshSurfID is set, we proceed with token fetching and API requests
|
// Once sshSurfID is set, proceed with token fetching and API requests
|
||||||
const apiToken = await getToken(sshSurfID, interaction);
|
const apiToken = await getToken(sshSurfID, interaction);
|
||||||
try {
|
try {
|
||||||
switch (interaction.commandName) {
|
switch (interaction.commandName) {
|
||||||
@ -392,7 +394,7 @@ client.on('interactionCreate', async interaction => {
|
|||||||
|
|
||||||
if (argscmd.includes('../')) {
|
if (argscmd.includes('../')) {
|
||||||
const numDirsBack = argscmd.split('../').length - 1;
|
const numDirsBack = argscmd.split('../').length - 1;
|
||||||
newPWD = RemoveLastDirectoryPartOf(userPWD, numDirsBack);
|
newPWD = userPWD.split('/').slice(0, -numDirsBack).join('/') || '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
userWorkingDirectories.set(sshSurfID, newPWD);
|
userWorkingDirectories.set(sshSurfID, newPWD);
|
||||||
@ -404,14 +406,32 @@ client.on('interactionCreate', async interaction => {
|
|||||||
cmd: command,
|
cmd: command,
|
||||||
pwd: userPWD
|
pwd: userPWD
|
||||||
});
|
});
|
||||||
|
console.log('execResponse:', JSON.stringify(execResponse, null, 2));
|
||||||
|
|
||||||
|
// Handle case where container does not exist
|
||||||
|
if (execResponse?.success === false && execResponse.message?.includes('no such container')) {
|
||||||
|
sendSexyEmbed(
|
||||||
|
'Error',
|
||||||
|
'No running container found. Please use the `/generate` command in the Discord-Linux server to create a new container.',
|
||||||
|
interaction,
|
||||||
|
isEphemeral(interaction.user.id)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if execResponse has the expected structure
|
||||||
|
if (!execResponse || !execResponse.stdout) {
|
||||||
|
console.error('Invalid execResponse:', execResponse);
|
||||||
|
await interaction.editReply('Error: No output received from the command.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (execResponse.stdout.length > 2020) {
|
if (execResponse.stdout.length > 2020) {
|
||||||
const tempFilePath = '/tmp/paste';
|
const tempFilePath = '/tmp/paste';
|
||||||
const pasteCommand = `Command: ${command} | Container Owner: ${interaction.user.username}\n${execResponse.stdout}`;
|
const pasteCommand = `Command: ${command} | Container Owner: ${interaction.user.username}\n${execResponse.stdout}`;
|
||||||
fs.writeFileSync(tempFilePath, pasteCommand, (err) => {
|
fs.writeFileSync(tempFilePath, pasteCommand, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error('Error writing to file:', err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -423,7 +443,8 @@ client.on('interactionCreate', async interaction => {
|
|||||||
.setDescription(`The command: ${command} was too large for Discord.`)
|
.setDescription(`The command: ${command} was too large for Discord.`)
|
||||||
.addFields({
|
.addFields({
|
||||||
name: 'Please check the below output log:',
|
name: 'Please check the below output log:',
|
||||||
value: pasteout.stdout.replace("Pro tip: you can password protect your paste just by typing a username and password after your paste command.", "")
|
value: pasteout.stdout
|
||||||
|
.replace("Pro tip: you can password protect your paste just by typing a username and password after your paste command.", "")
|
||||||
.replace("Paste Saved: ", "")
|
.replace("Paste Saved: ", "")
|
||||||
.replace("-------------------------------------------------------", "")
|
.replace("-------------------------------------------------------", "")
|
||||||
})
|
})
|
||||||
@ -431,6 +452,10 @@ client.on('interactionCreate', async interaction => {
|
|||||||
|
|
||||||
await interaction.editReply({ embeds: [mainEmbed] });
|
await interaction.editReply({ embeds: [mainEmbed] });
|
||||||
|
|
||||||
|
// Clean up the temporary file
|
||||||
|
fs.unlink(tempFilePath, (err) => {
|
||||||
|
if (err) console.error('Error cleaning up temp file:', err);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
let replyMessage = `\`\`\`\n${execResponse.stdout || 'No output'}\n\`\`\``;
|
let replyMessage = `\`\`\`\n${execResponse.stdout || 'No output'}\n\`\`\``;
|
||||||
|
|
||||||
@ -454,7 +479,7 @@ client.on('interactionCreate', async interaction => {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
interaction.reply({ content: 'Command not recognized.', ephemeral: isEphemeral(interaction.user.id) });
|
await interaction.editReply({ content: 'Command not recognized.', ephemeral: isEphemeral(interaction.user.id) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user