Implement Summon and Disconnect

This commit is contained in:
Manuel Ruwe 2022-12-16 21:21:26 +01:00
parent c581ef748a
commit 73f2f0eb5f
13 changed files with 167 additions and 36 deletions

View File

@ -61,3 +61,8 @@ $ npm run test:e2e
# test coverage
$ npm run test:cov
```
## 👤 Credits
- https://tabler-icons.io/ (MIT)
- https://docs.nestjs.com/ (MIT)
- https://discord.js.org/ (Apache 2.0)

View File

@ -24,6 +24,7 @@
"@discord-nestjs/common": "^4.0.8",
"@discord-nestjs/core": "^4.3.1",
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.14.0",
"@jellyfin/sdk": "^0.7.0",
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.2.0",

View File

@ -10,7 +10,7 @@ import { AppService } from './app.service';
import { DiscordClientModule } from './clients/discord/discord.module';
import { JellyfinClientModule } from './clients/jellyfin/jellyfin.module';
import { CommandModule } from './commands/command.module';
import { DiscordConfigService } from './clients/discord/jellyfin.config.service';
import { DiscordConfigService } from './clients/discord/discord.config.service';
@Module({
imports: [

View File

@ -11,7 +11,12 @@ export class DiscordConfigService implements DiscordOptionsFactory {
return {
token: process.env.DISCORD_CLIENT_TOKEN,
discordClientOptions: {
intents: [GatewayIntentBits.Guilds],
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildIntegrations,
],
},
};
}

View File

@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { DiscordConfigService } from './jellyfin.config.service';
import { DiscordConfigService } from './discord.config.service';
@Module({
imports: [],

View File

@ -0,0 +1,14 @@
import { Injectable } from "@nestjs/common";
import { VoiceChannel } from "discord.js";
@Injectable()
export class DiscordVoiceService {
summonClient(voiceChannel: VoiceChannel) {
// voiceChannel.join('');
}
startPlayback() {
}
}

View File

@ -1,8 +1,7 @@
import { Injectable, Logger } from '@nestjs/common';
import { Api, Jellyfin } from '@jellyfin/sdk';
import { Constants } from 'src/utils/constants';
import { Constants } from '../../utils/constants';
@Injectable()
export class JellyfinService {
@ -10,8 +9,6 @@ export class JellyfinService {
private jellyfin: Jellyfin;
private api: Api;
constructor() {}
init() {
this.jellyfin = new Jellyfin({
clientInfo: {

View File

@ -1,23 +1,55 @@
import { TransformPipe } from '@discord-nestjs/common';
import { Command, DiscordCommand, UsePipes } from '@discord-nestjs/core';
import {
Command,
DiscordTransformedCommand,
TransformedCommandExecutionContext,
UsePipes,
} from '@discord-nestjs/core';
import { InteractionReplyOptions } from 'discord.js';
CommandInteraction,
EmbedBuilder,
InteractionReplyOptions,
} from 'discord.js';
import { getVoiceConnection } from '@discordjs/voice';
import { DefaultJellyfinColor, ErrorJellyfinColor } from '../types/colors';
@Command({
name: 'disconnect',
description: 'Join your current voice channel',
})
@UsePipes(TransformPipe)
export class DisconnectCommand implements DiscordTransformedCommand<unknown> {
handler(
dto: unknown,
executionContext: TransformedCommandExecutionContext<any>,
): InteractionReplyOptions | string {
return 'nice';
export class DisconnectCommand implements DiscordCommand {
handler(interaction: CommandInteraction): InteractionReplyOptions | string {
const connection = getVoiceConnection(interaction.guildId);
if (!connection) {
return {
embeds: [
new EmbedBuilder()
.setColor(ErrorJellyfinColor)
.setAuthor({
name: 'Unable to disconnect from voice channel',
iconURL:
'https://github.com/manuel-rw/jellyfin-discord-music-bot/blob/nestjs-migration/images/icons/alert-circle.png?raw=true',
})
.setDescription(
'I am currently not connected to any voice channels',
)
.toJSON(),
],
};
return;
}
connection.destroy();
return {
embeds: [
new EmbedBuilder()
.setColor(DefaultJellyfinColor)
.setAuthor({
name: 'Disconnected from your channel',
iconURL:
'https://github.com/manuel-rw/jellyfin-discord-music-bot/blob/nestjs-migration/images/icons/circle-check.png?raw=true',
})
.toJSON(),
],
};
}
}

View File

@ -12,7 +12,7 @@ import { Client, InteractionReplyOptions, Status } from 'discord.js';
import { DefaultJellyfinColor } from 'src/types/colors';
import { formatDuration, intervalToDuration } from 'date-fns';
import { Constants } from 'src/utils/constants';
import { Constants } from '../utils/constants';
@Command({
name: 'status',

View File

@ -1,23 +1,64 @@
import { TransformPipe } from '@discord-nestjs/common';
import { Command, DiscordCommand, UsePipes } from '@discord-nestjs/core';
import { joinVoiceChannel } from '@discordjs/voice';
import { Logger } from '@nestjs/common';
import {
Command,
DiscordTransformedCommand,
TransformedCommandExecutionContext,
UsePipes,
} from '@discord-nestjs/core';
import { InteractionReplyOptions } from 'discord.js';
CommandInteraction,
EmbedBuilder,
GuildMember,
InteractionReplyOptions
} from 'discord.js';
import { DefaultJellyfinColor } from '../types/colors';
@Command({
name: 'summon',
description: 'Join your current voice channel',
})
@UsePipes(TransformPipe)
export class SummonCommand implements DiscordTransformedCommand<unknown> {
handler(
dto: unknown,
executionContext: TransformedCommandExecutionContext<any>,
): InteractionReplyOptions | string {
return 'nice';
export class SummonCommand implements DiscordCommand {
private readonly logger = new Logger(SummonCommand.name);
handler(interaction: CommandInteraction): InteractionReplyOptions | string {
const guildMember = interaction.member as GuildMember;
if (guildMember.voice.channel === null) {
return {
embeds: [
new EmbedBuilder()
.setColor(DefaultJellyfinColor)
.setAuthor({
name: 'Unable to join your channel',
iconURL:
'https://github.com/manuel-rw/jellyfin-discord-music-bot/blob/nestjs-migration/images/icons/alert-circle.png?raw=true',
})
.setDescription(
'You are in a channel, I am either unabelt to connect to or you aren&apost in a channel yet',
)
.toJSON(),
],
};
}
const channel = guildMember.voice.channel;
joinVoiceChannel({
channelId: channel.id,
adapterCreator: channel.guild.voiceAdapterCreator,
guildId: channel.guildId,
});
return {
embeds: [
new EmbedBuilder()
.setColor(DefaultJellyfinColor)
.setAuthor({
name: 'Joined your voicehannel',
iconURL:
'https://github.com/manuel-rw/jellyfin-discord-music-bot/blob/nestjs-migration/images/icons/circle-check.png?raw=true&test=a',
})
.toJSON(),
],
};
}
}

View File

@ -1,3 +1,4 @@
import { RGBTuple } from 'discord.js';
export const DefaultJellyfinColor: RGBTuple = [119, 116, 204];
export const ErrorJellyfinColor: RGBTuple = [242, 33, 95];

View File

@ -1,6 +1,6 @@
export const Constants = {
Metadata: {
Version: "0.0.1",
ApplicationName: "Discord Jellyfin Music Bot"
}
}
Version: '0.0.1',
ApplicationName: 'Discord Jellyfin Music Bot',
},
};

View File

@ -597,6 +597,19 @@ __metadata:
languageName: node
linkType: hard
"@discordjs/voice@npm:^0.14.0":
version: 0.14.0
resolution: "@discordjs/voice@npm:0.14.0"
dependencies:
"@types/ws": ^8.5.3
discord-api-types: ^0.37.20
prism-media: ^1.3.4
tslib: ^2.4.1
ws: ^8.11.0
checksum: baa68a324f8c7b4a7863a966e7d10a01a4df93aa68800f867e7a6fef016fcd16306ff5a562674884192b0e6538e53e8404d114a7c9781f0637c8e0dea3bca368
languageName: node
linkType: hard
"@eslint/eslintrc@npm:^1.3.3":
version: 1.3.3
resolution: "@eslint/eslintrc@npm:1.3.3"
@ -4438,6 +4451,7 @@ __metadata:
"@discord-nestjs/common": ^4.0.8
"@discord-nestjs/core": ^4.3.1
"@discordjs/opus": ^0.9.0
"@discordjs/voice": ^0.14.0
"@jellyfin/sdk": ^0.7.0
"@nestjs/cli": ^9.0.0
"@nestjs/common": ^9.0.0
@ -5961,6 +5975,27 @@ __metadata:
languageName: node
linkType: hard
"prism-media@npm:^1.3.4":
version: 1.3.4
resolution: "prism-media@npm:1.3.4"
peerDependencies:
"@discordjs/opus": ^0.8.0
ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0
node-opus: ^0.3.3
opusscript: ^0.0.8
peerDependenciesMeta:
"@discordjs/opus":
optional: true
ffmpeg-static:
optional: true
node-opus:
optional: true
opusscript:
optional: true
checksum: 703be28c87b4694714a52a0ea84516b19d2e62e510d0f204efc074b044ad93dde00241d4b4741c25aa2e27a00e3b472e60ad0f6c94e88710f0827dc63889373a
languageName: node
linkType: hard
"process-nextick-args@npm:~2.0.0":
version: 2.0.1
resolution: "process-nextick-args@npm:2.0.1"