🎨 Use new embed builder method instead for status and help

This commit is contained in:
Manuel Ruwe 2022-12-17 20:51:03 +01:00
parent 2571c71184
commit ef01e80890
4 changed files with 109 additions and 72 deletions

View File

@ -107,6 +107,14 @@ export class DiscordVoiceService {
); );
} }
/**
* Gets the current audio player status
* @returns The current audio player status
*/
getPlayerStatus(): AudioPlayerStatus {
return this.createAndReturnOrGetAudioPlayer().state.status;
}
/** /**
* Checks if the current state is paused or not and toggles the states to the opposite. * Checks if the current state is paused or not and toggles the states to the opposite.
* @returns The new paused state - true: paused, false: unpaused * @returns The new paused state - true: paused, false: unpaused

View File

@ -1,9 +1,8 @@
import { TransformPipe } from '@discord-nestjs/common'; import { TransformPipe } from '@discord-nestjs/common';
import { Command, DiscordCommand, UsePipes } from '@discord-nestjs/core'; import { Command, DiscordCommand, UsePipes } from '@discord-nestjs/core';
import { EmbedBuilder } from '@discordjs/builders';
import { CommandInteraction } from 'discord.js'; import { CommandInteraction } from 'discord.js';
import { DefaultJellyfinColor } from 'src/types/colors'; import { DiscordMessageService } from '../clients/discord/discord.message.service';
import { GenericCustomReply } from '../models/generic-try-handler'; import { GenericCustomReply } from '../models/generic-try-handler';
@Command({ @Command({
@ -12,21 +11,23 @@ import { GenericCustomReply } from '../models/generic-try-handler';
}) })
@UsePipes(TransformPipe) @UsePipes(TransformPipe)
export class HelpCommand implements DiscordCommand { export class HelpCommand implements DiscordCommand {
constructor(private readonly discordMessageService: DiscordMessageService) {}
handler(commandInteraction: CommandInteraction): GenericCustomReply { handler(commandInteraction: CommandInteraction): GenericCustomReply {
return { return {
embeds: [ embeds: [
new EmbedBuilder() this.discordMessageService.buildMessage({
title: 'a',
description:
'Jellyfin Discord Bot is an open source and self-hosted Discord bot, that integrates with your Jellyfin Media server and enables you to playback music from your libraries. You can use the Discord Slash Commands to invoke bot commands.',
mixin(embedBuilder) {
return embedBuilder
.setAuthor({ .setAuthor({
name: 'Jellyfin Discord Bot', name: 'Jellyfin Discord Bot',
iconURL: iconURL:
'https://github.com/walkxcode/dashboard-icons/blob/main/png/jellyfin.png?raw=true', 'https://github.com/walkxcode/dashboard-icons/blob/main/png/jellyfin.png?raw=true',
url: 'https://github.com/manuel-rw/jellyfin-discord-music-bot', url: 'https://github.com/manuel-rw/jellyfin-discord-music-bot',
}) })
.setColor(DefaultJellyfinColor)
.setTitle('Help Information')
.setDescription(
'Jellyfin Discord Music bot is an easy way to broadcast your music collection to a Discord voicechannel.',
)
.addFields([ .addFields([
{ {
name: 'Report an issue', name: 'Report an issue',
@ -36,11 +37,13 @@ export class HelpCommand implements DiscordCommand {
}, },
{ {
name: 'Source code', name: 'Source code',
value: 'https://github.com/manuel-rw/jellyfin-discord-music-bot', value:
'https://github.com/manuel-rw/jellyfin-discord-music-bot',
inline: true, inline: true,
}, },
]) ]);
.toJSON(), },
}),
], ],
}; };
} }

View File

@ -2,33 +2,40 @@ import { TransformPipe } from '@discord-nestjs/common';
import { import {
Command, Command,
DiscordTransformedCommand, DiscordCommand,
InjectDiscordClient, InjectDiscordClient,
TransformedCommandExecutionContext,
UsePipes, UsePipes,
} from '@discord-nestjs/core'; } from '@discord-nestjs/core';
import { EmbedBuilder } from '@discordjs/builders'; import {
import { Client, InteractionReplyOptions, Status } from 'discord.js'; Client,
import { DefaultJellyfinColor } from 'src/types/colors'; CommandInteraction,
InteractionReplyOptions,
Status,
} from 'discord.js';
import { formatDuration, intervalToDuration } from 'date-fns'; import { formatDuration, intervalToDuration } from 'date-fns';
import { DiscordMessageService } from '../clients/discord/discord.message.service';
import { JellyfinService } from '../clients/jellyfin/jellyfin.service';
import { Constants } from '../utils/constants'; import { Constants } from '../utils/constants';
import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api';
@Command({ @Command({
name: 'status', name: 'status',
description: 'Display the current status for troubleshooting', description: 'Display the current status for troubleshooting',
}) })
@UsePipes(TransformPipe) @UsePipes(TransformPipe)
export class StatusCommand implements DiscordTransformedCommand<unknown> { export class StatusCommand implements DiscordCommand {
constructor( constructor(
@InjectDiscordClient() @InjectDiscordClient()
private readonly client: Client, private readonly client: Client,
private readonly discordMessageService: DiscordMessageService,
private readonly jellyfinService: JellyfinService,
) {} ) {}
handler( async handler(
dto: unknown, commandInteraction: CommandInteraction,
executionContext: TransformedCommandExecutionContext<any>, ): Promise<string | InteractionReplyOptions> {
): InteractionReplyOptions {
const ping = this.client.ws.ping; const ping = this.client.ws.ping;
const status = Status[this.client.ws.status]; const status = Status[this.client.ws.status];
@ -38,34 +45,49 @@ export class StatusCommand implements DiscordTransformedCommand<unknown> {
}); });
const formattedDuration = formatDuration(interval); const formattedDuration = formatDuration(interval);
const jellyfinSystemApi = getSystemApi(this.jellyfinService.getApi());
const jellyfinSystemInformation = await jellyfinSystemApi.getSystemInfo();
return { return {
embeds: [ embeds: [
new EmbedBuilder() this.discordMessageService.buildMessage({
.setTitle('Online and ready') title: 'Discord Bot Status',
.setColor(DefaultJellyfinColor) mixin(embedBuilder) {
.addFields([ return embedBuilder.addFields([
{ {
name: 'Version', name: 'Bot Version',
value: Constants.Metadata.Version, value: Constants.Metadata.Version,
inline: false, inline: true,
}, },
{ {
name: 'Ping', name: 'Discord Bot Ping',
value: `${ping}ms`, value: `${ping}ms`,
inline: true, inline: true,
}, },
{ {
name: 'Status', name: 'Discord Bot Status',
value: `${status}`, value: `${status}`,
inline: true, inline: true,
}, },
{ {
name: 'Uptime', name: 'Discord Bot Uptime',
value: `${formattedDuration}`, value: `${formattedDuration}`,
inline: false,
},
{
name: 'Jellyfin Server Version',
value: jellyfinSystemInformation.data.Version ?? 'unknown',
inline: true, inline: true,
}, },
]) {
.toJSON(), name: 'Jellyfin Server Operating System',
value:
jellyfinSystemInformation.data.OperatingSystem ?? 'unknown',
inline: true,
},
]);
},
}),
], ],
}; };
} }

View File

@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { Playlist } from '../types/playlist'; import { Playlist } from '../types/playlist';
import { Track } from '../types/track'; import { Track } from '../types/track';
@ -7,6 +7,8 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
@Injectable() @Injectable()
export class PlaybackService { export class PlaybackService {
private readonly logger = new Logger(PlaybackService.name);
private readonly playlist: Playlist = { private readonly playlist: Playlist = {
tracks: [], tracks: [],
activeTrack: null, activeTrack: null,
@ -19,7 +21,6 @@ export class PlaybackService {
} }
setActiveTrack(trackId: string) { setActiveTrack(trackId: string) {
console.log(`getting track by id ${trackId}`);
const track = this.getTrackById(trackId); const track = this.getTrackById(trackId);
if (!track) { if (!track) {
@ -31,15 +32,12 @@ export class PlaybackService {
nextTrack() { nextTrack() {
const keys = this.getTrackIds(); const keys = this.getTrackIds();
console.log('keys:');
console.log(keys);
const index = this.getActiveIndex(); const index = this.getActiveIndex();
console.log(keys);
console.log(index);
if (!this.hasActiveTrack() || index + 1 >= keys.length) { if (!this.hasActiveTrack() || index + 1 >= keys.length) {
this.logger.debug(
`Unable to go to next track, because playback has reached end of the playlist`,
);
return false; return false;
} }
@ -53,6 +51,9 @@ export class PlaybackService {
const index = this.getActiveIndex(); const index = this.getActiveIndex();
if (!this.hasActiveTrack() || index < 1) { if (!this.hasActiveTrack() || index < 1) {
this.logger.debug(
`Unable to go to previous track, because there is no previous track in the playlist`,
);
return false; return false;
} }
@ -118,6 +119,9 @@ export class PlaybackService {
private controlAudioPlayer() { private controlAudioPlayer() {
const activeTrack = this.getActiveTrack(); const activeTrack = this.getActiveTrack();
this.logger.debug(
`A new track (${activeTrack.id}) was requested and will be emmitted as an event`,
);
this.eventEmitter.emit('playback.newTrack', activeTrack.track); this.eventEmitter.emit('playback.newTrack', activeTrack.track);
} }
} }