mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 00:03:09 +02:00
parent
621c49c4e6
commit
3a47a7df3f
@ -399,6 +399,11 @@ ticket:
|
||||
title: ❓ {requestedBy} wants to close this ticket
|
||||
wait_for_staff: ✋ Please wait for staff to close this ticket.
|
||||
wait_for_user: ✋ Please wait for the user to respond.
|
||||
closing_soon:
|
||||
description: |
|
||||
This ticket will be closed due to inactivity <t:{timestamp}:R>.
|
||||
Send a message to cancel this automation.
|
||||
title: ⌛ This ticket will be closed soon
|
||||
created:
|
||||
description: "Your ticket channel has been created: {channel}."
|
||||
title: ✅ Ticket created
|
||||
@ -406,6 +411,11 @@ ticket:
|
||||
description: Your changes have been saved.
|
||||
title: ✅ Ticket updated
|
||||
feedback: Thank you for your feedback.
|
||||
inactive:
|
||||
description: |
|
||||
There hasn't been any activity in this channel since <t:{timestamp}:R>.
|
||||
Please continue the conversation or {close} the ticket.
|
||||
title: ⏰ This ticket is inactive
|
||||
offline:
|
||||
description:
|
||||
There aren't any staff members available at the moment, so it may
|
||||
|
@ -9,6 +9,13 @@ const { version } = require('../../../package.json');
|
||||
const { msToMins } = require('../../lib/misc');
|
||||
const sync = require('../../lib/sync');
|
||||
const checkForUpdates = require('../../lib/updates');
|
||||
const { isStaff } = require('../../lib/users');
|
||||
const {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle,
|
||||
} = require('discord.js');
|
||||
const ExtendedEmbedBuilder = require('../../lib/embed');
|
||||
|
||||
module.exports = class extends Listener {
|
||||
constructor(client, options) {
|
||||
@ -137,20 +144,101 @@ module.exports = class extends Listener {
|
||||
setInterval(() => checkForUpdates(client), ms('1w'));
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
// TODO: check lastMessageAt and set stale
|
||||
// this.$stale.set(ticket.id, {
|
||||
// closeAt: ticket.guild.autoClose ? Date.now() + ticket.guild.autoClose : null,
|
||||
// closedBy: null, // null if set as stale due to inactivity
|
||||
// message: sent,
|
||||
// messages: 0,
|
||||
// reason: 'inactivity',
|
||||
// staleSince: Date.now(),
|
||||
// });
|
||||
// send inactivity warnings and close stale tickets
|
||||
const staleInterval = ms('5m');
|
||||
setInterval(async () => {
|
||||
// close stale tickets
|
||||
for (const [ticketId, $] of client.tickets.$stale) {
|
||||
const autoCloseAfter = $.closeAt - $.staleSince;
|
||||
const halfway = $.closeAt - (autoCloseAfter / 2);
|
||||
if (Date.now() >= halfway && Date.now() < halfway + staleInterval) {
|
||||
const channel = client.channels.cache.get(ticketId);
|
||||
if (!channel) continue;
|
||||
const { guild } = await client.prisma.ticket.findUnique({
|
||||
select: { guild: true },
|
||||
where: { id: ticketId },
|
||||
});
|
||||
const getMessage = client.i18n.getLocale(guild.locale);
|
||||
await channel.send({
|
||||
embeds: [
|
||||
new ExtendedEmbedBuilder()
|
||||
.setColor(guild.primaryColour)
|
||||
.setTitle(getMessage('ticket.closing_soon.title'))
|
||||
.setDescription(getMessage('ticket.closing_soon.description', { timestamp: Math.floor($.closeAt / 1000) })),
|
||||
],
|
||||
});
|
||||
} else if ($.closeAt < Date.now()) {
|
||||
client.tickets.finallyClose(ticketId, $.reason);
|
||||
}
|
||||
}
|
||||
|
||||
// for (const [ticketId, $] of client.tickets.$stale) {
|
||||
// // ⌛
|
||||
// }
|
||||
}, ms('5m'));
|
||||
const guilds = await client.prisma.guild.findMany({
|
||||
include: {
|
||||
tickets: {
|
||||
include: { category: true },
|
||||
where: { open: true },
|
||||
},
|
||||
},
|
||||
// where: { staleAfter: { not: null } },
|
||||
where: { staleAfter: { gte: staleInterval } },
|
||||
});
|
||||
|
||||
// set inactive tickets as stale
|
||||
for (const guild of guilds) {
|
||||
for (const ticket of guild.tickets) {
|
||||
// if (ticket.lastMessageAt && ticket.lastMessageAt < Date.now() - guild.staleAfter)
|
||||
if (ticket.lastMessageAt && Date.now() - ticket.lastMessageAt > guild.staleAfter) {
|
||||
/** @type {import("discord.js").TextChannel} */
|
||||
const channel = client.channels.cache.get(ticket.id);
|
||||
const messages = (await channel.messages.fetch({ limit: 5 })).filter(m => m.author.id !== client.user.id);
|
||||
let ping = '';
|
||||
|
||||
if (messages.size > 0) {
|
||||
const lastMessage = messages.first();
|
||||
const staff = await isStaff(channel.guild, lastMessage.author.id);
|
||||
if (staff) ping = lastMessage.author.toString();
|
||||
else ping = ticket.category.pingRoles.map(r => `<@&${r}>`).join(' ');
|
||||
}
|
||||
|
||||
const getMessage = client.i18n.getLocale(guild.locale);
|
||||
const closeComamnd = client.application.commands.cache.find(c => c.name === 'close');
|
||||
const sent = await channel.send({
|
||||
components: [
|
||||
new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(JSON.stringify({ action: 'close' }))
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
.setEmoji(getMessage('buttons.close.emoji'))
|
||||
.setLabel(getMessage('buttons.close.text')),
|
||||
),
|
||||
],
|
||||
content: ping,
|
||||
embeds: [
|
||||
new ExtendedEmbedBuilder({
|
||||
iconURL: channel.guild.iconURL(),
|
||||
text: guild.footer,
|
||||
})
|
||||
.setColor(guild.primaryColour)
|
||||
.setTitle(getMessage('ticket.inactive.title'))
|
||||
.setDescription(getMessage('ticket.inactive.description', {
|
||||
close: `</${closeComamnd.name}:${closeComamnd.id}>`,
|
||||
timestamp: Math.floor(ticket.lastMessageAt.getTime() / 1000),
|
||||
})),
|
||||
],
|
||||
});
|
||||
|
||||
client.tickets.$stale.set(ticket.id, {
|
||||
closeAt: guild.autoClose ? Date.now() + guild.autoClose : null,
|
||||
closedBy: null,
|
||||
message: sent,
|
||||
messages: 0,
|
||||
reason: 'inactivity',
|
||||
staleSince: Date.now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, staleInterval);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user