From 59dec2880414bc2e3c6712433717c5e56184e788 Mon Sep 17 00:00:00 2001 From: Isaac Date: Thu, 23 Mar 2023 21:48:46 +0000 Subject: [PATCH] feat: notify when staff are offline (closes #304) --- package.json | 2 +- src/client.js | 5 +++-- src/i18n/en-GB.yml | 5 +++++ src/lib/tickets/manager.js | 23 ++++++++++++++++++++++- src/listeners/client/messageCreate.js | 21 ++++++++++++++++++++- 5 files changed, 51 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 27d4392..b51509e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-tickets", - "version": "4.0.0-beta.9", + "version": "4.0.0-beta.10", "private": "true", "description": "An open-source Discord bot for ticket management", "main": "src/", diff --git a/src/client.js b/src/client.js index 82122fb..0b2567d 100644 --- a/src/client.js +++ b/src/client.js @@ -23,10 +23,11 @@ module.exports = class Client extends FrameworkClient { GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, + GatewayIntentBits.GuildPresences, ], partials: [ - Partials.Message, Partials.Channel, + Partials.Message, Partials.Reaction, ], }); @@ -66,4 +67,4 @@ module.exports = class Client extends FrameworkClient { await this.prisma.$disconnect(); return super.destroy(); } -}; \ No newline at end of file +}; diff --git a/src/i18n/en-GB.yml b/src/i18n/en-GB.yml index b2c267e..042d884 100644 --- a/src/i18n/en-GB.yml +++ b/src/i18n/en-GB.yml @@ -403,6 +403,11 @@ ticket: description: Your changes have been saved. title: ✅ Ticket updated feedback: Thank you for your feedback. + offline: + description: + There aren't any staff members available at the moment, so it may + take longer than usual to get a response. + title: 😴 We're not online opening_message: content: | {staff} diff --git a/src/lib/tickets/manager.js b/src/lib/tickets/manager.js index a6d9d6a..cf9ffba 100644 --- a/src/lib/tickets/manager.js +++ b/src/lib/tickets/manager.js @@ -690,6 +690,7 @@ module.exports = class TicketManager { const currentHours = workingHours[now.day()]; const start = now.time(currentHours[0]); const end = now.time(currentHours[1]); + let working = true; if (currentHours[0] === currentHours[1] || now.isAfter(end)) { // staff have the day off or have finished for the day // first look for the next working day *this* week (after today) @@ -697,6 +698,7 @@ module.exports = class TicketManager { // if there isn't one, look for the next working day *next* week (before and including today's weekday) if (!nextIndex) nextIndex = workingHours.findIndex((hours, i) => i <= now.day() && hours[0] !== hours[1]); if (nextIndex) { + working = false; const next = workingHours[nextIndex]; let then = now.add(nextIndex - now.day(), 'day'); if (nextIndex <= now.day()) then = then.add(1, 'week'); @@ -711,6 +713,7 @@ module.exports = class TicketManager { }); } } else if (now.isBefore(start)) { // staff haven't started working yet + working = false; const timestamp = Math.ceil(start.d.getTime() / 1000); // in seconds await channel.send({ embeds: [ @@ -722,7 +725,25 @@ module.exports = class TicketManager { }); } - // TODO: !staff + + if (working) { + let online = 0; + for (const [, member] of message.channel.members) { + if (!await isStaff(message.channel.guild, member.id)) continue; + if (member.presence && member.presence !== 'offline') online++; + } + if (online === 0) { + await channel.send({ + embeds: [ + new ExtendedEmbedBuilder() + .setColor(category.guild.primaryColour) + .setTitle(getMessage('ticket.offline.title')) + .setDescription(getMessage('ticket.offline.description')), + ], + }); + this.client.keyv.set(`offline/${channel.id}`, Date.now(), ms('1h')); + } + } } /** diff --git a/src/listeners/client/messageCreate.js b/src/listeners/client/messageCreate.js index 1cee0ea..96a31d0 100644 --- a/src/listeners/client/messageCreate.js +++ b/src/listeners/client/messageCreate.js @@ -182,6 +182,7 @@ module.exports = class extends Listener { } else { const settings = await client.prisma.guild.findUnique({ where: { id: message.guild.id } }); if (!settings) return; + const getMessage = client.i18n.getLocale(settings.locale); let ticket = await client.prisma.ticket.findUnique({ where: { id: message.channel.id } }); if (ticket) { @@ -230,7 +231,25 @@ module.exports = class extends Listener { } } - // TODO: if (!message.author.bot) staff status alert, working hours alerts + if (!message.author.bot) { + const key = `offline/${message.channel.id}`; + let online = 0; + for (const [, member] of message.channel.members) { + if (!await isStaff(message.channel.guild, member.id)) continue; + if (member.presence && member.presence !== 'offline') online++; + } + if (online === 0 && !client.keyv.has(key)) { + await message.channel.send({ + embeds: [ + new EmbedBuilder() + .setColor(settings.primaryColour) + .setTitle(getMessage('ticket.offline.title')) + .setDescription(getMessage('ticket.offline.description')), + ], + }); + client.keyv.set(key, Date.now(), ms('1h')); + } + } } // auto-tag