Skip to content

Commit e3d48e3

Browse files
feat: various qol changes
1 parent 8b24338 commit e3d48e3

15 files changed

+180
-224
lines changed

.env.example

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
POSTGRES_USER=root
2-
POSTGRES_PASSWORD=database_password
3-
POSTGRES_DB=db
4-
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@bot-database:5432/${POSTGRES_DB}?connect_timeout=300
5-
APP_ENV=development
61
DISCORD_TOKEN=""
72
DISCORD_GUILD_ID=""
83
DISCORD_EVENT_CATEGORY_ID=""
94
DISCORD_ARCHIVE_CATEGORY_ID=""
105
DISCORD_PLAYER_ROLE_ID=""
116
DISCORD_MEMBER_ROLE_ID=""
12-
DISCORD_VOICE_CATEGORY_ID=""
13-
DISCORD_DYNAMIC_ROLES_DIVIDER_ID=""
14-
DISCORD_DYNAMIC_ROLES_CATEGORY_ID=""
15-
DISCORD_RETIRED_DYNAMIC_ROLES_CATEGORY_ID=""
16-
DISCORD_MOD_ROLE_ID=""
7+
DISCORD_VOICE_CATEGORY_ID=""

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20.18.0
1+
22.11.0

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@
6868
"@types/supertest": "6.0.2",
6969
"@typescript-eslint/eslint-plugin": "8.10.0",
7070
"@typescript-eslint/parser": "8.10.0",
71-
"eslint": "9.13.0",
72-
"eslint-config-prettier": "9.1.0",
71+
"eslint": "8.57.1",
72+
"eslint-config-prettier": "8.10.0",
7373
"eslint-plugin-prettier": "5.2.1",
7474
"husky": "9.1.6",
7575
"jest": "29.7.0",

pnpm-lock.yaml

+133-137
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.module.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import configuration from './config/configuration';
2020
status: 'online',
2121
activities: [
2222
{
23-
name: 'Pac-Man',
23+
name: 'CS2 on de_cache',
2424
type: ActivityType.Playing
2525
}
2626
]

src/bot/channels/channels.gateway.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class ChannelsGateway {
1717
await this.channelsService.initVoiceChannels();
1818
this.logger.log(`Successfully initialized dynamic voice channels`);
1919
} catch (error) {
20-
this.logger.log(`Failed to initialize dynamic voice channels`);
20+
this.logger.error(`Failed to initialize dynamic voice channels:`, error);
2121
}
2222
}
2323

@@ -27,6 +27,7 @@ export class ChannelsGateway {
2727
await this.channelsService.handleOnVoiceStateUpdate(oldState, newState);
2828
this.logger.log(`Successfully handled voice state update`);
2929
} catch (error) {
30+
console.log('🚀 ~ ChannelsGateway ~ onVoiceStateUpdate ~ error:', error);
3031
this.logger.log(`Failed to handle voice state update`);
3132
}
3233
}

src/bot/channels/channels.service.ts

+20-5
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ export class ChannelsService extends GuildService {
7878
private async getCategoryChannels(): Promise<VoiceChannel[]> {
7979
const guild = await this.getGuild();
8080
const allChannels = Array.from(guild.channels.cache.values());
81-
return allChannels.filter(channel => channel.parentId === this.getVoiceCategoryId()) as VoiceChannel[];
81+
return allChannels.filter(
82+
channel => channel.parentId === this.getVoiceCategoryId() && channel.type === ChannelType.GuildVoice
83+
) as VoiceChannel[];
8284
}
8385

8486
private async getMaxBitrate(): Promise<number> {
@@ -160,7 +162,7 @@ export class ChannelsService extends GuildService {
160162
type: ChannelType.GuildVoice,
161163
parent: this.getVoiceCategoryId(),
162164
position: index,
163-
// topic: `dynamically created voice channel number ${index + 1}`,
165+
// topic: `i love apples`,
164166
bitrate: await this.getMaxBitrate()
165167
});
166168

@@ -178,8 +180,8 @@ export class ChannelsService extends GuildService {
178180
private async updateChannel(channel: VoiceBasedChannel, index: number): Promise<void> {
179181
try {
180182
const updatedChannel = await channel.edit({
181-
name: `voice ${index + 1}`,
182-
topic: `dynamically created voice channel number ${index + 1}`
183+
name: `voice ${index + 1}`
184+
// topic: `i love apples`
183185
});
184186

185187
this.logger.log(`Renamed channel ${channel.name} to ${updatedChannel.name}`);
@@ -195,13 +197,26 @@ export class ChannelsService extends GuildService {
195197

196198
private async deleteChannel(channel: VoiceBasedChannel): Promise<void> {
197199
try {
198-
await channel.delete();
200+
const botMember = channel.guild.members.me;
201+
202+
if (!botMember.permissions.has('ManageChannels')) {
203+
this.logger.error('Bot lacks ManageChannels permission at server level');
204+
return;
205+
}
199206

207+
if (!channel.permissionsFor(botMember).has('ManageChannels')) {
208+
this.logger.error(`Bot lacks ManageChannels permission for channel ${channel.name}`);
209+
return;
210+
}
211+
212+
await channel.delete();
200213
this.logger.log(`Deleted channel ${channel.name}`);
201214
} catch (e) {
202215
const error = e as DiscordAPIError;
203216
if (error.code === 10003) {
204217
this.logger.log('Channel not found');
218+
} else if (error.code === 50013) {
219+
this.logger.error(`Missing permissions to delete channel ${channel.name}`);
205220
} else {
206221
throw error;
207222
}

src/bot/channels/commands/lock-channel.command.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export class LockChannelCommand implements DiscordTransformedCommand<LockChannel
3131
await interaction.reply(await this.channelsService.handleLockChannel(voice, lockChannelDto));
3232
this.logger.log(`Lock command executed successfully`);
3333
} catch (error) {
34-
this.logger.log(`Failed to execute lock command`);
34+
const e = error as Error;
35+
this.logger.error(`Failed to execute lock command: ${e.message}`);
3536
}
3637
}
3738
}

src/bot/events/events.gateway.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ export class EventsGateway {
1616
try {
1717
await this.eventsService.handleOnCreate(event);
1818
this.logger.log(`Event ${event.name} created successfully`);
19-
} catch (error) {
20-
this.logger.log(`Failed to create event ${event.name}`);
19+
} catch (e) {
20+
const error = e as Error;
21+
this.logger.error(`Failed to create event ${event.name}: ${error.message}`);
2122
}
2223
}
2324

@@ -26,8 +27,9 @@ export class EventsGateway {
2627
try {
2728
await this.eventsService.handleOnUpdate(oldEvent, newEvent);
2829
this.logger.log(`Event ${newEvent.name} updated successfully`);
29-
} catch (error) {
30-
this.logger.log(`Failed to update event ${oldEvent.name}`);
30+
} catch (e) {
31+
const error = e as Error;
32+
this.logger.error(`Failed to update event ${oldEvent.name}: ${error.message}`);
3133
}
3234
}
3335

@@ -36,28 +38,31 @@ export class EventsGateway {
3638
try {
3739
await this.eventsService.handleOnDelete(event);
3840
this.logger.log(`Event ${event.name} deleted successfully`);
39-
} catch (error) {
40-
this.logger.log(`Failed to delete event ${event.name}`);
41+
} catch (e) {
42+
const error = e as Error;
43+
this.logger.error(`Failed to delete event ${event.name}: ${error.message}`);
4144
}
4245
}
4346

4447
@On('guildScheduledEventUserAdd')
4548
async onUserAdd(event: GuildScheduledEvent, user: User): Promise<void> {
4649
try {
4750
await this.eventsService.handleOnUserAdd(event, user);
48-
this.logger.log(`${user.username} was added to Event ${event.name} successfully`);
49-
} catch (error) {
50-
this.logger.log(`Failed to add ${user.username} to Event ${event.name}`);
51+
this.logger.log(`User ${user.username} was added to event ${event.name} successfully`);
52+
} catch (e) {
53+
const error = e as Error;
54+
this.logger.error(`Failed to add user ${user.username} to event ${event.name}: ${error.message}`);
5155
}
5256
}
5357

5458
@On('guildScheduledEventUserRemove')
5559
async onUserRemove(event: GuildScheduledEvent, user: User): Promise<void> {
5660
try {
5761
await this.eventsService.handleOnUserRemove(event, user);
58-
this.logger.log(`${user.username} was removed to Event ${event.name} successfully`);
59-
} catch (error) {
60-
this.logger.log(`Failed to remove ${user.username} to Event ${event.name}`);
62+
this.logger.log(`User ${user.username} was removed from event ${event.name} successfully`);
63+
} catch (e) {
64+
const error = e as Error;
65+
this.logger.error(`Failed to remove user ${user.username} from event ${event.name}: ${error.message}`);
6166
}
6267
}
6368
}

src/bot/guild.service.ts

-20
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ export class GuildService {
99
private static memberRoleId: string;
1010
private static playerRoleId: string;
1111
private static voiceCategoryId: string;
12-
private static dynamicRolesDividerId: string;
13-
private static dynamicRolesCategoryId: string;
14-
private static retiredDynamicRolesCategoryId: string;
1512

1613
constructor(
1714
private readonly client: Client,
@@ -23,11 +20,6 @@ export class GuildService {
2320
GuildService.memberRoleId = this.configService.getOrThrow<string>('discord.memberRoleId');
2421
GuildService.playerRoleId = this.configService.getOrThrow<string>('discord.playerRoleId');
2522
GuildService.voiceCategoryId = this.configService.getOrThrow<string>('discord.voiceCategoryId');
26-
GuildService.dynamicRolesDividerId = this.configService.getOrThrow<string>('discord.dynamicRolesDividerId');
27-
GuildService.dynamicRolesCategoryId = this.configService.getOrThrow<string>('discord.dynamicRolesCategoryId');
28-
GuildService.retiredDynamicRolesCategoryId = this.configService.getOrThrow<string>(
29-
'discord.retiredDynamicRolesCategoryId'
30-
);
3123
}
3224

3325
protected async getGuild(): Promise<Guild> {
@@ -61,16 +53,4 @@ export class GuildService {
6153
protected getVoiceCategoryId(): string {
6254
return GuildService.voiceCategoryId;
6355
}
64-
65-
protected getdynamicRolesDividerId(): string {
66-
return GuildService.dynamicRolesDividerId;
67-
}
68-
69-
protected getDynamicRolesCategoryId(): string {
70-
return GuildService.dynamicRolesCategoryId;
71-
}
72-
73-
protected getRetiredDynamicRolesCategoryId(): string {
74-
return GuildService.retiredDynamicRolesCategoryId;
75-
}
7656
}

src/bot/role.guard.ts

-13
This file was deleted.

src/config/configuration.interface.ts

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import IDatabaseConfiguration from './interfaces/database-configuration.interface copy';
21
import IDiscordConfiguration from './interfaces/discord-configuration.interface';
32

43
export default interface IConfiguration {
5-
db: IDatabaseConfiguration;
64
discord: IDiscordConfiguration;
75
}

src/config/configuration.ts

+1-10
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@ export default (): IConfiguration => ({
88
archiveCategoryId: process.env.DISCORD_ARCHIVE_CATEGORY_ID,
99
voiceCategoryId: process.env.DISCORD_VOICE_CATEGORY_ID,
1010
playerRoleId: process.env.DISCORD_PLAYER_ROLE_ID,
11-
memberRoleId: process.env.DISCORD_MEMBER_ROLE_ID,
12-
dynamicRolesDividerId: process.env.DISCORD_DYNAMIC_ROLES_DIVIDER_ID,
13-
dynamicRolesCategoryId: process.env.DISCORD_DYNAMIC_ROLES_CATEGORY_ID,
14-
retiredDynamicRolesCategoryId: process.env.DISCORD_RETIRED_DYNAMIC_ROLES_CATEGORY_ID
15-
},
16-
db: {
17-
user: process.env.POSTGRES_USER,
18-
password: process.env.POSTGRES_PASSWORD,
19-
db: process.env.POSTGRES_DB,
20-
url: process.env.DATABASE_URL
11+
memberRoleId: process.env.DISCORD_MEMBER_ROLE_ID
2112
}
2213
});

src/config/interfaces/database-configuration.interface copy.ts

-6
This file was deleted.

src/config/interfaces/discord-configuration.interface.ts

-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,4 @@ export default interface IDiscordConfiguration {
66
voiceCategoryId: string;
77
memberRoleId: string;
88
playerRoleId: string;
9-
dynamicRolesDividerId: string;
10-
dynamicRolesCategoryId: string;
11-
retiredDynamicRolesCategoryId: string;
129
}

0 commit comments

Comments
 (0)