Spaces:
Paused
Paused
| import mongoose, { Document, Schema, Model } from 'mongoose'; | |
| import { Message } from 'discord.js'; | |
| // Define TypeScript interfaces for Snipe schema | |
| interface IMessage { | |
| type: 'delete' | 'edit'; | |
| authorTag: string; | |
| authorId: string; | |
| authorAvatar: string; // New field to store the avatar hash | |
| content?: string; // Optional | |
| beforeEdit?: string; // Optional | |
| afterEdit?: string; // Optional | |
| timestamp: Date; | |
| replyToUserId?: string; // User ID of the message being replied to | |
| replyToContent?: string; // Content of the message being replied to | |
| } | |
| interface ISnipe extends Document { | |
| channelId: string; | |
| messages: IMessage[]; | |
| } | |
| // Define the Mongoose schema with explicit typing | |
| const snipeSchema = new Schema<ISnipe>({ | |
| channelId: { type: String, required: true }, | |
| messages: [ | |
| { | |
| type: { type: String, required: true, enum: ['delete', 'edit'] }, | |
| authorTag: { type: String, required: true }, | |
| authorId: { type: String, required: true }, | |
| authorAvatar: { type: String, required: true }, // Store the avatar hash | |
| content: { type: String, required: false }, | |
| beforeEdit: { type: String, required: false }, | |
| afterEdit: { type: String, required: false }, | |
| timestamp: { type: Date, default: Date.now }, | |
| replyToUserId: { type: String, required: false }, | |
| replyToContent: { type: String, required: false }, | |
| }, | |
| ], | |
| }); | |
| // Define the Mongoose model | |
| export const Snipe: Model<ISnipe> = mongoose.models.Snipe || mongoose.model<ISnipe>('Snipe', snipeSchema); | |
| // Track deleted messages with reply info | |
| export const trackDeletedMessages = async (msg: Message): Promise<void> => { | |
| if (!msg.guild || msg.author.bot) return; | |
| const snipeData: IMessage = { | |
| type: 'delete', | |
| authorTag: msg.author.tag, | |
| authorId: msg.author.id, | |
| authorAvatar: msg.author.avatar ?? '', // Save the avatar hash | |
| content: msg.content ?? '[No Content]', | |
| timestamp: new Date(), | |
| replyToUserId: msg.reference?.messageId ? (await msg.fetchReference()).author.id : undefined, | |
| replyToContent: msg.reference?.messageId ? (await msg.fetchReference()).content : undefined, | |
| }; | |
| const channelData = await Snipe.findOne({ channelId: msg.channel.id }); | |
| if (!channelData) { | |
| await Snipe.create({ channelId: msg.channel.id, messages: [snipeData] }); | |
| } else { | |
| channelData.messages.unshift(snipeData); | |
| if (channelData.messages.length > 15) { | |
| channelData.messages.pop(); | |
| } | |
| await channelData.save(); | |
| } | |
| }; | |
| // Track edited messages with reply info | |
| export const trackEditedMessages = async (before: Message, after: Message): Promise<void> => { | |
| if (!before.guild || before.author.bot) return; | |
| const snipeData: IMessage = { | |
| type: 'edit', | |
| authorTag: before.author.tag, | |
| authorId: before.author.id, | |
| authorAvatar: before.author.avatar ?? '', // Save the avatar hash | |
| beforeEdit: before.content ?? '[No Content]', | |
| afterEdit: after.content ?? '[No Content]', | |
| timestamp: new Date(), | |
| replyToUserId: before.reference?.messageId ? (await before.fetchReference()).author.id : undefined, | |
| replyToContent: before.reference?.messageId ? (await before.fetchReference()).content : undefined, | |
| }; | |
| const channelData = await Snipe.findOne({ channelId: before.channel.id }); | |
| if (!channelData) { | |
| await Snipe.create({ channelId: before.channel.id, messages: [snipeData] }); | |
| } else { | |
| channelData.messages.unshift(snipeData); | |
| if (channelData.messages.length > 15) { | |
| channelData.messages.pop(); | |
| } | |
| await channelData.save(); | |
| } | |
| }; |