UNPKG

@getsolara/solara.js

Version:

A lightweight and modular Discord bot framework built on discord.js v14, with truly optional feature packages.

25 lines 3.12 kB
const { ChannelType, PermissionsBitField, EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js'); module.exports = { name: "$newTicket", description: "Creates a new ticket channel. Args: topic;[categoryID?];[private(true)?];[reason?]", takesBrackets: true, execute: async (context, args) => { if (!context.guild) return "[Error: Requires guild context]"; if (!args[0]) return "[Error: Requires ticket topic/reason]"; const topic = args[0]; const categoryId = args[1]; const isPrivate = args[2]?.toLowerCase() === 'true'; const reason = args[3]; const userName = context.user?.username.replace(/[^a-zA-Z0-9-_]/g, '') || 'ticket'; // Sanitize username const channelName = `ticket-${userName}-${Date.now() % 10000}`; try { if (!context.guild.members.me?.permissions.has("ManageChannels")) return "[Error: Bot lacks Manage Channels permission]"; const overwrites = [ { id: context.guild.id, deny: [PermissionsBitField.Flags.ViewChannel] }, { id: context.user.id, allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.ReadMessageHistory, PermissionsBitField.Flags.AttachFiles, PermissionsBitField.Flags.EmbedLinks] }, { id: context.client.user.id, allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.ReadMessageHistory, PermissionsBitField.Flags.ManageMessages, PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.EmbedLinks] } ]; if (isPrivate) { /* Add Support Role Overwrites Here if needed */ } const options = { name: channelName, type: ChannelType.GuildText, topic: `Ticket by ${context.user.tag}. Topic: ${topic}`, permissionOverwrites: overwrites, reason: reason || "Ticket created" }; if (categoryId && /^\d{17,19}$/.test(categoryId)) options.parent = categoryId; const ticketChannel = await context.guild.channels.create(options); context.client.tickets.set(ticketChannel.id, { userId: context.user.id, claimedBy: null, timestamp: Date.now(), topic: topic }); const embed = new EmbedBuilder().setTitle(`Ticket Created: ${topic}`).setDescription(`Welcome <@${context.user.id}>! Staff will be with you shortly.`).setColor("Green").setTimestamp(); const closeButton = new ButtonBuilder().setCustomId(`ticket_close_${ticketChannel.id}`).setLabel("Close Ticket").setStyle(ButtonStyle.Danger); const claimButton = new ButtonBuilder().setCustomId(`ticket_claim_${ticketChannel.id}`).setLabel("Claim Ticket").setStyle(ButtonStyle.Primary); const row = new ActionRowBuilder().addComponents(closeButton, claimButton); await ticketChannel.send({ content: `<@${context.user.id}>`, embeds: [embed], components: [row] }); return ticketChannel.id; // Return new channel ID } catch (e) { return `[Error creating ticket: ${e.message}]`; } } }; // Note: Button handlers (ticket_close_*, ticket_claim_*) need separate commands.