diff options
| author | Alex Pooley (@zuedev) <zuedev@gmail.com> | 2026-07-22 15:32:57 +0100 |
|---|---|---|
| committer | Alex Pooley (@zuedev) <zuedev@gmail.com> | 2026-07-22 15:32:57 +0100 |
| commit | 72487019b3f255cece40a8073bbad8bc9968a3b7 (patch) | |
| tree | b6590e63039cdc8b1820bd345cdfe83f28ff839b /174bg/discord-bot/source/commands | |
| parent | da0509c91376f56f133872eddd2e4282d76f215e (diff) | |
| download | unnamed-group-72487019b3f255cece40a8073bbad8bc9968a3b7.tar unnamed-group-72487019b3f255cece40a8073bbad8bc9968a3b7.tar.gz unnamed-group-72487019b3f255cece40a8073bbad8bc9968a3b7.tar.bz2 unnamed-group-72487019b3f255cece40a8073bbad8bc9968a3b7.tar.xz unnamed-group-72487019b3f255cece40a8073bbad8bc9968a3b7.zip | |
major code refactor, add uex lookup
Diffstat (limited to '174bg/discord-bot/source/commands')
| -rw-r--r-- | 174bg/discord-bot/source/commands/_index.js | 8 | ||||
| -rw-r--r-- | 174bg/discord-bot/source/commands/close-ticket.js | 55 | ||||
| -rw-r--r-- | 174bg/discord-bot/source/commands/oncall-check.js | 51 | ||||
| -rw-r--r-- | 174bg/discord-bot/source/commands/requisition.js | 42 | ||||
| -rw-r--r-- | 174bg/discord-bot/source/commands/uex.js | 81 |
5 files changed, 237 insertions, 0 deletions
diff --git a/174bg/discord-bot/source/commands/_index.js b/174bg/discord-bot/source/commands/_index.js new file mode 100644 index 0000000..5fea200 --- /dev/null +++ b/174bg/discord-bot/source/commands/_index.js @@ -0,0 +1,8 @@ +import requisition from "./requisition.js"; +import closeTicket from "./close-ticket.js"; +import oncallCheck from "./oncall-check.js"; +import uex from "./uex.js"; + +export { requisition, closeTicket, oncallCheck, uex }; + +export default [requisition, closeTicket, oncallCheck, uex]; diff --git a/174bg/discord-bot/source/commands/close-ticket.js b/174bg/discord-bot/source/commands/close-ticket.js new file mode 100644 index 0000000..ca3040e --- /dev/null +++ b/174bg/discord-bot/source/commands/close-ticket.js @@ -0,0 +1,55 @@ +import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"; + +export default { + data: new SlashCommandBuilder() + .setName("close-ticket") + .setDescription( + "Closes the current ticket by logging the contents and deleting the channel.", + ) + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + execute: async (interaction) => { + const channel = interaction.channel; + + if (!channel || !channel.name.startsWith("ticket-")) { + return await interaction.reply({ + content: "This command can only be used in a ticket channel.", + ephemeral: true, + }); + } + + // log the contents of the ticket and send to the logs channel if it exists + const messages = await channel.messages.fetch({ limit: 100 }); + const log = messages + .map((message) => `${message.author.tag}: ${message.content}`) + .reverse() + .join("\n"); + + console.log(`Ticket log for ${channel.name}:\n${log}`); + + const logsChannel = interaction.guild.channels.cache.find( + (ch) => ch.name === "logs" && ch.isTextBased(), + ); + + if (logsChannel) + await logsChannel.send({ + content: `# Ticket log for ${channel.name}`, + files: [ + { + name: `${channel.name}.txt`, + attachment: Buffer.from( + messages + .map( + (message) => + `${message.author.tag}/${message.author.id}: ${message.content}`, + ) + .reverse() + .join("\n"), + ), + }, + ], + }); + + // delete the channel + await channel.delete(); + }, +}; diff --git a/174bg/discord-bot/source/commands/oncall-check.js b/174bg/discord-bot/source/commands/oncall-check.js new file mode 100644 index 0000000..7a3886d --- /dev/null +++ b/174bg/discord-bot/source/commands/oncall-check.js @@ -0,0 +1,51 @@ +import { SlashCommandBuilder, PermissionFlagsBits } from "discord.js"; +import { login } from "../controllers/pocketbase.js"; + +export default { + data: new SlashCommandBuilder() + .setName("oncall-check") + .setDescription("Returns a list of members who are currently on call.") + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + execute: async (interaction) => { + const date = new Date(); + const dateUTCHours = date.getUTCHours(); + const dateUTCMinutes = date.getUTCMinutes(); + const dateUTCDay = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][date.getUTCDay()]; + + const pb = await login(); + + const members = await pb.collection("members").getFullList(); + + let membersOnCall = []; + + for (const member of members) { + try { + if (member.onCallSchedule) { + const available = member.onCallSchedule[dateUTCDay]?.available || false; + + if (available) { + const start = member.onCallSchedule[dateUTCDay].start; + const startHours = start.split(":")[0]; + const startMinutes = start.split(":")[1]; + const end = member.onCallSchedule[dateUTCDay].end; + const endHours = end.split(":")[0]; + const endMinutes = end.split(":")[1]; + + console.log(`Checking on-call schedule for member ${member.name}: ${start} - ${end} (UTC)`); + + if ((dateUTCHours > startHours || (dateUTCHours === startHours && dateUTCMinutes >= startMinutes)) && (dateUTCHours < endHours || (dateUTCHours === endHours && dateUTCMinutes <= endMinutes))) { + membersOnCall.push(member); + } + } + } + } catch (error) { + console.error(`Error checking on-call schedule for member ${member.name}:`, error); + } + } + + await interaction.reply({ + content: `${membersOnCall.map((member) => `- <@${member.discordId}>`).join("\n") || "No members are currently on call."}`, + ephemeral: true, + }); + }, +}; diff --git a/174bg/discord-bot/source/commands/requisition.js b/174bg/discord-bot/source/commands/requisition.js new file mode 100644 index 0000000..02c7699 --- /dev/null +++ b/174bg/discord-bot/source/commands/requisition.js @@ -0,0 +1,42 @@ +import { SlashCommandBuilder } from "discord.js"; +import createTicket from "../utilities/createTicket.js"; +import notifyRoleByName from "../utilities/notifyRoleByName.js"; + +export default { + data: new SlashCommandBuilder() + .setName("requisition") + .setDescription( + "Request items from the quartermaster. A new requisition ticket will be created.", + ) + .addStringOption((option) => + option + .setName("contents") + .setDescription("What are you requesting? Be as specific as possible.") + .setRequired(true), + ), + execute: async (interaction) => { + const contents = interaction.options.getString("contents"); + + const ticket = await createTicket(interaction, { + roleNamesWithAccess: ["quartermaster"], + ticketNamePrefix: "req-", + }); + + await ticket.send({ + content: `**New requisition request from <@${interaction.user.id}>**: ${contents}`, + }); + + // reply to the user + await interaction.reply({ + content: `Your requisition ticket has been created: <#${ticket.id}>`, + ephemeral: true, + }); + + // notify quartermasters + await notifyRoleByName( + interaction.guild, + "quartermaster", + `New requisition request from <@${interaction.user.id}>: ${contents}`, + ); + }, +}; diff --git a/174bg/discord-bot/source/commands/uex.js b/174bg/discord-bot/source/commands/uex.js new file mode 100644 index 0000000..f2f654f --- /dev/null +++ b/174bg/discord-bot/source/commands/uex.js @@ -0,0 +1,81 @@ +import { SlashCommandBuilder, MessageFlags } from "discord.js"; +import { items } from "../controllers/uex.js"; + +export default { + data: new SlashCommandBuilder() + .setName("uex") + .setDescription( + "Commands for interacting with UEX.", + ) + .addSubcommandGroup((subcommandGroup) => + subcommandGroup + .setName("lookup") + .setDescription("Lookup UEX information.") + .addSubcommand((subcommand) => + subcommand + .setName("items") + .setDescription("Perform UEX lookup for Star Citizen items, including ship components, weapons, and more.") + .addStringOption((option) => + option + .setName("query") + .setDescription( + "The item name or partial name to search for.", + ) + .setRequired(true), + ), + ) + ), + execute: async (interaction) => { + const subcommandGroup = interaction.options.getSubcommandGroup(); + const subcommand = interaction.options.getSubcommand(); + + switch (subcommandGroup) { + case "lookup": + switch (subcommand) { + case "items": + await uex_lookup_items(interaction); + break; + default: + await interaction.reply({ + content: "Unknown subcommand.", + ephemeral: true, + }); + break; + } + break; + default: + await interaction.reply({ + content: "Unknown subcommand group.", + ephemeral: true, + }); + break; + } + }, +}; + +async function uex_lookup_items(interaction) { + const query = interaction.options.getString("query"); + + await interaction.deferReply({ flags: MessageFlags.Ephemeral }); + + const allItems = await items(); + + const matchingItems = allItems.filter((item) => + item.name.toLowerCase().includes(query.toLowerCase()), + ); + + if (matchingItems.length === 0) { + await interaction.editReply({ + content: `No items found matching "${query}".`, + }); + return; + } + + const itemList = matchingItems + .map((item) => `- ${item.name} (ID: ${item.id})`) + .join("\n"); + + await interaction.editReply({ + content: `Found ${matchingItems.length} item(s) matching "${query}":\n${itemList}`, + }); +}
\ No newline at end of file |
