Add play track command

This commit is contained in:
Manuel Ruwe 2022-12-16 22:14:56 +01:00
parent 73f2f0eb5f
commit ca10c0fd6d
7 changed files with 94 additions and 17 deletions

View File

@ -35,6 +35,7 @@
"discord.js": "^14.7.1", "discord.js": "^14.7.1",
"jellyfin-apiclient": "^1.10.0", "jellyfin-apiclient": "^1.10.0",
"joi": "^17.7.0", "joi": "^17.7.0",
"libsodium-wrappers": "^0.7.10",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rxjs": "^7.2.0" "rxjs": "^7.2.0"

View File

@ -16,6 +16,7 @@ export class DiscordConfigService implements DiscordOptionsFactory {
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent, GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildIntegrations, GatewayIntentBits.GuildIntegrations,
GatewayIntentBits.GuildVoiceStates,
], ],
}, },
}; };

View File

@ -1,10 +1,18 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { OnModuleDestroy } from '@nestjs/common/interfaces/hooks';
import { DiscordConfigService } from './discord.config.service'; import { DiscordConfigService } from './discord.config.service';
import { DiscordVoiceService } from './discord.voice.service';
@Module({ @Module({
imports: [], imports: [],
controllers: [], controllers: [],
providers: [DiscordConfigService], providers: [DiscordConfigService, DiscordVoiceService],
exports: [DiscordConfigService], exports: [DiscordConfigService],
}) })
export class DiscordClientModule {} export class DiscordClientModule implements OnModuleDestroy {
constructor(private readonly discordVoiceService: DiscordVoiceService) {}
onModuleDestroy() {
this.discordVoiceService.disconnectGracefully();
}
}

View File

@ -1,14 +1,20 @@
import { Injectable } from "@nestjs/common"; import { getVoiceConnections } from '@discordjs/voice';
import { VoiceChannel } from "discord.js"; import { Injectable } from '@nestjs/common';
import { Logger } from '@nestjs/common/services';
@Injectable() @Injectable()
export class DiscordVoiceService { export class DiscordVoiceService {
private readonly logger = new Logger(DiscordVoiceService.name);
summonClient(voiceChannel: VoiceChannel) { disconnectGracefully() {
// voiceChannel.join(''); const connections = getVoiceConnections();
} this.logger.debug(
`Disonnecting gracefully from ${
startPlayback() { Object.keys(connections).length
} connections`,
);
connections.forEach((connection) => {
connection.destroy();
});
} }
} }

View File

@ -1,23 +1,61 @@
import { TransformPipe } from '@discord-nestjs/common'; import { TransformPipe } from '@discord-nestjs/common';
import { import {
Command, Command,
DiscordTransformedCommand, DiscordTransformedCommand,
Payload,
TransformedCommandExecutionContext, TransformedCommandExecutionContext,
UsePipes, UsePipes,
} from '@discord-nestjs/core'; } from '@discord-nestjs/core';
import { InteractionReplyOptions } from 'discord.js'; import { InteractionReplyOptions, MessagePayload } from 'discord.js';
import { Injectable } from '@nestjs/common';
import { TrackRequestDto } from '../models/track-request.dto';
import {
createAudioPlayer,
createAudioResource,
getVoiceConnection,
} from '@discordjs/voice';
import { Logger } from '@nestjs/common/services';
@Command({ @Command({
name: 'play', name: 'play',
description: 'Immediately play a track', description: 'Immediately play a track',
}) })
@Injectable()
@UsePipes(TransformPipe) @UsePipes(TransformPipe)
export class PlayCommand implements DiscordTransformedCommand<unknown> { export class PlayCommand implements DiscordTransformedCommand<TrackRequestDto> {
private readonly logger = new Logger(PlayCommand.name);
handler( handler(
dto: unknown, @Payload() dto: TrackRequestDto,
executionContext: TransformedCommandExecutionContext<any>, executionContext: TransformedCommandExecutionContext<any>,
): InteractionReplyOptions | string { ):
return 'nice'; | string
| void
| MessagePayload
| InteractionReplyOptions
| Promise<string | void | MessagePayload | InteractionReplyOptions> {
const player = createAudioPlayer();
this.logger.debug('bruh');
player.on('error', (error) => {
this.logger.error(error);
});
player.on('debug', (error) => {
this.logger.debug(error);
});
const resource = createAudioResource(dto.search);
const connection = getVoiceConnection(executionContext.interaction.guildId);
connection.subscribe(player);
player.play(resource);
player.unpause();
return 'Playing Audio...';
} }
} }

View File

@ -0,0 +1,6 @@
import { Param } from '@discord-nestjs/core';
export class TrackRequestDto {
@Param({ required: true, description: 'Track name to search' })
search: string;
}

View File

@ -4475,6 +4475,7 @@ __metadata:
jellyfin-apiclient: ^1.10.0 jellyfin-apiclient: ^1.10.0
jest: 28.1.3 jest: 28.1.3
joi: ^17.7.0 joi: ^17.7.0
libsodium-wrappers: ^0.7.10
prettier: ^2.3.2 prettier: ^2.3.2
reflect-metadata: ^0.1.13 reflect-metadata: ^0.1.13
rimraf: ^3.0.2 rimraf: ^3.0.2
@ -5093,6 +5094,22 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"libsodium-wrappers@npm:^0.7.10":
version: 0.7.10
resolution: "libsodium-wrappers@npm:0.7.10"
dependencies:
libsodium: ^0.7.0
checksum: 294ac098895a15f99e65431c62478f149e9e5cbbcd1fa1b41e832b65e0ead63856cc964b3b7c14447a48701e3334661dea9223442834ae7dd0d34285991616cd
languageName: node
linkType: hard
"libsodium@npm:^0.7.0":
version: 0.7.10
resolution: "libsodium@npm:0.7.10"
checksum: 243794a0b3b753fafb304a82e9ff777eaccf11785bde6965e7f25171fd2fb35da302a89f009a91c1e922817d37724f7afc86592b128b2b58ed657d7fbe5259e6
languageName: node
linkType: hard
"lines-and-columns@npm:^1.1.6": "lines-and-columns@npm:^1.1.6":
version: 1.2.4 version: 1.2.4
resolution: "lines-and-columns@npm:1.2.4" resolution: "lines-and-columns@npm:1.2.4"