add error callback to allow errors to be shown within discord
This commit is contained in:
parent
891b081791
commit
83ede78a1d
|
@ -54,7 +54,7 @@ function nowPlayingResponse(bot: Bot, interaction: Interaction) {
|
|||
}
|
||||
}
|
||||
|
||||
function nowPlayingMessage(bot: Bot, guildId: number) {
|
||||
function nowPlayingMessage(bot: Bot, guildId: BigInt) {
|
||||
const player = bot.helpers.getPlayer(guildId);
|
||||
return <CreateMessage>{
|
||||
embeds: [<Embed>{
|
||||
|
|
|
@ -60,13 +60,14 @@ export async function play(bot: Bot, interaction: Interaction, _args?) {
|
|||
}
|
||||
|
||||
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.user.username, 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) {
|
||||
await editOriginalInteractionResponse(bot, interaction.token, addedToQueueResponse(interaction, result[0].title));
|
||||
}
|
||||
|
@ -84,72 +85,3 @@ export async function play(bot: Bot, interaction: Interaction, _args?) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*import { exists } from "https://deno.land/std@0.161.0/fs/mod.ts";
|
||||
|
||||
import { configs } from "../configs.ts";
|
||||
import { Bot } from "../deps.ts";
|
||||
import { download, ensureVoiceConnection } from "../utils.ts";
|
||||
import { type Command } from "../types.ts";
|
||||
|
||||
export async function play(bot: Bot, command: Command) {
|
||||
await ensureVoiceConnection(bot, command.guildId);
|
||||
const player = bot.helpers.getPlayer(command.guildId);
|
||||
await player.pushQuery(command.params);
|
||||
await player.play();
|
||||
}*/
|
||||
|
||||
/*const parsed_url = new URL(url);
|
||||
let video_id = "";
|
||||
|
||||
if(parsed_url.href.indexOf("youtube.com") !== -1) {
|
||||
video_id = parsed_url.search.substring(3);
|
||||
} else if(parsed_url.href.indexOf("youtu.be") === -1) {
|
||||
video_id = parsed_url.pathname.substring(1);
|
||||
} else {
|
||||
return {
|
||||
status: false,
|
||||
message: "This URL is invalid"
|
||||
};
|
||||
}
|
||||
|
||||
if (!(await exists(`${configs.project_root}/music/`))) {
|
||||
await download(video_id);
|
||||
}*/
|
||||
|
||||
|
||||
// single video
|
||||
/*
|
||||
URL {
|
||||
href: "https://www.youtube.com/watch?v=DhobsmmyGFs",
|
||||
origin: "https://www.youtube.com",
|
||||
protocol: "https:",
|
||||
username: "",
|
||||
password: "",
|
||||
host: "www.youtube.com",
|
||||
hostname: "www.youtube.com",
|
||||
port: "",
|
||||
pathname: "/watch",
|
||||
hash: "",
|
||||
search: "?v=DhobsmmyGFs"
|
||||
}
|
||||
{
|
||||
endpoint: "stockholm3048.discord.media:443",
|
||||
sessionId: "74d4d31a8f5c507f9852278867d42c05",
|
||||
token: "08b9f3bc65a233d5"
|
||||
}*/
|
||||
|
||||
// playlist
|
||||
/*URL {
|
||||
href: "https://www.youtube.com/playlist?list=PLvNazUnle2rTZO7OVYhhRdzFb9W4xSpNk",
|
||||
origin: "https://www.youtube.com",
|
||||
protocol: "https:",
|
||||
username: "",
|
||||
password: "",
|
||||
host: "www.youtube.com",
|
||||
hostname: "www.youtube.com",
|
||||
port: "",
|
||||
pathname: "/playlist",
|
||||
hash: "",
|
||||
search: "?list=PLvNazUnle2rTZO7OVYhhRdzFb9W4xSpNk"
|
||||
}*/
|
|
@ -6,6 +6,7 @@ export type AudioSource = {
|
|||
data: () =>
|
||||
| Promise<AsyncIterableIterator<Uint8Array>>
|
||||
| AsyncIterableIterator<Uint8Array>;
|
||||
guildId: bigint;
|
||||
added_by?: string;
|
||||
};
|
||||
|
||||
|
@ -16,6 +17,7 @@ export function createAudioSource(
|
|||
data: () =>
|
||||
| Promise<AsyncIterableIterator<Uint8Array>>
|
||||
| AsyncIterableIterator<Uint8Array>,
|
||||
guildId: bigint,
|
||||
added_by?: string
|
||||
): AudioSource {
|
||||
lastId++;
|
||||
|
@ -31,6 +33,7 @@ export function createAudioSource(
|
|||
return empty();
|
||||
}
|
||||
},
|
||||
guildId,
|
||||
added_by
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { getYoutubeSources } from "./youtube.ts";
|
|||
|
||||
export type LoadSource = typeof loadLocalOrYoutube;
|
||||
|
||||
export function loadLocalOrYoutube(query: string, added_by?: string) {
|
||||
return getYoutubeSources(query, String(added_by));
|
||||
export function loadLocalOrYoutube(query: string, guildId: bigint, added_by?: string) {
|
||||
return getYoutubeSources(guildId, String(added_by), query);
|
||||
}
|
||||
|
|
|
@ -3,31 +3,35 @@ import { bufferIter } from "../../utils/mod.ts";
|
|||
import { demux } from "../demux/mod.ts";
|
||||
import { createAudioSource, empty } from "./audio-source.ts";
|
||||
|
||||
export async function getYoutubeSources(added_by?: string, ...queries: string[]) {
|
||||
const sources = queries.map((query) => getYoutubeSource(query, added_by));
|
||||
import { errorMessageCallback, parseYoutubeId } from "../../../utils.ts";
|
||||
|
||||
export async function getYoutubeSources(guildId: bigint, added_by?: string, ...queries: string[]) {
|
||||
const sources = queries.map((query) => getYoutubeSource(query, guildId, added_by));
|
||||
const awaitedSources = await Promise.all(sources);
|
||||
return awaitedSources
|
||||
.filter((source) => source !== undefined)
|
||||
.map((source) => source!);
|
||||
}
|
||||
|
||||
export async function getYoutubeSource(query: string, added_by?: string) {
|
||||
export async function getYoutubeSource(query: string, guildId: bigint, added_by?: string) {
|
||||
try {
|
||||
query = parseYoutubeId(query);
|
||||
const results = await YouTube.search(query, { limit: 1, type: "video" });
|
||||
if (results.length > 0) {
|
||||
const { id, title } = results[0];
|
||||
return createAudioSource(title!, async () => {
|
||||
try {
|
||||
const stream = await ytDownload(id!, {
|
||||
const stream = await ytDownload(query, {
|
||||
mimeType: `audio/webm; codecs="opus"`,
|
||||
});
|
||||
return bufferIter(demux(stream));
|
||||
} catch {
|
||||
console.error("error");
|
||||
errorMessageCallback(guildId, `There was an error trying to play **${title}**:\n
|
||||
something broke in getYoutubeSource`);
|
||||
console.log(`Failed to play ${title}\n Returning empty stream`);
|
||||
return empty();
|
||||
}
|
||||
}, added_by);
|
||||
}, guildId, added_by);
|
||||
}
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
|
|
|
@ -9,7 +9,7 @@ export type BotData = {
|
|||
guildData: Map<bigint, ConnectionData>;
|
||||
udpSource: EventSource<[UdpArgs]>;
|
||||
bufferSize: number;
|
||||
loadSource: (query: string, added_by?: string) => AudioSource[] | Promise<AudioSource[]>;
|
||||
loadSource: (query: string, guild_id: bigint, added_by?: string) => AudioSource[] | Promise<AudioSource[]>;
|
||||
};
|
||||
|
||||
export type ConnectionData = {
|
||||
|
|
|
@ -79,24 +79,24 @@ export class QueuePlayer extends Queue<AudioSource> implements Player {
|
|||
* Interrupts the current song, resumes when finished
|
||||
* @param query Loads a universal song (local file or youtube search)
|
||||
*/
|
||||
async interruptQuery(query: string) {
|
||||
const sources = await this.#loadSource(query as string);
|
||||
async interruptQuery(guildId: bigint, query: string) {
|
||||
const sources = await this.#loadSource(query as string, guildId);
|
||||
this.#rawPlayer.interrupt(await sources[0].data());
|
||||
}
|
||||
|
||||
async pushQuery(added_by?: string, ...queries: string[]) {
|
||||
async pushQuery(guildId: bigint, added_by?: string, ...queries: string[]) {
|
||||
const sources = [];
|
||||
for (const query of queries) {
|
||||
sources.push(...(await this.#loadSource(String(added_by), query as string)));
|
||||
sources.push(...(await this.#loadSource(query as string, guildId, String(added_by))));
|
||||
this.push(...sources);
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
async unshiftQuery(...queries: string[]) {
|
||||
async unshiftQuery(guildId: bigint, ...queries: string[]) {
|
||||
const sources = [];
|
||||
for (const query of queries) {
|
||||
sources.push(...(await this.#loadSource(query as string)));
|
||||
sources.push(...(await this.#loadSource(query as string, guildId)));
|
||||
this.unshift(...sources);
|
||||
}
|
||||
return sources;
|
||||
|
|
2
main.ts
2
main.ts
|
@ -30,7 +30,7 @@ export const bot = enableAudioPlugin(baseBot);
|
|||
|
||||
bot.events.ready = async function (bot, payload) {
|
||||
//await registerCommands(bot);
|
||||
console.log(`${cyan("permanent waves")} is ready to go with session id ${yellow(payload.sessionId)}`);
|
||||
console.log(`${cyan("permanent waves")} is ready to go`);
|
||||
sessionId = payload.sessionId;
|
||||
}
|
||||
|
||||
|
|
65
utils.ts
65
utils.ts
|
@ -1,9 +1,19 @@
|
|||
import { ytdl } from "https://deno.land/x/ytdl_core@v0.1.1/mod.ts";
|
||||
import { Bot } from "https://deno.land/x/discordeno@18.0.1/bot.ts";
|
||||
import { connectToVoiceChannel } from "https://deno.land/x/discordeno@18.0.1/helpers/guilds/mod.ts";
|
||||
import { configs } from "./configs.ts";
|
||||
import { getChannel, getChannels, getGuild, type BigString, type Embed, type InteractionCallbackData, type InteractionResponse } from "./deps.ts";
|
||||
import {
|
||||
getChannel,
|
||||
getChannels,
|
||||
getGuild,
|
||||
sendMessage,
|
||||
type BigString,
|
||||
type CreateMessage,
|
||||
type Embed,
|
||||
type InteractionCallbackData,
|
||||
type InteractionResponse
|
||||
} from "./deps.ts";
|
||||
import { bot } from "./main.ts";
|
||||
|
||||
import { ConnectionData } from "./discordeno-audio-plugin/mod.ts";
|
||||
|
||||
export function channelIsAllowed(guild: string, channel: string) {
|
||||
if(`${guild}:${channel}` in configs.allowed_text_channels) {
|
||||
|
@ -13,30 +23,6 @@ export function channelIsAllowed(guild: string, channel: string) {
|
|||
return false;
|
||||
}
|
||||
|
||||
export async function download(url: string) {
|
||||
try {
|
||||
const stream = await ytdl(url, { filter: "audio" });
|
||||
|
||||
const chunks: Uint8Array[] = [];
|
||||
|
||||
for await (const chunk of stream) {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
|
||||
const videoDetails = stream.videoInfo.videoDetails;
|
||||
const blob = new Blob(chunks);
|
||||
const result = await Deno.writeFile(`${configs.project_root}/music/${videoDetails.videoId}.mp3`, new Uint8Array(await blob.arrayBuffer()));
|
||||
return {
|
||||
result: true,
|
||||
message: `Now playing **${videoDetails.title}**`
|
||||
};
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function ensureVoiceConnection(bot: Bot, guildId: BigString) {
|
||||
const channels = await getChannels(bot, guildId);
|
||||
const guild = await getGuild(bot, <BigString>guildId);
|
||||
|
@ -47,9 +33,9 @@ export async function ensureVoiceConnection(bot: Bot, guildId: BigString) {
|
|||
}
|
||||
}
|
||||
|
||||
const channel = await getChannel(bot, channelId);
|
||||
await getChannel(bot, channelId);
|
||||
try {
|
||||
const connection = await bot.helpers.connectToVoiceChannel(guildId, channelId);
|
||||
await bot.helpers.connectToVoiceChannel(guildId, channelId);
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -93,4 +79,23 @@ export const waitingForResponse = <InteractionResponse>{
|
|||
data: {
|
||||
content: "waiting for response..."
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function errorMessage(bot: Bot, guildId: bigint, message: string) {
|
||||
const player = bot.helpers.getPlayer(guildId);
|
||||
return <CreateMessage>{
|
||||
embeds: [<Embed>{
|
||||
color: configs.embed_color,
|
||||
description: message
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
export async function errorMessageCallback(guildId: bigint, message: string) {
|
||||
const channel = await getAllowedTextChannel(bot, guildId);
|
||||
await sendMessage(bot, channel.id, errorMessage(bot, guildId, message));
|
||||
}
|
||||
|
||||
export function parseYoutubeId(url: string) {
|
||||
return url.substring(url.indexOf("?")+3);
|
||||
}
|
Loading…
Reference in New Issue