Initial move
This commit is contained in:
154
discordBot/commands/join.mjs
Normal file
154
discordBot/commands/join.mjs
Normal file
@@ -0,0 +1,154 @@
|
||||
import { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
|
||||
import { requestNodeJoinSystem, checkIfNodeIsConnectedToVC, checkIfNodeHasOpenDiscordClient, getNodeCurrentListeningSystem } from '../../modules/socketServerWrappers.mjs';
|
||||
import { getSystemsByNuid, getAllSystems, getSystemByName } from '../../modules/mongoSystemsWrappers.mjs';
|
||||
import { getAvailableTokensInGuild } from '../modules/wrappers.mjs';
|
||||
|
||||
// Exporting data property
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName('join')
|
||||
.setDescription('Listen to the selected radio system in your channel')
|
||||
.addStringOption(system =>
|
||||
system.setName('system')
|
||||
.setDescription('The radio system you would like to listen to')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true));
|
||||
|
||||
// Exporting other properties
|
||||
export const example = "/join";
|
||||
export const deferInitialReply = true;
|
||||
|
||||
/**
|
||||
* Function to give the user auto-reply suggestions
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export async function autocomplete(nodeIo, interaction) {
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const choices = await getAllSystems();
|
||||
const filtered = choices.filter(choice => choice.name.startsWith(focusedValue));
|
||||
|
||||
console.log(focusedValue, choices, filtered);
|
||||
|
||||
await interaction.respond(
|
||||
filtered.map(choice => ({ name: choice.name, value: choice.name })),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function to run when the command is called by a discord user
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export async function execute(nodeIo, interaction) {
|
||||
// Check if the user is in a VC
|
||||
if (!interaction.member.voice.channel) { return await interaction.editReply({ content: `<@${interaction.member.id}>, you need to enter a voice channel before you use this command`, ephemeral: true }) }
|
||||
// Grab the channel if the user is connected to VC
|
||||
const channelToJoin = interaction.member.voice.channel;
|
||||
console.log(`The user '${interaction.member.id}' is in the voice channel '${channelToJoin}'`);
|
||||
|
||||
// Get the selected system option from the command interaction
|
||||
const selectedSystem = interaction.options.getString('system');
|
||||
|
||||
try {
|
||||
// Get the selected system object from the DB
|
||||
const system = await getSystemByName(selectedSystem);
|
||||
|
||||
// Function wrapper to request the selected/only node to join the selected system
|
||||
const joinSelectedNode = async (selectedNodeSocketId) => {
|
||||
const openSocket = await nodeIo.sockets.sockets.get(selectedNodeSocketId);
|
||||
// Get the open ID for this connection\
|
||||
const ss = await getAvailableTokensInGuild(nodeIo, interaction.guild.id);
|
||||
console.log("Available discord tokens: ", discordTokens);
|
||||
|
||||
if (discordTokens.length >= 1) {
|
||||
// TODO - Implement a method to have preferred tokens (bot users) for specific systems
|
||||
console.log("Joining selected open socket:", selectedNodeSocketId, system.name, channelToJoin.id, openSocket.node.name, discordTokens[0].token);
|
||||
|
||||
// Ask the node to join the selected channel and system
|
||||
await requestNodeJoinSystem(openSocket, system.name, channelToJoin.id, discordTokens[0].token);
|
||||
}
|
||||
else {
|
||||
return await interaction.editReply({ content: `<@${interaction.member.id}>, there are no free bots. Free up or create a new bot ID (discord app) to listen to this system.`, ephemeral: true })
|
||||
}
|
||||
}
|
||||
|
||||
// Get all open socket nodes
|
||||
const openSockets = [...await nodeIo.allSockets()]; // TODO - Filter the returned nodes to only nodes that have the radio capability
|
||||
console.log("All open sockets: ", openSockets);
|
||||
|
||||
var availableNodes = [];
|
||||
// Check each open socket to see if the node has the requested system
|
||||
await Promise.all(openSockets.map(async openSocket => {
|
||||
openSocket = await nodeIo.sockets.sockets.get(openSocket);
|
||||
// Check if the node has an existing open client (meaning the radio is already being listened to)
|
||||
const hasOpenClient = await checkIfNodeHasOpenDiscordClient(openSocket);
|
||||
if (hasOpenClient) {
|
||||
let currentSystem = await getNodeCurrentListeningSystem(openSocket);
|
||||
if (currentSystem != system.name) {
|
||||
console.log("Node is listening to a different system than requested", openSocket.node.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the bot has an open voice connection in the requested server already
|
||||
const connected = await checkIfNodeIsConnectedToVC(nodeIo, interaction.guild.id, openSocket.node.nuid);
|
||||
console.log("Connected:", connected);
|
||||
if (!connected) {
|
||||
// Check if this node has the requested system, if so add it to the availble array
|
||||
if (system.nodes.includes(openSocket.node.nuid)) {
|
||||
availableNodes.push(openSocket);
|
||||
}
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
console.log("Availble nodes:", availableNodes.map(socket => socket.node.name));
|
||||
|
||||
// If there are no available nodes, let the user know there are none available
|
||||
if (availableNodes.length == 0) {
|
||||
// There are no nodes availble for the requested system
|
||||
return await interaction.editReply(`<@${interaction.member.id}>, the selected system has no available nodes`);
|
||||
} else if (availableNodes.length == 1) {
|
||||
// There is only one node available for the requested system
|
||||
// Request the node to join
|
||||
await joinSelectedNode(availableNodes[0].id);
|
||||
// Let the user know
|
||||
await interaction.editReply({ content: `Ok <@${interaction.member.id}>, a bot will join your channel listening to *'${system.name}'* shortly`, components: [] });
|
||||
} else if (availableNodes.length > 1) {
|
||||
// There is more than one node availble for the requested system
|
||||
const nodeSelectionButtons = []
|
||||
|
||||
// Create a button for each available node
|
||||
for (const availableNode of availableNodes) {
|
||||
nodeSelectionButtons.push(new ButtonBuilder().setCustomId(availableNode.id).setLabel(availableNode.node.name).setStyle(ButtonStyle.Primary));
|
||||
}
|
||||
|
||||
const actionRow = new ActionRowBuilder().addComponents(nodeSelectionButtons);
|
||||
|
||||
// Reply to the user with the button prompts
|
||||
const response = await interaction.editReply({
|
||||
content: `<@${interaction.member.id}>, Please select the Node you would like to join with this system`,
|
||||
components: [actionRow]
|
||||
});
|
||||
|
||||
// Make sure the responding selection is from the user who initiated the command
|
||||
const collectorFilter = i => i.user.id === interaction.user.id;
|
||||
|
||||
// Wait for the confirmation from the user on which node to join
|
||||
try {
|
||||
const selectedNode = await response.awaitMessageComponent({ filter: collectorFilter, time: 60_000 });
|
||||
// Run the local wrapper to listen to the selected node
|
||||
await joinSelectedNode(selectedNode.customId);
|
||||
// Let the user know
|
||||
await selectedNodeConfirmation.update({ content: `Ok <@${interaction.member.id}>, a bot will join your channel listening to *'${system.name}'*`, components: [] });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
// Timeout the prompt if the user doesn't interact with it
|
||||
await interaction.editReply({ content: 'Confirmation not received within 1 minute, cancelling', components: [] });
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// await interaction.reply(err.toString());
|
||||
}
|
||||
}
|
||||
56
discordBot/commands/leave.mjs
Normal file
56
discordBot/commands/leave.mjs
Normal file
@@ -0,0 +1,56 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { requestBotLeaveServer, getSocketIdByNuid } from '../../modules/socketServerWrappers.mjs';
|
||||
import { checkOnlineBotsInGuild } from '../modules/wrappers.mjs'
|
||||
|
||||
// Exporting data property
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName('leave')
|
||||
.setDescription('Disconnect a bot from the server')
|
||||
.addStringOption(system =>
|
||||
system.setName('bot')
|
||||
.setDescription('The bot you would like to disconnect')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true));;
|
||||
|
||||
// Exporting other properties
|
||||
export const example = "/leave *{Bot Name}*";
|
||||
export const deferInitialReply = true;
|
||||
|
||||
/**
|
||||
* Function to give the user auto-reply suggestions
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export async function autocomplete(nodeIo, interaction) {
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const choices = (await checkOnlineBotsInGuild(nodeIo, interaction.guild.id));
|
||||
|
||||
console.log(choices);
|
||||
|
||||
const filtered = choices.filter(choice => choice.name.startsWith(focusedValue)).map(choice => choice = {name: choice.name, value: choice.nuid});
|
||||
|
||||
console.log(focusedValue, choices, filtered);
|
||||
|
||||
await interaction.respond(filtered);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function to run when the command is called by a discord user
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export async function execute(nodeIo, interaction) {
|
||||
try {
|
||||
// Get the requested bot
|
||||
const selectedNode = interaction.options.getString('bot');
|
||||
const socket = await getSocketIdByNuid(nodeIo, selectedNode);
|
||||
console.log("All open sockets:", socket, selectedNode);
|
||||
await requestBotLeaveServer(socket, interaction.guild.id);
|
||||
//await interaction.reply(`**Online Sockets: '${sockets}'**`);
|
||||
await interaction.editReply(`Ok <@${interaction.member.id}>, the bot is leaving shortly`);
|
||||
//await interaction.channel.send('**Pong.**');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// await interaction.reply(err.toString());
|
||||
}
|
||||
}
|
||||
43
discordBot/commands/ping.mjs
Normal file
43
discordBot/commands/ping.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
|
||||
// Exporting data property that contains the command structure for discord including any params
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Replies with your input!');
|
||||
|
||||
// Exporting other properties
|
||||
export const example = "/ping"; // An example of how the command would be run in discord chat, this will be used for the help command
|
||||
export const deferInitialReply = false; // If we the initial reply in discord should be deferred. This gives extra time to respond, however the method of replying is different.
|
||||
|
||||
/**
|
||||
* Function to give the user auto-reply suggestions
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
/*
|
||||
export async function autocomplete(nodeIo, interaction) {
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const choices = [];
|
||||
const filtered = choices.filter(choice => choice.name.startsWith(focusedValue));
|
||||
console.log(focusedValue, choices, filtered);
|
||||
await interaction.respond(filtered);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function to run when the command is called by a discord user
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export const execute = async (nodeIo, interaction) => {
|
||||
try {
|
||||
const sockets = await nodeIo.allSockets();
|
||||
console.log("All open sockets: ",sockets);
|
||||
//await interaction.reply(`**Online Sockets: '${sockets}'**`);
|
||||
await interaction.reply('**Pong.**');
|
||||
//await interaction.channel.send('**Pong.**');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// await interaction.reply(err.toString());
|
||||
}
|
||||
}
|
||||
35
discordBot/commands/update.mjs
Normal file
35
discordBot/commands/update.mjs
Normal file
@@ -0,0 +1,35 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { requestNodeUpdate } from '../../modules/socketServerWrappers.mjs';
|
||||
|
||||
// Exporting data property that contains the command structure for discord including any params
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName('update')
|
||||
.setDescription('Updates all nodes currently logged on');
|
||||
|
||||
// Exporting other properties
|
||||
export const example = "/update"; // An example of how the command would be run in discord chat, this will be used for the help command
|
||||
export const deferInitialReply = false; // If we the initial reply in discord should be deferred. This gives extra time to respond, however the method of replying is different.
|
||||
|
||||
/**
|
||||
* The function to run when the command is called by a discord user
|
||||
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
||||
* @param {any} interaction The interaction object
|
||||
*/
|
||||
export const execute = async (nodeIo, interaction) => {
|
||||
try {
|
||||
const openSockets = [...await nodeIo.allSockets()]; // TODO - Filter the returned nodes to only nodes that have the radio capability
|
||||
console.log("All open sockets: ", openSockets);
|
||||
|
||||
// Check each open socket to see if the node has the requested system
|
||||
await Promise.all(openSockets.map(openSocket => {
|
||||
openSocket = nodeIo.sockets.sockets.get(openSocket);
|
||||
requestNodeUpdate(openSocket);
|
||||
}));
|
||||
//await interaction.reply(`**Online Sockets: '${sockets}'**`);
|
||||
await interaction.reply('All nodes have been requested to update');
|
||||
//await interaction.channel.send('**Pong.**');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// await interaction.reply(err.toString());
|
||||
}
|
||||
}
|
||||
92
discordBot/discordBot.mjs
Normal file
92
discordBot/discordBot.mjs
Normal file
@@ -0,0 +1,92 @@
|
||||
import { Client, GatewayIntentBits, Collection } from 'discord.js';
|
||||
import { registerActiveCommands, unregisterAllCommands } from './modules/registerCommands.mjs'
|
||||
import { join, dirname } from 'path';
|
||||
import { readdirSync } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config()
|
||||
|
||||
/**
|
||||
* Add the enabled commands to the bot to be used by users in discord
|
||||
* (commands that end in '.mjs' will be enabled, to disable just remove the extension or replace with '.mjs.disabled')
|
||||
* @param {any} serverClient
|
||||
* @param {any} _commandsPath="./commands"
|
||||
* @returns {any}
|
||||
*/
|
||||
export const addEnabledCommands = async (serverClient, _commandsPath = "./commands") => {
|
||||
// Setup commands for the Discord bot
|
||||
serverClient.commands = new Collection();
|
||||
const commandsPath = join(__dirname, _commandsPath);
|
||||
const commandFiles = readdirSync(commandsPath).filter(file => file.endsWith('.mjs'));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = await join(commandsPath, file);
|
||||
console.log(`Adding enabled command: ${filePath}`);
|
||||
await import(`file://${filePath}`).then(command => {
|
||||
if (command.data instanceof Promise) {
|
||||
command.data.then(async (builder) => {
|
||||
command.data = builder;
|
||||
console.log("Importing command: ", command.data.name, command);
|
||||
// Set a new item in the Collection
|
||||
// With the key as the command name and the value as the exported module
|
||||
serverClient.commands.set(command.data.name, command);
|
||||
});
|
||||
} else {
|
||||
console.log("Importing command: ", command.data.name, command);
|
||||
// Set a new item in the Collection
|
||||
// With the key as the command name and the value as the exported module
|
||||
serverClient.commands.set(command.data.name, command);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Register the commands currently in use by the bot
|
||||
await registerActiveCommands(serverClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the enabled event listeners to the bot
|
||||
* (events that end in '.mjs' will be enabled, to disable just remove the extension or replace with '.mjs.disabled')
|
||||
* @param {any} serverClient
|
||||
* @param {any} _eventsPath="./events"
|
||||
* @returns {any}
|
||||
*/
|
||||
export function addEnabledEventListeners(serverClient, _eventsPath = "./events") {
|
||||
const eventsPath = join(__dirname, _eventsPath);
|
||||
const eventFiles = readdirSync(eventsPath).filter(file => file.endsWith('.mjs'));
|
||||
|
||||
for (const file of eventFiles) {
|
||||
const filePath = join(eventsPath, file);
|
||||
console.log(`Adding enabled event listener: ${filePath}`);
|
||||
import(`file://${filePath}`).then(event => {
|
||||
console.log("Adding event: ", event);
|
||||
if (event.once) {
|
||||
serverClient.once(event.name, (...args) => event.execute(serverClient.nodeIo, ...args));
|
||||
} else {
|
||||
serverClient.on(event.name, (...args) => event.execute(serverClient.nodeIo, ...args));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// The discord client
|
||||
export const serverClient = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates] });
|
||||
|
||||
// Run when the bot is ready
|
||||
serverClient.on('ready', async () => {
|
||||
console.log(`Logged in as ${serverClient.user.tag}!`);
|
||||
|
||||
// Add and register commands
|
||||
await addEnabledCommands(serverClient);
|
||||
|
||||
// Config the discord bot with events
|
||||
await addEnabledEventListeners(serverClient);
|
||||
});
|
||||
|
||||
// Startup the discord bot
|
||||
console.log(`Logging into discord with ID: ${process.env.DISCORD_TOKEN}`);
|
||||
serverClient.login(process.env.DISCORD_TOKEN);
|
||||
32
discordBot/events/interactionCreate.mjs
Normal file
32
discordBot/events/interactionCreate.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Events } from 'discord.js';
|
||||
|
||||
export const name = Events.InteractionCreate;
|
||||
|
||||
export async function execute(nodeIo, interaction) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
console.log("Interaction created for command: ", command);
|
||||
|
||||
// Execute autocomplete if the user is checking autocomplete
|
||||
if (interaction.isAutocomplete()) {
|
||||
console.log("Running autocomplete for command: ", command.data.name);
|
||||
return await command.autocomplete(nodeIo, interaction);
|
||||
}
|
||||
|
||||
// Check if the interaction is a command
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
if (!command) {
|
||||
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`${interaction.member.user} is running '${interaction.commandName}'`);
|
||||
|
||||
// Defer the initial reply if the command has the parameter set
|
||||
if (command.deferInitialReply) {
|
||||
await interaction.deferReply();
|
||||
}
|
||||
|
||||
// Execute the command
|
||||
command.execute(nodeIo, interaction);
|
||||
}
|
||||
83
discordBot/modules/registerCommands.mjs
Normal file
83
discordBot/modules/registerCommands.mjs
Normal file
@@ -0,0 +1,83 @@
|
||||
import { REST, Routes } from 'discord.js';
|
||||
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config()
|
||||
|
||||
const discordToken = process.env.DISCORD_TOKEN;
|
||||
|
||||
export const registerActiveCommands = async (serverClient) => {
|
||||
const guildIDs = serverClient.guilds.cache;
|
||||
const clientId = serverClient.user.id;
|
||||
const commands = await serverClient.commands.map(command => command = command.data.toJSON());
|
||||
|
||||
// Construct and prepare an instance of the REST module
|
||||
const rest = new REST({ version: '10' }).setToken(discordToken);
|
||||
|
||||
// and deploy your commands!
|
||||
guildIDs.forEach(guild => {
|
||||
console.log("Deploying commands for: ", guild.id);
|
||||
console.log("Commands", commands);
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing application (/) commands for guild ID: ${guild.id}.`);
|
||||
// The put method is used to fully refresh all commands in the guild with the current set
|
||||
const data = await rest.put(
|
||||
Routes.applicationGuildCommands(clientId, guild.id),
|
||||
{ body: commands },
|
||||
);
|
||||
|
||||
console.log(`Successfully reloaded ${data.length} application (/) commands for guild ID: ${guild.id}.`);
|
||||
} catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.log("ERROR Deploying commands: ", error, "Body from error: ", commands);
|
||||
}
|
||||
})()
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all commands for a given bot in a given guild
|
||||
*
|
||||
* @param {any} serverClient The discord bot client
|
||||
*/
|
||||
export const unregisterAllCommands = async (serverClient) => {
|
||||
const guildIDs = serverClient.guilds.cache;
|
||||
const clientId = serverClient.user.id;
|
||||
commands = [];
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(discordToken);
|
||||
guildIDs.forEach(guild => {
|
||||
console.log("Removing commands for: ", clientId, guild.id);
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started removal of ${commands.length} application (/) commands for guild ID: ${guild.id}.`);
|
||||
// The put method is used to fully refresh all commands in the guild with the current set
|
||||
const data = await rest.put(
|
||||
Routes.applicationGuildCommands(clientId, guild.id),
|
||||
{ body: commands },
|
||||
);
|
||||
|
||||
console.log(`Successfully removed ${data.length} application (/) commands for guild ID: ${guild.id}.`);
|
||||
} catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.log("ERROR removing commands: ", error, "Body from error: ", commands);
|
||||
}
|
||||
})()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This named wrapper will remove all commands and then re-add the commands back, effectively refreshing them
|
||||
* @param {any} serverClient The discord bot client object
|
||||
* @returns {any}
|
||||
*/
|
||||
export const refreshActiveCommandsWrapper = async (serverClient) => {
|
||||
// Remove all commands
|
||||
console.log("Removing/Unregistering all commands from all connected servers/guilds");
|
||||
await unregisterAllCommands(serverClient);
|
||||
// Deploy the active commands
|
||||
console.log("Adding commands to all connected servers/guilds");
|
||||
await registerActiveCommands(serverClient);
|
||||
return;
|
||||
}
|
||||
48
discordBot/modules/wrappers.mjs
Normal file
48
discordBot/modules/wrappers.mjs
Normal file
@@ -0,0 +1,48 @@
|
||||
import { checkIfNodeIsConnectedToVC, getNodeDiscordID, getNodeDiscordUsername } from '../../modules/socketServerWrappers.mjs';
|
||||
import { getAllDiscordIDs } from '../../modules/mongoDiscordIDWrappers.mjs'
|
||||
|
||||
|
||||
export const checkOnlineBotsInGuild = async (nodeIo, guildId) => {
|
||||
let onlineBots = [];
|
||||
const openSockets = [...await nodeIo.allSockets()];
|
||||
await Promise.all(openSockets.map(async openSocket => {
|
||||
openSocket = await nodeIo.sockets.sockets.get(openSocket);
|
||||
const connected = await checkIfNodeIsConnectedToVC(nodeIo, guildId, openSocket.node.nuid);
|
||||
console.log("Connected:", connected);
|
||||
if (connected) {
|
||||
const username = await getNodeDiscordUsername(openSocket, guildId);
|
||||
const discordID = await getNodeDiscordID(openSocket);
|
||||
onlineBots.push({
|
||||
name: username,
|
||||
discord_id: discordID,
|
||||
nuid: openSocket.node.nuid
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
return onlineBots;
|
||||
}
|
||||
|
||||
|
||||
export const getAvailableTokensInGuild = async (nodeIo, guildId) => {
|
||||
try {
|
||||
// Execute both asynchronous functions concurrently
|
||||
const [discordIDs, onlineBots] = await Promise.all([
|
||||
getAllDiscordIDs(), // Fetch all Discord IDs
|
||||
checkOnlineBotsInGuild(nodeIo, guildId) // Check online bots in the guild
|
||||
]);
|
||||
|
||||
// Use the results of both promises here
|
||||
console.log("Available Discord IDs:", discordIDs);
|
||||
console.log("Online bots in the guild:", onlineBots);
|
||||
|
||||
// Filter any discordIDs that are not active
|
||||
const availableDiscordIDs = discordIDs.filter(discordID => discordID.active == true).filter(discordID => !onlineBots.some(bot => Number(bot.discord_id) == discordID.discord_id));
|
||||
|
||||
// Return the unavailable discordIDs
|
||||
return availableDiscordIDs;
|
||||
} catch (error) {
|
||||
console.error('Error getting available tokens in guild:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user