StackOverflow

mail@pastecode.io avatar
unknown
typescript
3 years ago
32 kB
1
Indexable
Never
export async function inviteMember(slashCommand: CommandInteraction): Promise<void> {
    try {
        let inviteList: string[];

        const PREMADE_GROUP = PREMADE_GROUPS.get(slashCommand.user.id);

        if(PREMADE_GROUP.members.size === 4) {
            await slashCommand.defer({ ephemeral: true });
            slashCommand.editReply(PARTY_MESSAGES.get('MAX MEMBERS REACHED'));
            return;
        }
        else if(PREMADE_GROUP.invitations.count === 10) {
            await slashCommand.defer({ ephemeral: true });
            slashCommand.editReply(PARTY_MESSAGES.get('MAX INVITES REACHED'));
            return;
        }

        // This checks if the issued command has the invited_members argument, which indicates which members to invite to the group.
        if(slashCommand.options.first().options.first().options) {
            await slashCommand.defer({ ephemeral: true });
            inviteList = (<string>slashCommand.options.first().options.first().options.first().value).split(',');
        }
        else {
            const RETURNED_INFO: MessagePromptReturn = await createPrompt(slashCommand, {
                messages: {
                    initial: PARTY_MESSAGES.get('INVITE USERS'),
                },
                expectedResponseType: 'MESSAGE',
            });

            inviteList = RETURNED_INFO.message.split(',');
        }

        const INVALID_INVITES: InvalidInvite[] = [];
        const VALID_INVITES: String[] = [];

        for (let userIdentifier of inviteList) {
            userIdentifier = userIdentifier.trim();

            if(PREMADE_GROUP.invitations.count === 10) {
                INVALID_INVITES.push({
                    userIdentifier: userIdentifier,
                    reason: 'MAX_INVITES',
                });
                continue;
            }

            if(userIdentifier.match(/<@![0-9]{18}>/g)) {
                for (const MATCH of userIdentifier.match(/<@![0-9]{18}>/g)) {
                    const USER_ID: Snowflake = <Snowflake>MATCH.replace(/\D/g, '');

                    if(!await slashCommand.guild.members.fetch(USER_ID)) {
                        INVALID_INVITES.push({
                            userIdentifier: MATCH,
                            reason: 'INVALID_FORMAT',
                        });
                        continue;
                    }

                    const INVITED_MEMBER = await slashCommand.guild.members.fetch(USER_ID);

                    // DEBUG - UNCOMMENT THIS

                    // if((await slashCommand.guild.members.fetch(USER_ID)).user.id === slashCommand.user.id) {
                    //     INVALID_INVITES.push({
                    //         userIdentifier: INVITED_MEMBER.user.tag,
                    //         reason: 'INVITING_SELF',
                    //     });
                    //     continue;
                    // }

                    // const GUILDMEMBER_STATE = QUEUED_MEMBERS.get(INVITED_MEMBER.user.id);

                    // if(GUILDMEMBER_STATE) {
                    //     if(GUILDMEMBER_STATE.groupID === slashCommand.user.id) {
                    //         INVALID_INVITES.push({
                    //             userIdentifier: INVITED_MEMBER.user.tag,
                    //             reason: 'SAME_GROUP',
                    //         });
                    //         continue;
                    //     }
                    //     INVALID_INVITES.push({
                    //         userIdentifier: INVITED_MEMBER.user.tag,
                    //         reason: GUILDMEMBER_STATE.groupType.toUpperCase(),
                    //     });
                    //     continue;
                    // }

                    if(PREMADE_GROUPS.get(slashCommand.user.id).invitations.members.some(invitedMember => invitedMember === INVITED_MEMBER.user.tag)) {
                        INVALID_INVITES.push({
                            userIdentifier: INVITED_MEMBER.user.tag,
                            reason: 'ALREADY_INVITED',
                        });
                        continue;
                    }

                    let canDM: boolean = true;

                    await (async () => {
                        try {
                            await INVITED_MEMBER.createDM();
                        }
                        catch (error) {
                            canDM = false;
                        }
                    })();

                    console.log(canDM);

                    if(!canDM) {
                        if(!slashCommand.guild.me.permissions.has('MANAGE_CHANNELS')) {
                            INVALID_INVITES.push({
                                userIdentifier: INVITED_MEMBER.user.tag,
                                reason: 'CANT_DM',
                            });
                            continue;
                        }

                        const EXISTING_GUILD_SETTING = await GuildSetting.findOne({
                            attributes: ['categoryChannelID'],
                            where: {
                                guildID: slashCommand.guild.id,
                                scope: 'local',
                            },
                        });

                        let invitationChannel: TextChannel;
                        let invitationsCategory: CategoryChannel;

                        if(EXISTING_GUILD_SETTING) {
                            invitationChannel = await slashCommand.guild.channels.create(`📧${slashCommand.user.username}`, {
                                type: 'text',
                                topic: '🎉 Party Finder Invitation',
                                nsfw: false,
                                parent: <Snowflake>EXISTING_GUILD_SETTING.get('categoryChannelID'),
                                reason: 'Party Finder group invitation',
                                permissionOverwrites:
                                    [
                                        {
                                            id: slashCommand.guild.roles.cache.find(role => role.name === '@everyone'),
                                            deny: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'role',
                                        },
                                        {
                                            id: INVITED_MEMBER.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                        {
                                            id: PF_CLIENT.user.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                    ],
                            });
                        }
                        else {
                            invitationsCategory = await slashCommand.guild.channels.create('🎉 Party Invites', {
                                type: 'category',
                                topic: '🎉 Party Finder Invitations',
                                nsfw: false,
                                reason: 'Party Finder group invitations category',
                                permissionOverwrites:
                                    [
                                        {
                                            id: slashCommand.guild.roles.cache.find(role => role.name === '@everyone'),
                                            deny: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'role',
                                        },
                                        {
                                            id: INVITED_MEMBER.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                        {
                                            id: PF_CLIENT.user.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                    ],
                            });

                            invitationChannel = await slashCommand.guild.channels.create(`📧${slashCommand.user.username}`, {
                                type: 'text',
                                topic: '🎉 Party Finder Invitation',
                                nsfw: false,
                                parent: invitationsCategory.id,
                                reason: 'Party Finder group invitation',
                                permissionOverwrites:
                                    [
                                        {
                                            id: slashCommand.guild.roles.cache.find(role => role.name === '@everyone'),
                                            deny: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'role',
                                        },
                                        {
                                            id: INVITED_MEMBER.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                        {
                                            id: PF_CLIENT.user.id,
                                            allow: [
                                                'VIEW_CHANNEL',
                                            ],
                                            type: 'member',
                                        },
                                    ],
                            });
                        }

                        VALID_INVITES.push(INVITED_MEMBER.user.tag);
                        PREMADE_GROUP.invitations.members.push(INVITED_MEMBER.user.tag);
                        PREMADE_GROUP.invitations.count++;

                        try {
                            (async function() {
                                let sentMessage = await invitationChannel.send(new Invitation(slashCommand.user.username));
                                let userInteraction: MessageComponentInteraction;

                                try {
                                    userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                        filter: () => true,
                                        time: 120000,
                                    });
                                }
                                catch {
                                    sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                    PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                    throw 'INTERACTION_EXPIRED';
                                }

                                if(userInteraction.customID === 'accept') {
                                    // Checks if the invited user has already set up his own elo.
                                    if(await UserProfile.findOne({
                                        where: {
                                            userID: INVITED_MEMBER.user.id,
                                        },
                                    }) === null) {
                                        sentMessage.delete();
                                        sentMessage = await invitationChannel.send(PARTY_MESSAGES.get('ELO CONFIGURATION'));

                                        try {
                                            userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                                filter: () => true,
                                                time: 120000,
                                            });
                                        }
                                        catch {
                                            sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                            PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                            throw 'INTERACTION_EXPIRED';
                                        }

                                        UserProfile.create({
                                            userID: INVITED_MEMBER.user.id,
                                            elo: (<SelectMenuInteraction>userInteraction).values[0],
                                        });
                                    }

                                    await userInteraction.update(PARTY_MESSAGES.get('SELECT ROLES'));

                                    try {
                                        userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                            filter: () => true,
                                            time: 120000,
                                        });
                                    }
                                    catch {
                                        sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                        PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                        throw 'INTERACTION_EXPIRED';
                                    }

                                    QUEUED_MEMBERS.set(INVITED_MEMBER.user.id, {
                                        groupType: 'group',
                                        groupID: PREMADE_GROUPS.findKey((value) => value === PREMADE_GROUP),
                                    });

                                    PREMADE_GROUP.members.set(INVITED_MEMBER.user.id, {
                                        roles: (<SelectMenuInteraction>userInteraction).values,
                                        elo: <ELO>(await UserProfile.findOne({
                                            attributes: ['elo'],
                                            where: {
                                                userID: INVITED_MEMBER.user.id,
                                            },
                                        })).get('elo'),
                                    });

                                    (<TextChannel>await PF_CLIENT.channels.fetch(PREMADE_GROUP.channelID)).createOverwrite(INVITED_MEMBER.id, {
                                        'VIEW_CHANNEL': true,
                                    });

                                    userInteraction.update(new JoinedGroup(PREMADE_GROUP.invitations.URL));
                                    (<TextChannel>(await PF_CLIENT.channels.fetch(PREMADE_GROUP.channelID))).send(new JoinedGroupInfo(INVITED_MEMBER.user.tag));
                                }
                                else {
                                    sentMessage.edit(PARTY_MESSAGES.get('INVITATION DECLINED'));
                                    PREMADE_GROUP.invitations.members.splice(PREMADE_GROUP.invitations.members.indexOf(INVITED_MEMBER.user.tag), 1);
                                }

                                setTimeout(async () => {
                                    await invitationChannel.delete();
                                    if(invitationsCategory) invitationsCategory.delete();
                                }, 15000);

                                PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                            })();
                        }
                        catch(error) {
                            throw error;
                        }

                        continue;
                    }

                    VALID_INVITES.push(INVITED_MEMBER.user.tag);
                    PREMADE_GROUP.invitations.members.push(INVITED_MEMBER.user.tag);
                    PREMADE_GROUP.invitations.count++;

                    try {
                        (async function() {
                            let sentMessage = await INVITED_MEMBER.send(new Invitation(slashCommand.user.username));

                            let userInteraction: MessageComponentInteraction;

                            try {
                                userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                    filter: () => true,
                                    time: 120000,
                                });
                            }
                            catch {
                                sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                throw 'INTERACTION_EXPIRED';
                            }

                            if(userInteraction.customID === 'accept') {
                                // Checks if the invited user has already set up his own elo.
                                if(await UserProfile.findOne({
                                    where: {
                                        userID: INVITED_MEMBER.user.id,
                                    },
                                }) === null) {
                                    sentMessage.delete();
                                    sentMessage = await INVITED_MEMBER.send(PARTY_MESSAGES.get('ELO CONFIGURATION'));

                                    try {
                                        userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                            filter: () => true,
                                            time: 120000,
                                        });
                                    }
                                    catch {
                                        sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                        PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                        throw 'INTERACTION_EXPIRED';
                                    }

                                    UserProfile.create({
                                        userID: INVITED_MEMBER.user.id,
                                        elo: (<SelectMenuInteraction>userInteraction).values[0],
                                    });
                                }

                                await userInteraction.update(PARTY_MESSAGES.get('SELECT ROLES'));

                                try {
                                    userInteraction = await sentMessage.awaitMessageComponentInteraction({
                                        filter: () => true,
                                        time: 120000,
                                    });
                                }
                                catch {
                                    sentMessage.edit(SETUP_MESSAGES.get('EXPIRED'));
                                    PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                    throw 'INTERACTION_EXPIRED';
                                }

                                QUEUED_MEMBERS.set(INVITED_MEMBER.user.id, {
                                    groupType: 'group',
                                    groupID: PREMADE_GROUPS.findKey((value) => value === PREMADE_GROUP),
                                });

                                PREMADE_GROUP.members.set(INVITED_MEMBER.user.id, {
                                    roles: (<SelectMenuInteraction>userInteraction).values,
                                    elo: <ELO>(await UserProfile.findOne({
                                        attributes: ['elo'],
                                        where: {
                                            userID: INVITED_MEMBER.user.id,
                                        },
                                    })).get('elo'),
                                });

                                (<TextChannel>await PF_CLIENT.channels.fetch(PREMADE_GROUP.channelID)).createOverwrite(INVITED_MEMBER.id, {
                                    'VIEW_CHANNEL': true,
                                });

                                userInteraction.update(new JoinedGroup(PREMADE_GROUP.invitations.URL));
                                (<TextChannel>(await PF_CLIENT.channels.fetch(PREMADE_GROUP.channelID))).send(new JoinedGroupInfo(INVITED_MEMBER.user.tag));
                            }
                            else {
                                sentMessage.edit(PARTY_MESSAGES.get('INVITATION DECLINED'));
                                PREMADE_GROUP.invitations.members.splice(PREMADE_GROUP.invitations.members.indexOf(INVITED_MEMBER.user.tag), 1);
                            }

                            PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                        })();
                    }
                    catch(error) {
                        throw error;
                    }
                }
            }
            else {
                if(userIdentifier.slice(0, userIdentifier.indexOf('#')).length === 0 || userIdentifier.slice(userIdentifier.indexOf('#'), userIdentifier.length - 1).length !== 4 || /\D/.test(userIdentifier.slice(userIdentifier.indexOf('#') + 1, userIdentifier.length - 1))) {
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: 'INVALID_FORMAT',
                    });
                    continue;
                }

                if(userIdentifier === slashCommand.user.tag) {
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: 'INVITING_SELF',
                    });
                    continue;
                }

                const USERNAME = userIdentifier.slice(0, userIdentifier.indexOf('#'));

                const GUILDMEMBERS_WITH_SPECIFIED_USERNAME = await slashCommand.guild.members.fetch({
                    query: USERNAME,
                });

                if(!GUILDMEMBERS_WITH_SPECIFIED_USERNAME) {
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: 'NOT_FOUND',
                    });
                    continue;
                }

                const INVITED_MEMBER = GUILDMEMBERS_WITH_SPECIFIED_USERNAME.find(guildMember => guildMember.user.tag === userIdentifier);

                if(!INVITED_MEMBER) {
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: 'NOT_FOUND',
                    });
                    continue;
                }

                const GUILDMEMBER_STATE = QUEUED_MEMBERS.get(INVITED_MEMBER.user.id);

                if(GUILDMEMBER_STATE) {
                    if(GUILDMEMBER_STATE.groupID === slashCommand.user.id) {
                        INVALID_INVITES.push({
                            userIdentifier: userIdentifier,
                            reason: 'SAME_GROUP',
                        });
                        continue;
                    }
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: GUILDMEMBER_STATE.groupType.toUpperCase(),
                    });
                    continue;
                }

                if(PREMADE_GROUPS.get(slashCommand.user.id).invitations.members.some(invitedMember => invitedMember === userIdentifier)) {
                    INVALID_INVITES.push({
                        userIdentifier: userIdentifier,
                        reason: 'ALREADY_INVITED',
                    });
                    continue;
                }

                if(!await INVITED_MEMBER.createDM()) {
                    INVALID_INVITES.push({
                        userIdentifier: INVITED_MEMBER.user.tag,
                        reason: 'CANT_DM',
                    });
                    continue;
                }

                VALID_INVITES.push(userIdentifier);
                PREMADE_GROUP.invitations.members.push(userIdentifier);
                PREMADE_GROUP.invitations.count++;

                try {
                    (async function() {
                        const SENT_INVITATION_MESSAGE = await INVITED_MEMBER.send(new Invitation(slashCommand.user.username));

                        let userInteraction: MessageComponentInteraction;

                        try {
                            userInteraction = await SENT_INVITATION_MESSAGE.awaitMessageComponentInteraction({
                                filter: () => true,
                                time: 120000,
                            });
                        }
                        catch {
                            SENT_INVITATION_MESSAGE.edit(SETUP_MESSAGES.get('EXPIRED'));
                            PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                            throw 'INTERACTION_EXPIRED';
                        }

                        if(userInteraction.customID === 'accept') {
                            // Checks if the invited user has already set up his own elo.
                            if(await UserProfile.findOne({
                                where: {
                                    userID: INVITED_MEMBER.user.id,
                                },
                            }) === null) {
                                SENT_INVITATION_MESSAGE.edit(PARTY_MESSAGES.get('ELO CONFIGURATION'));

                                try {
                                    userInteraction = await SENT_INVITATION_MESSAGE.awaitMessageComponentInteraction({
                                        filter: () => true,
                                        time: 120000,
                                    });
                                }
                                catch {
                                    SENT_INVITATION_MESSAGE.edit(SETUP_MESSAGES.get('EXPIRED'));
                                    PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                    throw 'INTERACTION_EXPIRED';
                                }

                                UserProfile.update({
                                    elo: (<SelectMenuInteraction>userInteraction).values[0],
                                },
                                {
                                    where: {
                                        userID: INVITED_MEMBER.user.id,
                                    },
                                });
                            }

                            await userInteraction.update(PARTY_MESSAGES.get('SELECT ROLES'));

                            try {
                                userInteraction = await SENT_INVITATION_MESSAGE.awaitMessageComponentInteraction({
                                    filter: () => true,
                                    time: 120000,
                                });
                            }
                            catch {
                                SENT_INVITATION_MESSAGE.edit(SETUP_MESSAGES.get('EXPIRED'));
                                PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                                throw 'INTERACTION_EXPIRED';
                            }

                            QUEUED_MEMBERS.set(INVITED_MEMBER.user.id, {
                                groupType: 'group',
                                groupID: PREMADE_GROUPS.findKey((value) => value === PREMADE_GROUP),
                            });

                            PREMADE_GROUP.members.set(INVITED_MEMBER.user.id, {
                                roles: (<SelectMenuInteraction>userInteraction).values,
                                elo: <ELO>(await UserProfile.findOne({
                                    attributes: ['elo'],
                                    where: {
                                        userID: INVITED_MEMBER.user.id,
                                    },
                                })).get('elo'),
                            });

                            userInteraction.update(new JoinedGroup(PREMADE_GROUP.invitations.URL));
                            (<TextChannel>(await PF_CLIENT.channels.fetch(PREMADE_GROUP.channelID))).send(new JoinedGroupInfo(INVITED_MEMBER.user.tag));
                        // userInteraction.update(new MemberKicked(INVITED_MEMBER.user.tag));
                        // PREMADE_GROUP.members.delete(INVITED_MEMBER.user.id);
                        // QUEUED_MEMBERS.delete(INVITED_MEMBER.user.id);
                        }
                        else {
                            SENT_INVITATION_MESSAGE.edit(PARTY_MESSAGES.get('INVITATION DECLINED'));
                            PREMADE_GROUP.invitations.members.splice(PREMADE_GROUP.invitations.members.indexOf(INVITED_MEMBER.user.tag), 1);
                        }

                        PREMADE_GROUP.invitations.members = PREMADE_GROUP.invitations.members.filter((invitedMember) => invitedMember !== userIdentifier);
                    })();
                }
                catch(error) {
                    throw error;
                }
            }
        }

        slashCommand.editReply(new InvitationReply(VALID_INVITES, INVALID_INVITES));

    }
    catch(error) {
        if(error === 'INTERACTION_EXPIRED') return;
        console.log('[ERROR] INVITE SLASH COMMAND');
        console.log(error);
        slashCommand.followUp(SETUP_MESSAGES.get('SOMETHING WENT WRONG'));
    }
}