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{ 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 | 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 | 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}`); } }