Skip to content

Commit

Permalink
added queue activity channel (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Siniecki committed Nov 28, 2023
1 parent 30878d6 commit 8c146f6
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 46 deletions.
41 changes: 7 additions & 34 deletions src/commands/queue/join.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { ApplicationCommandOptionType, Message } from "discord.js";
import {ApplicationCommandOptionType, Message} from "discord.js";
import { Command } from "../../../typings";
import {GuildModel} from "../../models/guilds";
import {UserModel} from "../../models/users";
import { SessionModel } from "../../models/sessions";
import { Queue } from "../../models/queues";
import { ArraySubDocumentType } from "@typegoose/typegoose";
import { Bot } from "../../bot";
import {manageJoinQueue} from "../../utils/general";


const command: Command = {
name: "join",
Expand Down Expand Up @@ -77,44 +75,19 @@ const command: Command = {
intent: interaction.options.getString("intent") ?? undefined,
});


try {
const roles = await g.roles.fetch();
const waiting_role = roles.find(x => x.name.toLowerCase() === queueData.name.toLowerCase() + "-waiting");

const member = g.members.resolve(user);
if (waiting_role && member && !member.roles.cache.has(waiting_role.id)) {
member.roles.add(waiting_role);
}
// await member?.voice.disconnect();
await manageJoinQueue(g, guildData, user, queueData);
} catch (error) {
console.log(error);
console.log(error)
}

await client.utils.embeds.SimpleEmbed(interaction, { title: "Coaching System", text: queueData.getJoinMessage(user.id), empheral: true });

// await client.utils.embeds.SimpleEmbed(interaction, "TODO", `Command \`${path.relative(process.cwd(), __filename)}\` is not Implemented Yet.`);

await informCoaches(client, queueData);

},
};

/**
* sends a private message to all coaches having an active session on the given queue
* @param queueData queue the user joined in
*/
async function informCoaches(client: Bot, queueData: ArraySubDocumentType<Queue>) {
const activeSessions = await SessionModel.find({ queue: queueData.id, active: true }).exec();
try {
for(const session of activeSessions) {
const user = await client.users.fetch(session.user);
const dmChannel = await user.createDM();
await client.utils.embeds.SimpleEmbed(dmChannel, { title: "Coaching System", text: `${user.displayName} has joined the queue: ${queueData.name}`, empheral: true });
}
} catch (error) {
console.log(error)
}
}


/**
* Exporting the Command using CommonJS
Expand Down
94 changes: 94 additions & 0 deletions src/commands/setqueueactivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
ApplicationCommandOptionType,
ChannelType,
GuildChannel,
Message,
TextChannel as DiscordTextChannel,
} from "discord.js";
import { Command } from "../../typings";
import { GuildModel } from "../models/guilds";
import { FilterOutFunctionKeys } from "@typegoose/typegoose/lib/types";
import {TextChannel} from "../models/text_channels";

const command: Command = {
name: "setqueueinfo",
description: "the given text chnnel will inform tutors with active sessions about queue activities",
aliases: ["sqi"],
usage: "[channel resolvable]",
cooldown: 5,
category: "Coaching",
guildOnly: true,
defaultPermission: false,
options: [{
name: "queueinfochannel",
description: "the text channels name",
type: ApplicationCommandOptionType.Channel,
required: true,
},
{
name: "queue",
description: "name of the queue",
type: ApplicationCommandOptionType.String,
required: true,
}
],
execute: async (client, interaction, args) => {
if (!interaction) {
return;
}
if (interaction instanceof Message) {
await client.utils.embeds.SimpleEmbed(interaction, { title: "Slash Only Command", text: "This Command is Slash only but you Called it with The Prefix. use the slash Command instead.", deleteinterval: 3000 });
if (interaction.deletable) await interaction.delete();
return;
}
const member = client.utils.general.getMember(interaction);
if (!member || member.id !== client.config.get("ownerID") as string) {
await interaction?.reply("You do not have permission to execute this command.");
return;
}


// Find channel
const channel = interaction.options.getChannel("queueinfochannel", true);
if (!channel || !(channel instanceof GuildChannel)) {
return await interaction?.reply("Channel could not be found.");
}
if (!(channel instanceof DiscordTextChannel)) {
return await interaction?.reply("QueueInfoChannel channel must be a text Channel.");
}

const g = interaction!.guild!;
const guildData = (await GuildModel.findById(g.id));

if (!guildData) {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Coaching System", text: "Guild Data Could not be found.", empheral: true });
}

const queue = interaction.options.getString("queue", true);
const queueData = guildData.queues.find(x => x.name === queue);

const updated = await GuildModel.updateOne(
{ _id: g.id },
{
$push: {
"text_channels": {
_id: channel.id,
managed: true,
channel_type : ChannelType.GroupDM,
queue: queueData,
listen_for_commands: true,
category: channel.parent?.name
} as FilterOutFunctionKeys<TextChannel>,
},
},
{ upsert: true, setDefaultsOnInsert: true },
);
console.log(updated);
interaction!.reply({ content: `Success. ${channel.name} set to queue info channel for queue: ${queue}` });
},
};

/**
* Exporting the Command using CommonJS
*/
module.exports = command;
12 changes: 5 additions & 7 deletions src/events/VoiceStateUpdateEvent.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { ExecuteEvent } from "../../typings";
import { Collection, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
import {Collection, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js";
import { GuildModel } from "../models/guilds";
import { QueueEntry } from "../models/queue_entry";
export const name = "voiceStateUpdate";
import { RoomModel } from "../models/rooms";
import { Event as EVT, eventType } from "../models/events";
import {manageJoinQueue} from "../utils/general";

export const execute: ExecuteEvent<"voiceStateUpdate"> = async (client, oldState, newState) => {
const oldUserChannel = oldState.channel;
Expand Down Expand Up @@ -77,13 +78,10 @@ export const execute: ExecuteEvent<"voiceStateUpdate"> = async (client, oldState
importance: 1,
});

const roles = await guild.roles.fetch();
const waiting_role = roles.find(x => x.name.toLowerCase() === queue.name.toLowerCase() + "-waiting");

const member = newState.member!;
if (waiting_role && member && !member.roles.cache.has(waiting_role.id)) {
member.roles.add(waiting_role);
}
if (guildData != null && newState.member!.user)
await manageJoinQueue(guild, guildData, newState.member!.user, queue)

} catch (error) {
try {
await client.utils.embeds.SimpleEmbed(await newState.member!.createDM(), { title: "Queue System", text: `An error occurred: ${error}` });
Expand Down
10 changes: 9 additions & 1 deletion src/models/text_channels.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChannelType, TextChannelType } from "discord.js";
import { getModelForClass, prop } from "@typegoose/typegoose";
import {getModelForClass, prop, Ref} from "@typegoose/typegoose";
import {Queue} from "./queues";

/**
* Database Representation of a Discord Channel
Expand All @@ -25,6 +26,7 @@ export interface Channel {
* The Channel owner
*/
owner?: string,

}

export class TextChannel implements Channel {
Expand Down Expand Up @@ -53,6 +55,12 @@ export class TextChannel implements Channel {
*/
@prop({ default: false })
rage_channel?: boolean;

/**
* The queue to show activities of
*/
@prop({ ref: () => Queue })
queue?: Ref<Queue>;
}

export const TextChannelModel = getModelForClass(TextChannel, {
Expand Down
35 changes: 31 additions & 4 deletions src/utils/general.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { ConfigHandler } from "./../handlers/configHandler";
import { DBRole, InternalRoles, RoleScopes } from "./../models/bot_roles";
import ChannelType, {
CommandInteraction,
CommandInteraction, Guild as DiscrodGuild,
Guild,
GuildMember,
GuildMemberResolvable,
GuildResolvable,
Interaction,
Message,
RoleResolvable,
RoleResolvable, TextChannel,
User,
UserResolvable
} from "discord.js";
import moment from "moment";
import { Command, StringReplacements } from "../../typings";
import { GuildModel } from "../models/guilds";
import { Guild as GuildDB, GuildModel } from "../models/guilds";
import { Bot } from "../bot";
import { UserModel } from "../models/users";
import * as cryptojs from "crypto-js";
import { DocumentType } from "@typegoose/typegoose";
import {ArraySubDocumentType, DocumentType} from "@typegoose/typegoose";
import {Queue} from "../models/queues";

/**
* Checks if a given Variable is an array[] with at least a length of one or not
Expand Down Expand Up @@ -427,4 +428,30 @@ export async function removeRoleFromUser(g: Guild, user: User, roleName: string)
} else {
console.error(`Could not remove role: ${roleName} from ${user.username} on guild: ${g.name}`)
}
}

/**
* assigns the waiting role and informs tutors that user has joined
* @param g
* @param guildData
* @param user
* @param queueData
*/
export async function manageJoinQueue(g: DiscrodGuild, guildData: DocumentType<GuildDB>, user: User, queueData: ArraySubDocumentType<Queue>) {
const roles = await g.roles.fetch();
const waiting_role = roles.find(role => role.name.toLowerCase() === queueData.name.toLowerCase() + "-waiting");

const member = g.members.resolve(user);
if (waiting_role && member && !member.roles.cache.has(waiting_role.id)) {
member.roles.add(waiting_role);
}
const channel = guildData.text_channels.find(channel => channel.queue?._id.toString() === queueData.id)
const activeSessionRole = guildData.guild_settings.roles?.find(role => role.internal_name === InternalRoles.ACTIVE_SESSION)

if (channel && activeSessionRole) {
const discordChannel = await g.channels.fetch(channel.id) as TextChannel
await discordChannel.send(`<@&${activeSessionRole?.role_id}> ${user.displayName} joined the queue`)
}

// await member?.voice.disconnect();
}

0 comments on commit 8c146f6

Please sign in to comment.