130 lines
3.5 KiB
JavaScript
130 lines
3.5 KiB
JavaScript
import { DebugBuilder } from "../../modules/debugger.mjs";
|
|
import { SlashCommandBuilder } from "discord.js";
|
|
import {
|
|
joinNode,
|
|
getAvailableNodes,
|
|
promptNodeSelection,
|
|
getUserVoiceChannel,
|
|
} from "../modules/wrappers.mjs";
|
|
import {
|
|
getAllSystems,
|
|
getSystemByName,
|
|
} from "../../modules/mongo-wrappers/mongoSystemsWrappers.mjs";
|
|
|
|
const log = new DebugBuilder("server", "discordBot.command.join");
|
|
|
|
// 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),
|
|
);
|
|
|
|
log.DEBUG(focusedValue, choices, filtered);
|
|
|
|
try {
|
|
await interaction.respond(
|
|
filtered.map((choice) => ({ name: choice.name, value: choice.name })),
|
|
);
|
|
} catch (e) {
|
|
log.WARN("Autocomplete interaction failure", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle join command execution
|
|
* @param {any} nodeIo The nodeIO server for manipulation of sockets
|
|
* @param {any} interaction The interaction object
|
|
*/
|
|
export async function execute(nodeIo, interaction) {
|
|
try {
|
|
// Validate user is in a voice channel
|
|
const channelToJoin = getUserVoiceChannel(interaction);
|
|
if (!channelToJoin) return;
|
|
|
|
// Get the selected system
|
|
const selectedSystemName = interaction.options.getString("system");
|
|
const system = await getSystemByName(selectedSystemName);
|
|
|
|
// Check if there was a system found by the given system name
|
|
if (!system) {
|
|
await interaction.editReply({
|
|
content: `System '${selectedSystemName}' not found.`,
|
|
ephemeral: true,
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Get the available nodes for this system
|
|
const availableNodes = await getAvailableNodes(
|
|
nodeIo,
|
|
interaction.guild.id,
|
|
system,
|
|
);
|
|
|
|
// Check if there are available nodes
|
|
if (availableNodes.length === 0) {
|
|
// If not, let the user know
|
|
await interaction.editReply(
|
|
`<@${interaction.member.id}>, the selected system has no available nodes`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
// If there is one available node, request that node join
|
|
if (availableNodes.length === 1) {
|
|
await joinNode(
|
|
nodeIo,
|
|
interaction,
|
|
availableNodes[0].id,
|
|
system,
|
|
channelToJoin,
|
|
);
|
|
}
|
|
|
|
// If there are more than one available, prompt the user for their selected node
|
|
else {
|
|
await promptNodeSelection(
|
|
interaction,
|
|
availableNodes,
|
|
async (selectedNode) => {
|
|
await joinNode(
|
|
nodeIo,
|
|
interaction,
|
|
selectedNode,
|
|
system,
|
|
channelToJoin,
|
|
);
|
|
},
|
|
);
|
|
}
|
|
} catch (err) {
|
|
log.ERROR(err);
|
|
await interaction.editReply({
|
|
content: `An error occurred: ${err.message}`,
|
|
ephemeral: true,
|
|
});
|
|
}
|
|
}
|