aboutsummaryrefslogtreecommitdiff
path: root/src/lib/models/instance/Guild.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/models/instance/Guild.ts')
-rw-r--r--src/lib/models/instance/Guild.ts414
1 files changed, 414 insertions, 0 deletions
diff --git a/src/lib/models/instance/Guild.ts b/src/lib/models/instance/Guild.ts
new file mode 100644
index 0000000..11469d2
--- /dev/null
+++ b/src/lib/models/instance/Guild.ts
@@ -0,0 +1,414 @@
+import { ChannelType, type Snowflake } from 'discord.js';
+import { type Sequelize } from 'sequelize';
+import { BadWordDetails } from '../../common/AutoMod.js';
+import { type BushClient } from '../../extensions/discord-akairo/BushClient.js';
+import { BaseModel } from '../BaseModel.js';
+const { DataTypes } = (await import('sequelize')).default;
+
+export interface GuildModel {
+ id: Snowflake;
+ prefix: string;
+ autoPublishChannels: Snowflake[];
+ blacklistedChannels: Snowflake[];
+ blacklistedUsers: Snowflake[];
+ welcomeChannel: Snowflake;
+ muteRole: Snowflake;
+ punishmentEnding: string;
+ disabledCommands: string[];
+ lockdownChannels: Snowflake[];
+ autoModPhases: BadWordDetails[];
+ enabledFeatures: GuildFeatures[];
+ joinRoles: Snowflake[];
+ logChannels: LogChannelDB;
+ bypassChannelBlacklist: Snowflake[];
+ noXpChannels: Snowflake[];
+ levelRoles: { [level: number]: Snowflake };
+ levelUpChannel: Snowflake;
+}
+
+export interface GuildModelCreationAttributes {
+ id: Snowflake;
+ prefix?: string;
+ autoPublishChannels?: Snowflake[];
+ blacklistedChannels?: Snowflake[];
+ blacklistedUsers?: Snowflake[];
+ welcomeChannel?: Snowflake;
+ muteRole?: Snowflake;
+ punishmentEnding?: string;
+ disabledCommands?: string[];
+ lockdownChannels?: Snowflake[];
+ autoModPhases?: BadWordDetails[];
+ enabledFeatures?: GuildFeatures[];
+ joinRoles?: Snowflake[];
+ logChannels?: LogChannelDB;
+ bypassChannelBlacklist?: Snowflake[];
+ noXpChannels?: Snowflake[];
+ levelRoles?: { [level: number]: Snowflake };
+ levelUpChannel?: Snowflake;
+}
+
+export class Guild extends BaseModel<GuildModel, GuildModelCreationAttributes> implements GuildModel {
+ /**
+ * The ID of the guild
+ */
+ public declare id: Snowflake;
+
+ /**
+ * The bot's prefix for the guild
+ */
+ public declare prefix: string;
+
+ /**
+ * Channels that will have their messages automatically published
+ */
+ public declare autoPublishChannels: Snowflake[];
+
+ /**
+ * Channels where the bot won't respond in.
+ */
+ public declare blacklistedChannels: Snowflake[];
+
+ /**
+ * Users that the bot ignores in this guild
+ */
+ public declare blacklistedUsers: Snowflake[];
+
+ /**
+ * The channels where the welcome messages are sent
+ */
+ public declare welcomeChannel: Snowflake;
+
+ /**
+ * The role given out when muting someone
+ */
+ public declare muteRole: Snowflake;
+
+ /**
+ * The message that gets sent after someone gets a punishment dm
+ */
+ public declare punishmentEnding: string;
+
+ /**
+ * Guild specific disabled commands
+ */
+ public declare disabledCommands: string[];
+
+ /**
+ * Channels that should get locked down when the lockdown command gets used.
+ */
+ public declare lockdownChannels: Snowflake[];
+
+ /**
+ * Custom automod phases
+ */
+ public declare autoModPhases: BadWordDetails[];
+
+ /**
+ * The features enabled in a guild
+ */
+ public declare enabledFeatures: GuildFeatures[];
+
+ /**
+ * The roles to assign to a user if they are not assigned sticky roles
+ */
+ public declare joinRoles: Snowflake[];
+
+ /**
+ * The channels where logging messages will be sent.
+ */
+ public declare logChannels: LogChannelDB;
+
+ /**
+ * These users will be able to use commands in channels blacklisted
+ */
+ public declare bypassChannelBlacklist: Snowflake[];
+
+ /**
+ * Channels where users will not earn xp for leveling.
+ */
+ public declare noXpChannels: Snowflake[];
+
+ /**
+ * What roles get given to users when they reach certain levels.
+ */
+ public declare levelRoles: { [level: number]: Snowflake };
+
+ /**
+ * The channel to send level up messages in instead of last channel.
+ */
+ public declare levelUpChannel: Snowflake;
+
+ /**
+ * Initializes the model.
+ * @param sequelize The sequelize instance.
+ */
+ public static initModel(sequelize: Sequelize, client: BushClient): void {
+ Guild.init(
+ {
+ id: { type: DataTypes.STRING, primaryKey: true },
+ prefix: { type: DataTypes.TEXT, allowNull: false, defaultValue: client.config.prefix },
+ autoPublishChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedUsers: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ welcomeChannel: { type: DataTypes.STRING, allowNull: true },
+ muteRole: { type: DataTypes.STRING, allowNull: true },
+ punishmentEnding: { type: DataTypes.TEXT, allowNull: true },
+ disabledCommands: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ lockdownChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ autoModPhases: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ enabledFeatures: {
+ type: DataTypes.JSONB,
+ allowNull: false,
+ defaultValue: Object.keys(guildFeaturesObj).filter(
+ (key) => guildFeaturesObj[key as keyof typeof guildFeaturesObj].default
+ )
+ },
+ joinRoles: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ logChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: {} },
+ bypassChannelBlacklist: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ noXpChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ levelRoles: { type: DataTypes.JSONB, allowNull: false, defaultValue: {} },
+ levelUpChannel: { type: DataTypes.STRING, allowNull: true }
+ },
+ { sequelize }
+ );
+ }
+}
+
+export type BaseGuildSetting = 'channel' | 'role' | 'user';
+export type GuildSettingType = 'string' | 'custom' | BaseGuildSetting | `${BaseGuildSetting}-array`;
+
+export interface GuildSetting {
+ name: string;
+ description: string;
+ type: GuildSettingType;
+ subType: ChannelType[] | undefined;
+ configurable: boolean;
+}
+const asGuildSetting = <T>(et: { [K in keyof T]: GuildSetting }) => et;
+
+export const guildSettingsObj = asGuildSetting({
+ prefix: {
+ name: 'Prefix',
+ description: 'The phrase required to trigger text commands in this server.',
+ type: 'string',
+ subType: undefined,
+ configurable: true
+ },
+ autoPublishChannels: {
+ name: 'Auto Publish Channels',
+ description: 'Channels were every message is automatically published.',
+ type: 'channel-array',
+ subType: [ChannelType.GuildNews],
+ configurable: true
+ },
+ welcomeChannel: {
+ name: 'Welcome Channel',
+ description: 'The channel where the bot will send join and leave message.',
+ type: 'channel',
+ subType: [
+ ChannelType.GuildText,
+ ChannelType.GuildNews,
+ ChannelType.GuildNewsThread,
+ ChannelType.GuildPublicThread,
+ ChannelType.GuildPrivateThread
+ ],
+ configurable: true
+ },
+ muteRole: {
+ name: 'Mute Role',
+ description: 'The role assigned when muting someone.',
+ type: 'role',
+ subType: undefined,
+ configurable: true
+ },
+ punishmentEnding: {
+ name: 'Punishment Ending',
+ description: 'The message after punishment information to a user in a dm.',
+ type: 'string',
+ subType: undefined,
+ configurable: true
+ },
+ lockdownChannels: {
+ name: 'Lockdown Channels',
+ description: 'Channels that are locked down when a mass lockdown is specified.',
+ type: 'channel-array',
+ subType: [ChannelType.GuildText],
+ configurable: true
+ },
+ joinRoles: {
+ name: 'Join Roles',
+ description: 'Roles assigned to users on join who do not have sticky role information.',
+ type: 'role-array',
+ subType: undefined,
+ configurable: true
+ },
+ bypassChannelBlacklist: {
+ name: 'Bypass Channel Blacklist',
+ description: 'These users will be able to use commands in channels blacklisted.',
+ type: 'user-array',
+ subType: undefined,
+ configurable: true
+ },
+ logChannels: {
+ name: 'Log Channels',
+ description: 'The channel were logs are sent.',
+ type: 'custom',
+ subType: [ChannelType.GuildText],
+ configurable: false
+ },
+ autoModPhases: {
+ name: 'Automod Phases',
+ description: 'Custom phrases to be detected by automod.',
+ type: 'custom',
+ subType: undefined,
+ configurable: false
+ },
+ noXpChannels: {
+ name: 'No Xp Channels',
+ description: 'Channels where users will not earn xp for leveling.',
+ type: 'channel-array',
+ subType: [
+ ChannelType.GuildText,
+ ChannelType.GuildNews,
+ ChannelType.GuildNewsThread,
+ ChannelType.GuildPublicThread,
+ ChannelType.GuildPrivateThread
+ ],
+ configurable: true
+ },
+ levelRoles: {
+ name: 'Level Roles',
+ description: 'What roles get given to users when they reach certain levels.',
+ type: 'custom',
+ subType: undefined,
+ configurable: false
+ },
+ levelUpChannel: {
+ name: 'Level Up Channel',
+ description: 'The channel to send level up messages in instead of last channel.',
+ type: 'channel',
+ subType: [
+ ChannelType.GuildText,
+ ChannelType.GuildNews,
+ ChannelType.GuildNewsThread,
+ ChannelType.GuildPublicThread,
+ ChannelType.GuildPrivateThread
+ ],
+ configurable: true
+ }
+});
+
+export type GuildSettings = keyof typeof guildSettingsObj;
+export const settingsArr = Object.keys(guildSettingsObj).filter(
+ (s) => guildSettingsObj[s as GuildSettings].configurable
+) as GuildSettings[];
+
+interface GuildFeature {
+ name: string;
+ description: string;
+ default: boolean;
+}
+const asGuildFeature = <T>(gf: { [K in keyof T]: GuildFeature }) => gf;
+
+export const guildFeaturesObj = asGuildFeature({
+ automod: {
+ name: 'Automod',
+ description: 'Deletes offensive content as well as phishing links.',
+ default: false
+ },
+ excludeDefaultAutomod: {
+ name: 'Exclude Default Automod',
+ description: 'Opt out of using the default automod options.',
+ default: false
+ },
+ excludeAutomodScamLinks: {
+ name: 'Exclude Automod Scam Links',
+ description: 'Opt out of having automod delete scam links.',
+ default: false
+ },
+ delScamMentions: {
+ name: 'Delete Scam Mentions',
+ description: 'Deletes messages with @everyone and @here mentions that have common scam phrases.',
+ default: false
+ },
+ autoPublish: {
+ name: 'Auto Publish',
+ description: 'Publishes messages in configured announcement channels.',
+ default: false
+ },
+ // todo implement a better auto thread system
+ // autoThread: {
+ // name: 'Auto Thread',
+ // description: 'Creates a new thread for messages in configured channels.',
+ // default: false
+ // },
+ blacklistedFile: {
+ name: 'Blacklisted File',
+ description: 'Automatically deletes malicious files.',
+ default: false
+ },
+ boosterMessageReact: {
+ name: 'Booster Message React',
+ description: 'Reacts to booster messages with the boost emoji.',
+ default: false
+ },
+ leveling: {
+ name: 'Leveling',
+ description: "Tracks users' messages and assigns them xp.",
+ default: false
+ },
+ stickyRoles: {
+ name: 'Sticky Roles',
+ description: 'Restores past roles to a user when they rejoin.',
+ default: false
+ },
+ reporting: {
+ name: 'Reporting',
+ description: 'Allow users to make reports.',
+ default: false
+ },
+ modsCanPunishMods: {
+ name: 'Mods Can Punish Mods',
+ description: 'Allow moderators to punish other moderators.',
+ default: false
+ },
+ sendLevelUpMessages: {
+ name: 'Send Level Up Messages',
+ description: 'Send a message when a user levels up.',
+ default: true
+ },
+ logManualPunishments: {
+ name: 'Log Manual Punishments',
+ description: "Adds manual punishment to the user's modlogs and the logging channels.",
+ default: true
+ }
+});
+
+export const guildLogsObj = {
+ automod: {
+ description: 'Sends a message in this channel every time automod is activated.',
+ configurable: true
+ },
+ moderation: {
+ description: 'Sends a message in this channel every time a moderation action is performed.',
+ configurable: true
+ },
+ report: {
+ description: 'Logs user reports.',
+ configurable: true
+ },
+ error: {
+ description: 'Logs errors that occur with the bot.',
+ configurable: true
+ }
+};
+
+export type GuildLogType = keyof typeof guildLogsObj;
+export const guildLogsArr = Object.keys(guildLogsObj).filter(
+ (s) => guildLogsObj[s as GuildLogType].configurable
+) as GuildLogType[];
+type LogChannelDB = { [x in keyof typeof guildLogsObj]?: Snowflake };
+
+export type GuildFeatures = keyof typeof guildFeaturesObj;
+export const guildFeaturesArr: GuildFeatures[] = Object.keys(guildFeaturesObj) as GuildFeatures[];