147 lines
4.4 KiB
TypeScript
147 lines
4.4 KiB
TypeScript
|
import {
|
||
|
Client,
|
||
|
MessageReaction,
|
||
|
Collection,
|
||
|
Snowflake,
|
||
|
TextChannel,
|
||
|
Message,
|
||
|
MessageEmbed,
|
||
|
MessageOptions,
|
||
|
ColorResolvable,
|
||
|
} from "discord.js";
|
||
|
import {
|
||
|
starMessageData,
|
||
|
StarboardClientOptions,
|
||
|
StarboardGuild,
|
||
|
} from "./starboard.interface";
|
||
|
|
||
|
export class StarboardClient {
|
||
|
public client: Client;
|
||
|
public color: ColorResolvable;
|
||
|
public guilds: StarboardGuild[];
|
||
|
public cache: Collection<Snowflake, starMessageData[]> = new Collection();
|
||
|
|
||
|
constructor(options: StarboardClientOptions) {
|
||
|
this.client = options.client;
|
||
|
this.color = options.color || "RANDOM";
|
||
|
this.guilds = options.Guilds || [];
|
||
|
this.client.on("ready", () => this.cacheData());
|
||
|
}
|
||
|
public config = {
|
||
|
guilds: {
|
||
|
set: (StarboardGuilds: StarboardGuild[]) => {
|
||
|
this.guilds = StarboardGuilds;
|
||
|
this.cacheData();
|
||
|
},
|
||
|
add: (StarboardGuild: StarboardGuild) => {
|
||
|
const filtered = (this.guilds || []).filter(
|
||
|
x => x.id === StarboardGuild.id
|
||
|
);
|
||
|
|
||
|
this.guilds = [...filtered, StarboardGuild];
|
||
|
this.cacheData();
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
private cacheData() {
|
||
|
this.guilds.forEach(async guild => {
|
||
|
const channel = this.client.channels.cache.get(
|
||
|
guild.options.starboardChannel
|
||
|
) as TextChannel;
|
||
|
if (!channel) return;
|
||
|
const messages = await channel.messages.fetch({ limit: 100 });
|
||
|
if (!messages) return;
|
||
|
const value = messages.reduce(
|
||
|
(accumulator: starMessageData[], message) => {
|
||
|
if (message.author.id !== this.client.user.id) return accumulator;
|
||
|
const starCount = message.content.match(/(?<=\*\*)\d*(?=\*\*)/)?.[0];
|
||
|
const origin = message.embeds?.[0]?.footer?.text.match(/\d*/)?.[0];
|
||
|
if (!starCount || !origin) return accumulator;
|
||
|
const data: starMessageData = {
|
||
|
id: message.id,
|
||
|
origin,
|
||
|
};
|
||
|
return [...accumulator, data];
|
||
|
},
|
||
|
[]
|
||
|
);
|
||
|
this.cache.set(guild.id, value);
|
||
|
});
|
||
|
}
|
||
|
private validGuild(guild: Snowflake): Boolean {
|
||
|
return this.guilds.some(x => x.id === guild);
|
||
|
}
|
||
|
private getData(guildId: Snowflake): StarboardGuild {
|
||
|
return this.guilds.find(x => x.id === guildId);
|
||
|
}
|
||
|
private generateEdit(starCount: number, message: Message): MessageOptions {
|
||
|
return {
|
||
|
content: `⭐ **${starCount}** ${message.channel}`,
|
||
|
embeds: [
|
||
|
new MessageEmbed()
|
||
|
.setAuthor(
|
||
|
message.author.tag,
|
||
|
message.author.displayAvatarURL({ dynamic: true })
|
||
|
)
|
||
|
.setColor(this.color)
|
||
|
.setDescription(
|
||
|
`Content: ${message.content ? message.content : "None"}`
|
||
|
)
|
||
|
.setThumbnail(message.author.displayAvatarURL({ dynamic: true }))
|
||
|
.addField("Message", `[Jump!](${message.url})`)
|
||
|
.setImage(message.attachments.first()?.url || null)
|
||
|
.setTimestamp(message.createdTimestamp)
|
||
|
.setFooter(message.id),
|
||
|
],
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public async listener(reaction: MessageReaction) {
|
||
|
if (!this.validGuild) return;
|
||
|
if (reaction.message.partial) await reaction.message.fetch();
|
||
|
if (reaction.partial) await reaction.fetch();
|
||
|
const { guildId, id } = reaction.message;
|
||
|
if (
|
||
|
reaction.emoji.name !== "⭐"
|
||
|
// ||reaction.count < this.getData(guildId)?.options.starCount
|
||
|
)
|
||
|
return;
|
||
|
const data = this.cache.get(guildId) || [];
|
||
|
const starboardChannel = this.client.channels.cache.get(
|
||
|
this.guilds.find(x => x.id === guildId)?.options.starboardChannel
|
||
|
) as TextChannel;
|
||
|
const getMessage = data.find(x => x.origin === id);
|
||
|
|
||
|
const generateEdit = this.generateEdit(
|
||
|
reaction.count,
|
||
|
reaction.message as Message
|
||
|
);
|
||
|
const sendMessage = () => {
|
||
|
starboardChannel?.send(generateEdit).then(m => {
|
||
|
this.cache.set(reaction.message.guildId, [
|
||
|
...data,
|
||
|
{ id: m.id, origin: reaction.message.id },
|
||
|
]);
|
||
|
});
|
||
|
};
|
||
|
if (getMessage) {
|
||
|
if (reaction.count === 0) {
|
||
|
setTimeout(
|
||
|
() =>
|
||
|
starboardChannel.messages
|
||
|
.fetch(getMessage.id)
|
||
|
.then(async r => await r.delete()),
|
||
|
10000
|
||
|
);
|
||
|
} else {
|
||
|
starboardChannel.messages
|
||
|
.fetch(getMessage.id)
|
||
|
.then(publishedMessage => {
|
||
|
publishedMessage.edit(generateEdit);
|
||
|
})
|
||
|
.catch(sendMessage);
|
||
|
}
|
||
|
} else sendMessage();
|
||
|
}
|
||
|
}
|