initial commit
This commit is contained in:
101
events/handle-auto-roles.ts
Normal file
101
events/handle-auto-roles.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import discord, {
|
||||
MessageReaction, PartialMessageReaction,
|
||||
User, PartialUser,
|
||||
} from 'discord.js';
|
||||
import {HydratedDocument} from 'mongoose';
|
||||
|
||||
import {logger} from '../logger';
|
||||
import {config} from '../config';
|
||||
import {Guild, guildModel} from '../models/Guild';
|
||||
import {AutoroleMsg, autoroleMsgModel} from '../models/AutoroleMsg';
|
||||
|
||||
function isMessageReaction(reaction: MessageReaction | PartialMessageReaction): reaction is MessageReaction{
|
||||
return reaction.partial === false;
|
||||
}
|
||||
|
||||
function isUser(user: User | PartialUser): user is User{
|
||||
return user.partial === false;
|
||||
}
|
||||
|
||||
async function handleRole(
|
||||
reaction: MessageReaction | PartialMessageReaction,
|
||||
user: User | PartialUser,
|
||||
action: string
|
||||
): Promise<void>{
|
||||
try{
|
||||
if(config.clientId === user.id) return;
|
||||
if(reaction.partial)
|
||||
reaction = await reaction.fetch();
|
||||
if(user.partial)
|
||||
user = await user.fetch();
|
||||
|
||||
if(!isMessageReaction(reaction))
|
||||
throw Error('type mismatch: reaction.partial');
|
||||
if(!isUser(user))
|
||||
throw Error('type mismatch: user.partial');
|
||||
if(!reaction.emoji)
|
||||
throw Error('reaction.emoji not exist');
|
||||
const dbAutoroleMsg: HydratedDocument<AutoroleMsg> | null =
|
||||
await autoroleMsgModel.findOneAndUpdate(
|
||||
{messageId: reaction.message.id},
|
||||
{$set: {emoji: reaction.emoji.toString()}},
|
||||
{new: true}
|
||||
);
|
||||
if(!dbAutoroleMsg || dbAutoroleMsg.emoji !== reaction.emoji.toString())
|
||||
return;
|
||||
if(!reaction.me)
|
||||
await reaction.react();
|
||||
|
||||
const dbGuild: HydratedDocument<Guild> | null =
|
||||
await guildModel.findById(dbAutoroleMsg.guild._id);
|
||||
if(!dbGuild)
|
||||
throw Error('dbGuild not exist');
|
||||
|
||||
const guild: discord.Guild | null =
|
||||
await reaction.client.guilds.resolve(dbGuild.id);
|
||||
if(!guild)
|
||||
throw Error('guild not exist');
|
||||
|
||||
const role: discord.Role | null =
|
||||
await guild.roles.resolve(dbAutoroleMsg.roleId);
|
||||
if(!role)
|
||||
throw Error('role not exist');
|
||||
|
||||
switch(action){
|
||||
case 'add': await guild.members.addRole({
|
||||
user: user.id, role: role.id
|
||||
}); break;
|
||||
case 'remove': await guild.members.removeRole({
|
||||
user: user.id, role: role.id
|
||||
}); break;
|
||||
}
|
||||
|
||||
logger.log(`${user} has been ${action === 'add'?'given':'removed'} ${role} role.`);
|
||||
if('autoroleLogChannelId' in dbGuild && dbGuild.autoroleLogChannelId){
|
||||
const autoroleChannel: discord.Channel | null =
|
||||
await guild.channels.resolve(dbGuild.autoroleLogChannelId);
|
||||
if(autoroleChannel === null || !autoroleChannel.isTextBased())
|
||||
throw Error('autoroleChannel not exist or autoroleChannel isn\'t text based');
|
||||
await autoroleChannel.send({content:
|
||||
`${user} has been ${action === 'add'?'given':'removed'} ${role} role.`
|
||||
});
|
||||
}
|
||||
}catch(err: unknown){
|
||||
let message;
|
||||
if(err instanceof Error) message = err.message;
|
||||
else message = String(message);
|
||||
logger.error(`While executing "handle-autorole", ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleRoleAdd(
|
||||
reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser
|
||||
): Promise<void>{
|
||||
await handleRole(reaction, user, 'add');
|
||||
}
|
||||
|
||||
export async function handleRoleRemove(
|
||||
reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser
|
||||
): Promise<void>{
|
||||
await handleRole(reaction, user, 'remove');
|
||||
}
|
||||
31
events/handle-commands.ts
Normal file
31
events/handle-commands.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {Interaction} from 'discord.js';
|
||||
|
||||
import {isExtendedClient} from '../classes/extendedclient';
|
||||
import {logger} from '../logger';
|
||||
|
||||
export async function handleCommands(interaction: Interaction): Promise<void>{
|
||||
if(!interaction.isChatInputCommand()) return;
|
||||
if(interaction.commandName === null)
|
||||
throw logger.error('interaction.commandName not exist');
|
||||
if(!isExtendedClient(interaction.client))
|
||||
throw logger.error(`Type Error in function "handleCommands"`);
|
||||
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
if(!command)
|
||||
throw logger.error(`No command matching ${interaction.commandName} was found.`);
|
||||
|
||||
try{
|
||||
if('execute' in command)
|
||||
await command.execute(interaction);
|
||||
else{
|
||||
logger.error(`The command (${interaction.commandName}) is missing a require "execute" function`);
|
||||
return;
|
||||
}
|
||||
}catch(err: unknown){
|
||||
if(interaction.replied || interaction.deferred)
|
||||
await interaction.followUp({content: 'There was an error while executing this command!', ephemeral: true});
|
||||
else
|
||||
await interaction.reply({content: 'There was an error while executing this command!', ephemeral: true});
|
||||
throw logger.error(`While handling "${interaction.commandName}, ${err}"`);
|
||||
}
|
||||
}
|
||||
88
events/handle-giveaway.ts
Normal file
88
events/handle-giveaway.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import discord, {
|
||||
MessageReaction, PartialMessageReaction,
|
||||
User, PartialUser,
|
||||
} from 'discord.js';
|
||||
import {HydratedDocument} from 'mongoose';
|
||||
|
||||
import {logger} from '../logger';
|
||||
import {config} from '../config';
|
||||
import {Guild, guildModel} from '../models/Guild';
|
||||
import {GiveawayMsg, giveawayMsgModel} from '../models/GiveawayMsg';
|
||||
|
||||
function isMessageReaction(reaction: MessageReaction | PartialMessageReaction): reaction is MessageReaction{
|
||||
return reaction.partial === false;
|
||||
}
|
||||
|
||||
function isUser(user: User | PartialUser): user is User{
|
||||
return user.partial === false;
|
||||
}
|
||||
|
||||
export async function handleGiveaway(
|
||||
reaction: MessageReaction | PartialMessageReaction,
|
||||
user: User | PartialUser
|
||||
): Promise<void>{
|
||||
try{
|
||||
// fetch data
|
||||
if(config.clientId === user.id) return;
|
||||
if(reaction.partial){
|
||||
reaction = await reaction.fetch();
|
||||
logger.debug('reaction in handleRole has fetched');
|
||||
}
|
||||
if(user.partial){
|
||||
user = await user.fetch();
|
||||
logger.debug('user in handleRole has fetched');
|
||||
}
|
||||
if(!isMessageReaction(reaction))
|
||||
throw Error('type mismatch: reaction.partial');
|
||||
if(!isUser(user))
|
||||
throw Error('type mismatch: user.partial');
|
||||
if(!reaction.emoji)
|
||||
throw Error('reaction.emoji not exist');
|
||||
if(reaction.emoji.toString() !== config.giveaway.emoji) return;
|
||||
let dbGiveawayMsg: HydratedDocument<GiveawayMsg> | null =
|
||||
await giveawayMsgModel.findOne(
|
||||
{messageId: reaction.message.id}
|
||||
);
|
||||
if(!dbGiveawayMsg) return;
|
||||
if(dbGiveawayMsg.userIds.includes(user.id)){
|
||||
logger.info(`${user} has already in giveaway userIds`);
|
||||
return;
|
||||
}
|
||||
const dbGuild: HydratedDocument<Guild> | null =
|
||||
await guildModel.findById(dbGiveawayMsg.guild._id);
|
||||
if(!dbGuild)
|
||||
throw Error('dbGuild not exist');
|
||||
const guild: discord.Guild = await reaction.client.guilds.resolve(dbGuild.id);
|
||||
if(!guild)
|
||||
throw Error('guild not exist');
|
||||
|
||||
// record
|
||||
dbGiveawayMsg = await giveawayMsgModel.findOneAndUpdate(
|
||||
{messageId: dbGiveawayMsg.messageId},
|
||||
{$push: {userIds: user.id}}, {new: true}
|
||||
);
|
||||
if(!dbGiveawayMsg)
|
||||
throw Error('dbGiveawayMsg not exist');
|
||||
|
||||
// notify
|
||||
logger.log(`${user} has been reacted to giveaway, id: ${dbGiveawayMsg.messageId}.`);
|
||||
if(!dbGuild.giveawayLogChannelId){
|
||||
const author: discord.User | null =
|
||||
await reaction.client.users.fetch(dbGiveawayMsg.authorId);
|
||||
if(!author)
|
||||
throw Error(`author ${author} not exist`);
|
||||
await author.send({content: `user ${user} has reacted to giveaway, id: ${dbGiveawayMsg.messageId}`});
|
||||
}else{
|
||||
const logChannel: discord.Channel | null =
|
||||
await guild.channels.resolve(dbGuild.giveawayLogChannelId);
|
||||
if(!logChannel || !logChannel.isTextBased())
|
||||
throw Error('logChannel not exist or logChannel isn\'t text based');
|
||||
await logChannel.send({content: `user ${user} has reacted to giveaway, id: ${dbGiveawayMsg.messageId}`});
|
||||
}
|
||||
}catch(err: unknown){
|
||||
let message;
|
||||
if(err instanceof Error) message = err.message;
|
||||
else message = String(message);
|
||||
logger.error(`While executing "handleGiveaway", ${message}`);
|
||||
}
|
||||
}
|
||||
40
events/handle-react-image.ts
Normal file
40
events/handle-react-image.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import discord from 'discord.js';
|
||||
import {HydratedDocument} from 'mongoose';
|
||||
|
||||
import {logger} from '../logger';
|
||||
import {config} from '../config';
|
||||
import {reactPreprocess} from '../functions/react-preprocess';
|
||||
import {Alias, aliasModel} from '../models/Alias';
|
||||
import {Guild, guildModel} from '../models/Guild';
|
||||
import {Image, imageModel} from '../models/Image';
|
||||
|
||||
export async function handleReactImage(message: discord.Message): Promise<void>{
|
||||
try{
|
||||
if(!message.guild || !message.guild.id || !message.content) return;
|
||||
const guild: HydratedDocument<Guild> | null =
|
||||
await guildModel.findOne({id: message.guild.id});
|
||||
if(!guild) return; // not in guild
|
||||
const alias: HydratedDocument<Alias> | null =
|
||||
await aliasModel.findOne(
|
||||
{guild: guild, text: reactPreprocess(message.content)}
|
||||
);
|
||||
if(!alias) return; // alias not exist
|
||||
if(!alias.images.length) return; // alias not linked
|
||||
|
||||
const chosenImage: Image =
|
||||
alias.images[Math.floor(Math.random() * alias.images.length)];
|
||||
const image: HydratedDocument<Image> | null =
|
||||
await imageModel.findById(chosenImage._id);
|
||||
if(!image)
|
||||
throw Error('image not exist');
|
||||
|
||||
await message.channel.send({
|
||||
content: `${config.httpServer.external.url}/${image._id}${image.extension}`
|
||||
});
|
||||
}catch(err: unknown){
|
||||
let errMsg;
|
||||
if(err instanceof Error) errMsg = err.message;
|
||||
else errMsg = String(errMsg);
|
||||
logger.error(`While executing "handleReactImage", ${errMsg}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user