mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-22 15:53:08 +02:00
Progress on message archiving
This commit is contained in:
parent
9682fcf22b
commit
460138fb73
@ -22,7 +22,7 @@ model ArchivedChannel {
|
||||
model ArchivedMessage {
|
||||
author ArchivedUser @relation(fields: [ticketId, authorId], references: [ticketId, userId], onDelete: Cascade)
|
||||
authorId String @db.VarChar(19)
|
||||
content Json
|
||||
content String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
deleted Boolean @default(false)
|
||||
edited Boolean @default(false)
|
||||
@ -50,17 +50,17 @@ model ArchivedRole {
|
||||
|
||||
model ArchivedUser {
|
||||
archivedMessages ArchivedMessage[]
|
||||
avatar String
|
||||
avatar String?
|
||||
bot Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
discriminator String @db.Char(4)
|
||||
displayName String @db.Text
|
||||
role ArchivedRole @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String @db.VarChar(19)
|
||||
discriminator String? @db.Char(4)
|
||||
displayName String? @db.Text
|
||||
role ArchivedRole? @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String? @db.VarChar(19)
|
||||
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||
ticketId String @db.VarChar(19)
|
||||
userId String @db.VarChar(19)
|
||||
username String @db.Text
|
||||
username String? @db.Text
|
||||
|
||||
@@id([ticketId, userId])
|
||||
@@unique([ticketId, userId])
|
||||
@ -68,30 +68,30 @@ model ArchivedUser {
|
||||
}
|
||||
|
||||
model Category {
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String @db.VarChar(19)
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String @db.VarChar(19)
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String @db.Text
|
||||
pingRoles Json @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles Json @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles Json
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String @db.VarChar(19)
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String @db.VarChar(19)
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String @db.Text
|
||||
pingRoles Json @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles Json @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles Json
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ model ArchivedChannel {
|
||||
model ArchivedMessage {
|
||||
author ArchivedUser @relation(fields: [ticketId, authorId], references: [ticketId, userId], onDelete: Cascade)
|
||||
authorId String @db.VarChar(19)
|
||||
content Json
|
||||
content String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
deleted Boolean @default(false)
|
||||
edited Boolean @default(false)
|
||||
@ -50,17 +50,17 @@ model ArchivedRole {
|
||||
|
||||
model ArchivedUser {
|
||||
archivedMessages ArchivedMessage[]
|
||||
avatar String
|
||||
avatar String?
|
||||
bot Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
discriminator String @db.Char(4)
|
||||
displayName String @db.Text
|
||||
role ArchivedRole @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String @db.VarChar(19)
|
||||
discriminator String? @db.Char(4)
|
||||
displayName String? @db.Text
|
||||
role ArchivedRole? @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String? @db.VarChar(19)
|
||||
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||
ticketId String @db.VarChar(19)
|
||||
userId String @db.VarChar(19)
|
||||
username String @db.Text
|
||||
username String? @db.Text
|
||||
|
||||
@@id([ticketId, userId])
|
||||
@@unique([ticketId, userId])
|
||||
@ -68,30 +68,30 @@ model ArchivedUser {
|
||||
}
|
||||
|
||||
model Category {
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String @db.VarChar(19)
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String @db.VarChar(19)
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String @db.Text
|
||||
pingRoles Json @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles Json @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles Json
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String @db.VarChar(19)
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String @db.VarChar(19)
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String @db.Text
|
||||
pingRoles Json @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles Json @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles Json
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
@ -50,17 +50,17 @@ model ArchivedRole {
|
||||
|
||||
model ArchivedUser {
|
||||
archivedMessages ArchivedMessage[]
|
||||
avatar String
|
||||
avatar String?
|
||||
bot Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
discriminator String
|
||||
displayName String
|
||||
role ArchivedRole @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String
|
||||
discriminator String?
|
||||
displayName String?
|
||||
role ArchivedRole? @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||
roleId String?
|
||||
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||
ticketId String
|
||||
userId String
|
||||
username String
|
||||
username String?
|
||||
|
||||
@@id([ticketId, userId])
|
||||
@@unique([ticketId, userId])
|
||||
@ -68,30 +68,30 @@ model ArchivedUser {
|
||||
}
|
||||
|
||||
model Category {
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String
|
||||
pingRoles String @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles String @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles String
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
channelName String
|
||||
claiming Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
cooldown Int?
|
||||
customTopic String?
|
||||
description String
|
||||
discordCategory String
|
||||
emoji String
|
||||
enableFeedback Boolean @default(false)
|
||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||
guildId String
|
||||
id Int @id @default(autoincrement())
|
||||
image String?
|
||||
memberLimit Int @default(1)
|
||||
name String
|
||||
openingMessage String
|
||||
pingRoles String @default("[]")
|
||||
questions Question[]
|
||||
ratelimit Int?
|
||||
requiredRoles String @default("[]")
|
||||
requireTopic Boolean @default(false)
|
||||
staffRoles String
|
||||
tickets Ticket[]
|
||||
totalLimit Int @default(50)
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ module.exports = class CreateMessageCommand extends MessageCommand {
|
||||
* @param {import("discord.js").MessageContextMenuCommandInteraction} interaction
|
||||
*/
|
||||
async run(interaction) {
|
||||
// TODO: archive message
|
||||
await useGuild(this.client, interaction, { referencesMessage: interaction.targetMessage.channelId + '/' + interaction.targetId });
|
||||
}
|
||||
};
|
@ -1,11 +1,255 @@
|
||||
const Cryptr = require('cryptr');
|
||||
// const cryptr = new Cryptr(process.env.ENCRYPTION_KEY);
|
||||
const cryptr = new Cryptr(process.env.ENCRYPTION_KEY);
|
||||
|
||||
/**
|
||||
* Returns highest (roles.highest) hoisted role , or everyone
|
||||
* @param {import("discord.js").GuildMember} member
|
||||
* @returns {import("discord.js").Role}
|
||||
*/
|
||||
const hoistedRole = member => member.roles.hoist || member.guild.roles.everyone;
|
||||
|
||||
module.exports = class TicketArchiver {
|
||||
constructor(client) {
|
||||
/** @type {import("client")} */
|
||||
this.client = client;
|
||||
this.encrypt = cryptr.encrypt;
|
||||
this.decrypt = cryptr.decrypt;
|
||||
}
|
||||
|
||||
async addMessage() {}
|
||||
/** Add or update a message
|
||||
* @param {string} ticketId
|
||||
* @param {import("discord.js").Message} message
|
||||
* @param {boolean?} external
|
||||
* @returns {import("@prisma/client").ArchivedMessage|boolean}
|
||||
*/
|
||||
async saveMessage(ticketId, message, external = false) {
|
||||
if (this.client.config.overrides.disableArchives) return false;
|
||||
|
||||
if (!message.member) {
|
||||
try {
|
||||
message.member = await message.guild.members.fetch(message.author.id);
|
||||
} catch {
|
||||
this.client.log.verbose('Failed to fetch member %s of %s', message.author.id, message.guild.id);
|
||||
}
|
||||
}
|
||||
|
||||
const channels = message.mentions.channels;
|
||||
const members = [...message.mentions.members];
|
||||
const roles = [...message.mentions.roles];
|
||||
|
||||
if (message.member) {
|
||||
members.push(message.member);
|
||||
roles.push(hoistedRole(message.member));
|
||||
} else {
|
||||
this.client.log.warn('Message member does not exist');
|
||||
await this.client.prisma.archivedUser.upsert({
|
||||
create: {},
|
||||
update: {},
|
||||
where: {
|
||||
ticketId_userId: {
|
||||
ticketId,
|
||||
userId: 'default',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (const role of roles) {
|
||||
const data = {
|
||||
colour: role.hexColor.slice(1),
|
||||
name: role.name,
|
||||
roleId: role.id,
|
||||
ticket: { connect: { id: ticketId } },
|
||||
};
|
||||
await this.client.prisma.archivedRole.upsert({
|
||||
create: data,
|
||||
update: data,
|
||||
where: {
|
||||
ticketId_roleId: {
|
||||
roleId: role.id,
|
||||
ticketId,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (const member of members) {
|
||||
const data = {
|
||||
avatar: member.avatar || member.user.avatar, // TODO: save avatar in user/avatars/
|
||||
bot: member.user.bot,
|
||||
discriminator: member.user.discriminator,
|
||||
displayName: member.displayName ? this.encrypt(member.displayName) : null,
|
||||
roleId: !!member && hoistedRole(member).id,
|
||||
ticketId,
|
||||
userId: member.user.id,
|
||||
username: this.encrypt(member.user.username),
|
||||
};
|
||||
await this.client.prisma.archivedUser.upsert({
|
||||
create: data,
|
||||
update: data,
|
||||
where: {
|
||||
ticketId_userId: {
|
||||
ticketId,
|
||||
userId: member.user.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const messageD = {
|
||||
author: {
|
||||
connect: {
|
||||
ticketId_userId: {
|
||||
ticketId,
|
||||
userId: message.author?.id || 'default',
|
||||
},
|
||||
},
|
||||
},
|
||||
content: cryptr.encrypt(
|
||||
JSON.stringify({
|
||||
attachments: [...message.attachments.values()],
|
||||
components: [...message.components.values()],
|
||||
content: message.content,
|
||||
embeds: message.embeds.map(embed => ({ embed })),
|
||||
}),
|
||||
),
|
||||
createdAt: message.createdAt,
|
||||
edited: !!message.editedAt,
|
||||
external,
|
||||
id: message.id,
|
||||
};
|
||||
|
||||
await this.client.prisma.ticket.update({
|
||||
data: {
|
||||
archivedChannels: {
|
||||
upsert: channels.map(channel => {
|
||||
const data = {
|
||||
channelId: channel.id,
|
||||
name: channel.name,
|
||||
};
|
||||
return {
|
||||
create: data,
|
||||
update: data,
|
||||
where: {
|
||||
ticketId_channelId: {
|
||||
channelId: channel.id,
|
||||
ticketId,
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
},
|
||||
archivedMessages: {
|
||||
upsert: {
|
||||
create: messageD,
|
||||
update: messageD,
|
||||
where: { id: message.id },
|
||||
},
|
||||
},
|
||||
},
|
||||
where: { id: ticketId },
|
||||
});
|
||||
|
||||
// await this.client.prisma.ticket.update({
|
||||
// data: {
|
||||
// archivedChannels: {
|
||||
// upsert: channels.map(channel => {
|
||||
// const data = {
|
||||
// channelId: channel.id,
|
||||
// name: channel.name,
|
||||
// };
|
||||
// return {
|
||||
// create: data,
|
||||
// update: data,
|
||||
// where: {
|
||||
// ticketId_channelId: {
|
||||
// channelId: channel.id,
|
||||
// ticketId,
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// }),
|
||||
// },
|
||||
// archivedRoles: {
|
||||
// upsert: roles.map(role => {
|
||||
// const data = {
|
||||
// colour: role.hexColor.slice(1),
|
||||
// name: role.name,
|
||||
// roleId: role.id,
|
||||
// };
|
||||
// return {
|
||||
// create: data,
|
||||
// update: data,
|
||||
// where: {
|
||||
// ticketId_roleId: {
|
||||
// roleId: role.id,
|
||||
// ticketId,
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// }),
|
||||
// },
|
||||
// archivedUsers: {
|
||||
// upsert: members.map(member => {
|
||||
// // message author might have left the server (this message could be external/referenced)
|
||||
// const data = {
|
||||
// avatar: member?.avatar || member.user?.avatar, // TODO: save avatar in user/avatars/
|
||||
// bot: member.user?.bot,
|
||||
// discriminator: member.user?.discriminator,
|
||||
// displayName: member?.displayName ? this.encrypt(member?.displayName) : null,
|
||||
// // role: !!member && {
|
||||
// // connectOrCreate: {
|
||||
// // create: {
|
||||
// // colour: hoistedRole(member).hexColor.slice(1),
|
||||
// // name: hoistedRole(member).name,
|
||||
// // roleId: hoistedRole(member).id,
|
||||
// // ticket: { connect: { id: ticketId } },
|
||||
// // },
|
||||
// // where: {
|
||||
// // roleId: hoistedRole(member).id,
|
||||
// // ticketId,
|
||||
// // },
|
||||
// // },
|
||||
// // },
|
||||
// roleId: !!member && hoistedRole(member).id,
|
||||
// userId: member.user?.id || 'default',
|
||||
// username: member.user?.username ? this.encrypt(member.user.username) : null,
|
||||
// };
|
||||
// return {
|
||||
// create: data,
|
||||
// update: data,
|
||||
// where: {
|
||||
// ticketId_userId: {
|
||||
// ticketId,
|
||||
// userId: member.user.id,
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// }),
|
||||
// },
|
||||
// },
|
||||
// where: { id: ticketId },
|
||||
// });
|
||||
|
||||
// const messageD = {
|
||||
// author: { connect: { id: message.author?.id || 'default' } },
|
||||
// content: cryptr.encrypt(
|
||||
// JSON.stringify({
|
||||
// attachments: [...message.attachments.values()],
|
||||
// components: [...message.components.values()],
|
||||
// content: message.content,
|
||||
// embeds: message.embeds.map(embed => ({ embed })),
|
||||
// }),
|
||||
// ),
|
||||
// createdAt: message.createdAt,
|
||||
// edited: !!message.editedAt,
|
||||
// external,
|
||||
// };
|
||||
|
||||
// return await this.client.prisma.archivedMessage.upsert({
|
||||
// create: messageD,
|
||||
// update: messageD,
|
||||
// where: { id: message.id },
|
||||
// });
|
||||
}
|
||||
};
|
@ -474,36 +474,50 @@ module.exports = class TicketManager {
|
||||
.catch(() => this.client.log.warn('Failed to delete system pin message'));
|
||||
}
|
||||
|
||||
// TODO: referenced msg or ticket
|
||||
|
||||
/** @type {import("discord.js").Message|undefined} */
|
||||
let message;
|
||||
if (referencesMessage) {
|
||||
referencesMessage = referencesMessage.split('/');
|
||||
/** @type {import("discord.js").Message} */
|
||||
const message = await (await this.client.channels.fetch(referencesMessage[0]))?.messages.fetch(referencesMessage[1]);
|
||||
message = await (await this.client.channels.fetch(referencesMessage[0]))?.messages.fetch(referencesMessage[1]);
|
||||
if (message) {
|
||||
await channel.send({
|
||||
embeds: [
|
||||
new ExtendedEmbedBuilder()
|
||||
.setColor(category.guild.primaryColour)
|
||||
.setTitle(getMessage('ticket.references_message.title'))
|
||||
.setDescription(
|
||||
getMessage('ticket.references_message.description', {
|
||||
author: message.author.toString(),
|
||||
timestamp: `<t:${Math.ceil(message.createdTimestamp / 1000)}:R>`,
|
||||
url: message.url,
|
||||
})),
|
||||
new ExtendedEmbedBuilder({
|
||||
iconURL: guild.iconURL(),
|
||||
text: category.guild.footer,
|
||||
})
|
||||
.setColor(category.guild.primaryColour)
|
||||
.setAuthor({
|
||||
iconURL: message.member?.displayAvatarURL(),
|
||||
name: message.member?.displayName || 'Unknown',
|
||||
})
|
||||
.setDescription(message.content.substring(0, 1000) + message.content.length > 1000 ? '...' : ''),
|
||||
],
|
||||
});
|
||||
// not worth the effort of making system messages work atm
|
||||
if (message.system) {
|
||||
referencesMessage = null;
|
||||
message = null;
|
||||
} else {
|
||||
if (!message.member) {
|
||||
try {
|
||||
message.member = await message.guild.members.fetch(message.author.id);
|
||||
} catch {
|
||||
this.client.log.verbose('Failed to fetch member %s of %s', message.author.id, message.guild.id);
|
||||
}
|
||||
await channel.send({
|
||||
embeds: [
|
||||
new ExtendedEmbedBuilder()
|
||||
.setColor(category.guild.primaryColour)
|
||||
.setTitle(getMessage('ticket.references_message.title'))
|
||||
.setDescription(
|
||||
getMessage('ticket.references_message.description', {
|
||||
author: message.author.toString(),
|
||||
timestamp: `<t:${Math.ceil(message.createdTimestamp / 1000)}:R>`,
|
||||
url: message.url,
|
||||
})),
|
||||
new ExtendedEmbedBuilder({
|
||||
iconURL: guild.iconURL(),
|
||||
text: category.guild.footer,
|
||||
})
|
||||
.setColor(category.guild.primaryColour)
|
||||
.setAuthor({
|
||||
iconURL: message.member?.displayAvatarURL(),
|
||||
name: message.member?.displayName || 'Unknown',
|
||||
})
|
||||
.setDescription(message.content.substring(0, 1000) + (message.content.length > 1000 ? '...' : '')),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else if (referencesTicketId) {
|
||||
// TODO: add portal url
|
||||
@ -554,9 +568,6 @@ module.exports = class TicketManager {
|
||||
topic: topic ? cryptr.encrypt(topic) : null,
|
||||
};
|
||||
if (referencesTicketId) data.referencesTicket = { connect: { id: referencesTicketId } };
|
||||
let message;
|
||||
if (referencesMessage) message = await this.client.prisma.archivedMessage.findUnique({ where: { id: referencesMessage[1] } });
|
||||
if (message) data.referencesMessage = { connect: { id: referencesMessage[0] } }; // only add if the message has been archived ^^
|
||||
if (answers) data.questionAnswers = { createMany: { data: answers } };
|
||||
await interaction.editReply({
|
||||
components: [],
|
||||
@ -583,6 +594,16 @@ module.exports = class TicketManager {
|
||||
await this.client.keyv.set(cacheKey, expiresAt, TTL);
|
||||
}
|
||||
|
||||
if (category.guild.archive && message) {
|
||||
const row = await this.archiver.saveMessage(ticket.id, message, true);
|
||||
if (row) {
|
||||
await this.client.prisma.ticket.update({
|
||||
data: { referencesMessageId: row.id },
|
||||
where: { id: ticket.id },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
logTicketEvent(this.client, {
|
||||
action: 'create',
|
||||
target: {
|
||||
|
@ -177,11 +177,34 @@ module.exports = class extends Listener {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// TODO: archive messages in tickets
|
||||
// TODO: first response
|
||||
// TODO: lastMessageAt
|
||||
// TODO: auto tag
|
||||
// TODO: staff status alert, working hours alerts
|
||||
let ticket = await client.prisma.ticket.findUnique({
|
||||
include: { guild: true },
|
||||
where: { id: message.channel.id },
|
||||
});
|
||||
|
||||
if (ticket) {
|
||||
if (ticket.guild.archive) {
|
||||
try {
|
||||
await client.tickets.archiver.saveMessage(ticket.id, message);
|
||||
} catch (error) {
|
||||
client.log.warn('Failed to archive message', message.id);
|
||||
client.log.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (ticket.firstResponseAt === null) {
|
||||
ticket = await client.prisma.ticket.update({
|
||||
data: { firstResponseAt: new Date() },
|
||||
where: { id: ticket.id },
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: lastMessageAt
|
||||
// TODO: staff status alert, working hours alerts
|
||||
} else {
|
||||
// TODO: auto tag
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user