MCPcopy Index your code
hub / github.com/codebymitch/TitanBot / closeTicket

Function closeTicket

src/services/ticket.js:236–437  ·  view source on GitHub ↗
(channel, closer, reason = 'No reason provided')

Source from the content-addressed store, hash-verified

234}
235
236export async function closeTicket(channel, closer, reason = 'No reason provided') {
237 try {
238 const ticketData = await getTicketData(channel.guild.id, channel.id);
239 if (!ticketData) {
240 return { success: false, error: 'This is not a ticket channel' };
241 }
242
243 const config = await getGuildConfig(channel.client, channel.guild.id);
244 const dmOnClose = config.dmOnClose !== false;
245 const closedCategoryId = config.ticketClosedCategoryId || null;
246 let movedToClosedCategory = false;
247
248 ticketData.status = 'closed';
249 ticketData.closedBy = closer.id;
250 ticketData.closedAt = new Date().toISOString();
251 ticketData.closeReason = reason;
252
253 await saveTicketData(channel.guild.id, channel.id, ticketData);
254
255 if (closedCategoryId && channel.parentId !== closedCategoryId) {
256 const closedCategory = channel.guild.channels.cache.get(closedCategoryId)
257 || await channel.guild.channels.fetch(closedCategoryId).catch(() => null);
258
259 if (closedCategory?.type === ChannelType.GuildCategory) {
260 try {
261 await channel.setParent(closedCategoryId, { lockPermissions: false });
262 movedToClosedCategory = true;
263 } catch (moveError) {
264 logger.warn(`Could not move ticket ${channel.id} to closed category ${closedCategoryId}: ${moveError.message}`);
265 }
266 } else {
267 logger.warn(`Configured closed category is invalid for guild ${channel.guild.id}: ${closedCategoryId}`);
268 }
269 }
270
271 if (dmOnClose) {
272 try {
273 const ticketCreator = await channel.client.users.fetch(ticketData.userId).catch(() => null);
274 if (ticketCreator) {
275 const dmEmbed = createEmbed({
276 title: '🎫 Your Ticket Has Been Closed',
277 description: `Your ticket **${channel.name}** has been closed.\n\n**Reason:** ${reason}\n**Closed by:** ${closer.tag}\n**Closed at:** <t:${Math.floor(Date.now() / 1000)}:F>\n\nThank you for using our support system! If you have any further questions, feel free to create a new ticket.`,
278 color: '#e74c3c',
279 footer: { text: `Ticket ID: ${ticketData.id}` }
280 });
281
282 await ticketCreator.send({ embeds: [dmEmbed] });
283
284 try {
285 const feedbackEmbed = createEmbed({
286 title: '⭐ How was your support experience?',
287 description: `We'd love to know how we did with **${channel.name}**.\nSelect a rating below — it only takes a second!`,
288 color: '#F1C40F',
289 footer: { text: 'Your feedback helps us improve.' },
290 });
291
292 const base = `ticket_feedback:${channel.guild.id}:${channel.id}`;
293 const starsRow = new ActionRowBuilder().addComponents(

Callers 2

executeFunction · 0.90
executeFunction · 0.90

Calls 8

getTicketDataFunction · 0.90
getGuildConfigFunction · 0.90
saveTicketDataFunction · 0.90
createEmbedFunction · 0.90
logTicketEventFunction · 0.90
ensureTypedServiceErrorFunction · 0.90
editMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected