89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
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}`);
|
|
}
|
|
}
|