Skip to content

Commit

Permalink
Sticky Messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Kathund committed Aug 7, 2024
1 parent eaa079d commit 77a2e6c
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
116 changes: 116 additions & 0 deletions src/commands/sticky.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import {
ChatInputCommandInteraction,
PermissionFlagsBits,
SlashCommandBuilder,
EmbedBuilder,
ChannelType
} from 'discord.js';
import { model, Schema } from 'mongoose';

export const data = new SlashCommandBuilder()
.setName('sticky')
.setDescription('Sticky Messages')
.addSubcommand((subcommand) =>
subcommand
.setName('set')
.setDescription('Set a sticky message for a channel')
.addStringOption((option) => option.setName('message').setDescription('Message').setRequired(true))
)
.addSubcommand((subcommand) =>
subcommand
.setName('get')
.setDescription('Get the sticky message for a channel')
.addChannelOption((option) =>
option.setName('channel').setDescription('Channel').addChannelTypes(ChannelType.GuildText).setRequired(false)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('delete')
.setDescription('Delete the sticky message for a channel')
.addChannelOption((option) =>
option.setName('channel').setDescription('Channel').addChannelTypes(ChannelType.GuildText).setRequired(false)
)
)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
.setDMPermission(false);

const userSchema = new Schema({ id: String, staff: Boolean, bot: Boolean });
const stickySchema = new Schema({ content: String, message: String, channel: String, user: userSchema });
const stickyModel = model('Sticky', stickySchema);

export async function getStickyMessage(
channelId: string
): Promise<{ content: string; message: string; channel: string } | null> {
const stickyMessage = await stickyModel.findOne({ channel: channelId });
if (!stickyMessage || !stickyMessage.content || !stickyMessage.message || !stickyMessage.channel) return null;
return { content: stickyMessage.content, message: stickyMessage.message, channel: stickyMessage.channel };
}

export async function updateStickyMessage(channelId: string, messageId: string): Promise<void> {
await stickyModel.findOneAndUpdate({ channel: channelId }, { message: messageId });
}

async function deleteStickyMessage(channelId: string): Promise<void> {
await stickyModel.findOneAndDelete({ channel: channelId });
}

export async function execute(interaction: ChatInputCommandInteraction): Promise<void> {
try {
if (!interaction.channel) return;
const subCommand = interaction.options.getSubcommand();
switch (subCommand) {
case 'set': {
const message = interaction.options.getString('message', true);
const sentMessage = await interaction.channel.send({ content: message });
new stickyModel({
content: message,
message: sentMessage.id,
channel: interaction.channel.id,
user: { id: interaction.user.id, staff: true, bot: interaction.user.bot }
}).save();
await interaction.reply({ content: 'Sticky message has been set', ephemeral: true });
break;
}
case 'get': {
const channel = interaction.options.getChannel('channel') ?? interaction.channel;
if (!channel || channel.type !== ChannelType.GuildText) return;
const stickyMessage = await getStickyMessage(channel.id);
if (!stickyMessage) {
await interaction.reply({ content: 'No sticky message found for this channel', ephemeral: true });
return;
}
await interaction.reply({ content: stickyMessage.content, ephemeral: true });
break;
}
case 'delete': {
const channel = await interaction.guild?.channels.fetch(
interaction.options.getChannel('channel')?.id ?? interaction.channel.id
);
if (!channel || channel.type !== ChannelType.GuildText) return;
const stickyMessage = await getStickyMessage(channel.id);
if (null === stickyMessage) {
await interaction.reply({ content: 'No sticky message found for this channel', ephemeral: true });
return;
}
channel.messages.fetch(stickyMessage.message).then((message) => message.delete());
await deleteStickyMessage(channel.id);
await interaction.reply({ content: 'Sticky message has been deleted', ephemeral: true });
break;
}
default: {
const embed = new EmbedBuilder()
.setTitle('Invalid subcommand')
.setDescription('Please provide a valid subcommand');
await interaction.reply({ embeds: [embed] });
}
}
} catch (error) {
console.log(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'Something went wrong. Please try again later.', ephemeral: true });
return;
}
await interaction.reply({ content: 'Something went wrong. Please try again later.', ephemeral: true });
}
}
7 changes: 7 additions & 0 deletions src/handlers/MessageHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChannelType, GuildMemberRoleManager, Message, TextChannel, Webhook, WebhookType } from 'discord.js';
import { DiscordInviteRegex, HypixelAPIKeyRegex, IPAddressPattern, URLRegex } from '../utils/regex';
import { getStickyMessage, updateStickyMessage } from '../commands/sticky';
import { getAllowedDomains, getAntiLinkState } from '../utils/mongo';
import { autoModBypassRole } from '../../config.json';
import DiscordManager from '../DiscordManager';
Expand All @@ -20,6 +21,12 @@ class MessageHandler {

async onMessage(message: Message) {
if (!message.member) return;
const sticky = await getStickyMessage(message.channel.id);
if (null !== sticky && message.author !== message.client.user) {
message.channel.messages.fetch(sticky.message).then((message) => message.delete());
const newMsg = await message.channel.send({ content: sticky.content });
updateStickyMessage(message.channel.id, newMsg.id);
}
const memberRoles = (message.member.roles as GuildMemberRoleManager).cache.map((role) => role.id);
if (memberRoles.includes(autoModBypassRole)) return;
this.updateAllowedDomains();
Expand Down

0 comments on commit 77a2e6c

Please sign in to comment.