-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.gateway.ts
More file actions
89 lines (81 loc) · 3.48 KB
/
Copy pathbot.gateway.ts
File metadata and controls
89 lines (81 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { BotService } from '@bot/bot.service';
import { PlayerButtonActionId } from '@bot/constants/player.constants';
import { PlayerService } from '@bot/services/player/player.service';
import { ConfigService } from '@config/config.service';
import { MemberDocument } from '@database/schemas/member.schema';
import { InjectDiscordClient, InteractionEvent, On, Once } from '@discord-nestjs/core';
import { Injectable, Logger } from '@nestjs/common';
import { IMemberVoiceState } from '@shared/interfaces/memberVoiceState.interface';
import { ActivityType, ButtonInteraction, Client, MessageFlags, VoiceState } from 'discord.js';
import { FRIENDLY_ERROR_MESSAGES } from './constants/messages.constant';
import { getNowPlayingButtons } from './utils/player.utils';
@Injectable()
export class BotGateway {
private readonly logger = new Logger(BotGateway.name);
constructor(
@InjectDiscordClient() private readonly client: Client,
private readonly _botService: BotService,
private readonly _playerService: PlayerService,
private readonly _configService: ConfigService,
) {}
@Once('ready')
onReady(): void {
this.logger.log(`Bot ${this.client.user.tag} was started!`);
this.initPresence();
}
@On('voiceStateUpdate')
async onVoiceStateUpdate(lastState: VoiceState, newState: VoiceState): Promise<MemberDocument> {
if (lastState.channelId === newState.channelId) return; // Ignore if the user is in the same channel
if (newState.member.user.bot) return; // Ignore if the user is a bot
this.logger.log(`Handling VoiceStateUpdate for ${newState.member.user.username}`);
const { channelId, guild, member } = newState;
const memberVoiceState: IMemberVoiceState = {
userId: member.user.id,
username: member.user.username,
discriminator: member.user.discriminator,
guildId: guild.id,
guildName: guild.name,
currentChannelId: channelId,
};
return this._botService.updateMemberVoiceState({ memberVoiceState });
}
@On('interactionCreate')
async onButtonInteractionCreate(@InteractionEvent() interaction: ButtonInteraction) {
if (!interaction.isButton()) return;
const { customId, guildId, channel } = interaction;
const guildQueue = this._playerService.getGuildQueue(guildId);
if (!guildQueue) {
await this.handleInvalidButtonInteraction(interaction);
return;
}
switch (customId) {
case PlayerButtonActionId.PLAY_PAUSE: {
this._playerService.togglePause({ guildId });
await interaction.deferUpdate();
return;
}
case PlayerButtonActionId.SKIP: {
await channel.sendTyping();
this._playerService.skip({ guildId });
await interaction.deferUpdate();
return;
}
}
}
private async disableButtonInteraction(interaction: ButtonInteraction): Promise<void> {
const { message } = interaction;
const disabledButtons = getNowPlayingButtons({ disabled: true });
await message.edit({ components: [disabledButtons] });
}
private async handleInvalidButtonInteraction(interaction: ButtonInteraction): Promise<void> {
await this.disableButtonInteraction(interaction);
await interaction.reply({ content: FRIENDLY_ERROR_MESSAGES.NO_ACTIVE_QUEUE, flags: MessageFlags.Ephemeral });
}
private async initPresence(): Promise<void> {
const version = this._configService.getAppVersion();
this.client.user.setPresence({
status: 'dnd',
activities: [{ name: `v${version}-RELEASE`, type: ActivityType.Custom }],
});
}
}