permanent-waves/commands/play.ts

106 lines
4.0 KiB
TypeScript

import {
Bot,
editOriginalInteractionResponse,
Interaction,
sendInteractionResponse,
type ApplicationCommandOption,
type CreateSlashApplicationCommand
} from "../deps.ts";
import { YouTube } from "../discordeno-audio-plugin/deps.ts";
import { ensureVoiceConnection, formatCallbackData, isPlaylist, waitingForResponse } from "../utils.ts";
async function addedPlaylistResponse(interaction: Interaction, url: string) {
const playlist = await YouTube.getPlaylist(url);
return formatCallbackData(`${interaction.user.username} added ${playlist.videoCount} videos from [**${playlist.title}**](${interaction!.data!.options![0].value}) to the queue.`,
"Added to queue");
}
function addedSongResponse(interaction: Interaction, title: string) {
return formatCallbackData(`${interaction.user.username} added [**${title}**](${interaction!.data!.options![0].value}) to the queue.`, "Added to queue");
}
function alreadyPlayingResponse(bot: Bot, interaction: Interaction) {
const player = bot.helpers.getPlayer(interaction.guildId);
return formatCallbackData(`The bot is already playing.
Currently playing: **${player.nowPlaying.title}**, added by ${player.nowPlaying.added_by}`);
}
const badUrlResponse = formatCallbackData(`Bad URL, please enter a URL that starts with https://youtube.com or https://youtu.be.`);
const emptyQueueResponse = formatCallbackData(`There's nothing in the queue to play right now.`);
function nowPlayingResponse(bot: Bot, interaction: Interaction) {
const player = bot.helpers.getPlayer(interaction.guildId);
return formatCallbackData(`The bot has started playing again.
Currently playing: **${player.nowPlaying.title}**, added by ${player.nowPlaying.added_by}`);
}
export const playCommand = <CreateSlashApplicationCommand>{
name: "play",
description: "Adds a song or playlist to the queue and starts the music if it's not already playing",
dmPermission: false,
options: [
<ApplicationCommandOption>{
type: 3, // string
name: "url",
description: "The URL or video ID of the song or playlist to play",
required: false
}
]
};
export async function play(bot: Bot, interaction: Interaction) {
if (!interaction.guildId) return;
await ensureVoiceConnection(bot, interaction.guildId);
const player = bot.helpers.getPlayer(interaction.guildId);
await sendInteractionResponse(bot, interaction.id, interaction.token, waitingForResponse);
let parsed_url;
if(!interaction) return;
if(!interaction.data) return;
if(interaction.data.options) {
if(!interaction.data.options[0].value) return;
try {
parsed_url = new URL(interaction.data.options[0].value.toString());
} catch {
await editOriginalInteractionResponse(bot, interaction.token, badUrlResponse);
}
if(!parsed_url) return;
let href;
// remove the timestamp from the query
if(parsed_url.href.indexOf("?t=") !== -1) {
href = parsed_url.href.substring(0, parsed_url.href.indexOf("?"))
} else {
href = parsed_url.href;
}
const result = await player.pushQuery(interaction.guildId, interaction.user.username, href);
if(result && result[0] && parsed_url.href.indexOf("youtube.com") !== -1 || parsed_url.href.indexOf("youtu.be") !== -1 && result[0].title) {
if(isPlaylist(parsed_url.href))
{
await editOriginalInteractionResponse(bot, interaction.token, await addedPlaylistResponse(interaction, parsed_url.href));
} else {
await editOriginalInteractionResponse(bot, interaction.token, addedSongResponse(interaction, result[0].title));
}
}
} else {
// restart the player if there's no url
if(player.waiting || !player.playing) {
if(player.nowPlaying) {
await player.play();
await editOriginalInteractionResponse(bot, interaction.token, nowPlayingResponse(bot, interaction));
} else {
await editOriginalInteractionResponse(bot, interaction.token, emptyQueueResponse);
}
} else {
await editOriginalInteractionResponse(bot, interaction.token, alreadyPlayingResponse(bot, interaction));
}
}
}