update discordeno-audio-plugin and finally switch to yt_download, update discordeno
This commit is contained in:
parent
320d6d1782
commit
891b081791
24
deps.ts
24
deps.ts
|
@ -1,4 +1,4 @@
|
||||||
export { ApplicationCommandOptionTypes, createBot, Intents, startBot } from "https://deno.land/x/discordeno@17.0.1/mod.ts";
|
export { ApplicationCommandOptionTypes, createBot, Intents, startBot } from "https://deno.land/x/discordeno@18.0.1/mod.ts";
|
||||||
export {
|
export {
|
||||||
createGlobalApplicationCommand,
|
createGlobalApplicationCommand,
|
||||||
editGlobalApplicationCommand,
|
editGlobalApplicationCommand,
|
||||||
|
@ -9,15 +9,15 @@ export {
|
||||||
sendFollowupMessage,
|
sendFollowupMessage,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
upsertGlobalApplicationCommands
|
upsertGlobalApplicationCommands
|
||||||
} from "https://deno.land/x/discordeno@17.0.1/helpers/mod.ts";
|
} from "https://deno.land/x/discordeno@18.0.1/helpers/mod.ts";
|
||||||
export { type BigString, type CreateApplicationCommand, type CreateSlashApplicationCommand, type InteractionCallbackData } from "https://deno.land/x/discordeno@17.0.1/types/mod.ts";
|
export { type BigString, type CreateApplicationCommand, type CreateSlashApplicationCommand, type InteractionCallbackData } from "https://deno.land/x/discordeno@18.0.1/types/mod.ts";
|
||||||
export { type CreateMessage } from "https://deno.land/x/discordeno@17.0.1/helpers/messages/mod.ts";
|
export { type CreateMessage } from "https://deno.land/x/discordeno@18.0.1/helpers/messages/mod.ts";
|
||||||
export { type InteractionResponse } from "https://deno.land/x/discordeno@17.0.1/types/discordeno.ts";
|
export { type InteractionResponse } from "https://deno.land/x/discordeno@18.0.1/types/discordeno.ts";
|
||||||
export { editOriginalInteractionResponse, sendInteractionResponse } from "https://deno.land/x/discordeno@17.0.1/helpers/interactions/mod.ts";
|
export { editOriginalInteractionResponse, sendInteractionResponse } from "https://deno.land/x/discordeno@18.0.1/helpers/interactions/mod.ts";
|
||||||
export { sendPrivateInteractionResponse } from "https://deno.land/x/discordeno@17.0.1/plugins/mod.ts";
|
export { sendPrivateInteractionResponse } from "https://deno.land/x/discordeno@18.0.1/plugins/mod.ts";
|
||||||
export { type Channel } from "https://deno.land/x/discordeno@17.0.1/transformers/channel.ts";
|
export { type Channel } from "https://deno.land/x/discordeno@18.0.1/transformers/channel.ts";
|
||||||
export { type Bot } from "https://deno.land/x/discordeno@17.0.1/bot.ts";
|
export { type Bot } from "https://deno.land/x/discordeno@18.0.1/bot.ts";
|
||||||
export { type Interaction } from "https://deno.land/x/discordeno@17.0.1/transformers/interaction.ts";
|
export { type Interaction } from "https://deno.land/x/discordeno@18.0.1/transformers/interaction.ts";
|
||||||
export { type ApplicationCommandOption, type ApplicationCommandOptionChoice, type Embed } from "https://deno.land/x/discordeno@17.0.1/transformers/mod.ts";
|
export { type ApplicationCommandOption, type ApplicationCommandOptionChoice, type Embed } from "https://deno.land/x/discordeno@18.0.1/transformers/mod.ts";
|
||||||
export { leaveVoiceChannel } from "https://deno.land/x/discordeno@17.0.1/helpers/guilds/mod.ts";
|
export { leaveVoiceChannel } from "https://deno.land/x/discordeno@18.0.1/helpers/guilds/mod.ts";
|
||||||
export { getConnectionData } from "./discordeno-audio-plugin/src/connection-data.ts";
|
export { getConnectionData } from "./discordeno-audio-plugin/src/connection-data.ts";
|
|
@ -1,8 +1,6 @@
|
||||||
export * from "https://deno.land/x/discordeno@17.1.0/mod.ts";
|
export * from "https://deno.land/x/discordeno@18.0.1/mod.ts";
|
||||||
export * from "https://deno.land/x/discordeno@17.1.0/plugins/cache/mod.ts";
|
export * from "https://deno.land/x/discordeno@18.0.1/plugins/cache/mod.ts";
|
||||||
export * as opus from "https://unpkg.com/@evan/wasm@0.0.95/target/opus/deno.js";
|
export * as opus from "https://unpkg.com/@evan/wasm@0.0.95/target/opus/deno.js";
|
||||||
export * from "https://unpkg.com/@evan/wasm@0.0.95/target/nacl/deno.js";
|
export * from "https://unpkg.com/@evan/wasm@0.0.95/target/nacl/deno.js";
|
||||||
export { ytDownload } from "https://deno.land/x/yt_download@1.2/mod.ts";
|
export { ytDownload } from "https://deno.land/x/yt_download@1.3/mod.ts";
|
||||||
export type { VideoFormat } from "https://deno.land/x/ytdl_core@v0.1.2/src/types.ts";
|
|
||||||
export { downloadFromInfo, getInfo, ytdl } from "https://deno.land/x/ytdl_core@v0.1.2/mod.ts";
|
|
||||||
export { default as YouTube } from "https://deno.land/x/youtube_sr@v4.1.17/mod.ts";
|
export { default as YouTube } from "https://deno.land/x/youtube_sr@v4.1.17/mod.ts";
|
|
@ -1,20 +1,8 @@
|
||||||
import { YouTube, ytdl } from "../../deps.ts";
|
import { YouTube, ytDownload } from "../../deps.ts";
|
||||||
import { bufferIter } from "../../utils/mod.ts";
|
import { bufferIter } from "../../utils/mod.ts";
|
||||||
import { demux } from "../demux/mod.ts";
|
import { demux } from "../demux/mod.ts";
|
||||||
import { createAudioSource, empty } from "./audio-source.ts";
|
import { createAudioSource, empty } from "./audio-source.ts";
|
||||||
|
|
||||||
function supportedFormatFilter(format: {
|
|
||||||
codecs: string;
|
|
||||||
container: string;
|
|
||||||
audioSampleRate?: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
format.codecs === "opus" &&
|
|
||||||
format.container === "webm" &&
|
|
||||||
format.audioSampleRate === "48000"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getYoutubeSources(added_by?: string, ...queries: string[]) {
|
export async function getYoutubeSources(added_by?: string, ...queries: string[]) {
|
||||||
const sources = queries.map((query) => getYoutubeSource(query, added_by));
|
const sources = queries.map((query) => getYoutubeSource(query, added_by));
|
||||||
const awaitedSources = await Promise.all(sources);
|
const awaitedSources = await Promise.all(sources);
|
||||||
|
@ -30,11 +18,12 @@ export async function getYoutubeSource(query: string, added_by?: string) {
|
||||||
const { id, title } = results[0];
|
const { id, title } = results[0];
|
||||||
return createAudioSource(title!, async () => {
|
return createAudioSource(title!, async () => {
|
||||||
try {
|
try {
|
||||||
const stream = await ytdl(id!, {
|
const stream = await ytDownload(id!, {
|
||||||
filter: supportedFormatFilter
|
mimeType: `audio/webm; codecs="opus"`,
|
||||||
});
|
});
|
||||||
return bufferIter(demux(stream));
|
return bufferIter(demux(stream));
|
||||||
} catch {
|
} catch {
|
||||||
|
console.error("error");
|
||||||
console.log(`Failed to play ${title}\n Returning empty stream`);
|
console.log(`Failed to play ${title}\n Returning empty stream`);
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ export type ConnectionData = {
|
||||||
speaking: boolean;
|
speaking: boolean;
|
||||||
sequence: number;
|
sequence: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
missedHeart: number;
|
||||||
|
lastHeart?: number;
|
||||||
|
reconnect: number;
|
||||||
};
|
};
|
||||||
connectInfo: {
|
connectInfo: {
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
|
@ -106,6 +109,8 @@ export function getConnectionData(botId: bigint, guildId: bigint) {
|
||||||
speaking: false,
|
speaking: false,
|
||||||
sequence: randomNBit(16),
|
sequence: randomNBit(16),
|
||||||
timestamp: randomNBit(32),
|
timestamp: randomNBit(32),
|
||||||
|
missedHeart: 0,
|
||||||
|
reconnect: 0,
|
||||||
},
|
},
|
||||||
connectInfo: {},
|
connectInfo: {},
|
||||||
audio: new EventSource<[Uint8Array]>(),
|
audio: new EventSource<[Uint8Array]>(),
|
||||||
|
|
|
@ -76,16 +76,6 @@ export function createOnAudio(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((data) => data !== undefined)
|
.filter((data) => data !== undefined)
|
||||||
.map((data) => data!)
|
.map((data) => data!);
|
||||||
.filter((data) => !silence(...data.decoded));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function silence(...values: number[]) {
|
|
||||||
for (const value of values) {
|
|
||||||
if (value !== 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,42 +3,23 @@ import { ConnectionData, setUserSSRC } from "../connection-data.ts";
|
||||||
import { discoverIP } from "../udp/discover.ts";
|
import { discoverIP } from "../udp/discover.ts";
|
||||||
import { setSpeaking } from "../udp/speaking.ts";
|
import { setSpeaking } from "../udp/speaking.ts";
|
||||||
import { sendHeart } from "./heartbeat.ts";
|
import { sendHeart } from "./heartbeat.ts";
|
||||||
|
import { ReceiveVoiceOpcodes } from "./opcodes.ts";
|
||||||
export enum ServerVoiceOpcodes {
|
|
||||||
/** Complete the websocket handshake. */
|
|
||||||
Ready = VoiceOpcodes.Ready,
|
|
||||||
/** Describe the session. */
|
|
||||||
SessionDescription = VoiceOpcodes.SessionDescription,
|
|
||||||
/** Indicate which users are speaking. */
|
|
||||||
Speaking = VoiceOpcodes.Speaking,
|
|
||||||
/** Sent to acknowledge a received client heartbeat. */
|
|
||||||
HeartbeatACK = VoiceOpcodes.HeartbeatACK,
|
|
||||||
/** Time to wait between sending heartbeats in milliseconds. */
|
|
||||||
Hello = VoiceOpcodes.Hello,
|
|
||||||
/** Acknowledge a successful session resume. */
|
|
||||||
Resumed = VoiceOpcodes.Resumed,
|
|
||||||
/** A client has disconnected from the voice channel */
|
|
||||||
ClientDisconnect = VoiceOpcodes.ClientDisconnect,
|
|
||||||
/** Weird OP code containing video and audio codecs */
|
|
||||||
Undocumented = 14,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const socketHandlers: Record<
|
export const socketHandlers: Record<
|
||||||
ServerVoiceOpcodes,
|
ReceiveVoiceOpcodes,
|
||||||
(connectionData: ConnectionData, d: any) => void
|
(connectionData: ConnectionData, d: any) => void
|
||||||
> = {
|
> = {
|
||||||
[ServerVoiceOpcodes.Ready]: ready,
|
[ReceiveVoiceOpcodes.Ready]: ready,
|
||||||
[ServerVoiceOpcodes.SessionDescription]: sessionDescription,
|
[ReceiveVoiceOpcodes.SessionDescription]: sessionDescription,
|
||||||
[ServerVoiceOpcodes.Speaking]: speaking,
|
[ReceiveVoiceOpcodes.Speaking]: speaking,
|
||||||
[ServerVoiceOpcodes.HeartbeatACK]: heartbeatACK,
|
[ReceiveVoiceOpcodes.HeartbeatACK]: heartbeatACK,
|
||||||
[ServerVoiceOpcodes.Hello]: hello,
|
[ReceiveVoiceOpcodes.Hello]: hello,
|
||||||
[ServerVoiceOpcodes.Resumed]: resumed,
|
[ReceiveVoiceOpcodes.Resumed]: resumed,
|
||||||
[ServerVoiceOpcodes.ClientDisconnect]: clientDisconnect,
|
[ReceiveVoiceOpcodes.ClientDisconnect]: clientDisconnect,
|
||||||
[ServerVoiceOpcodes.Undocumented]: undocumented,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function hello(conn: ConnectionData, d: { heartbeat_interval: number }) {
|
function hello(conn: ConnectionData, d: { heartbeat_interval: number }) {
|
||||||
conn.stopHeart = sendHeart(conn.ws!, d.heartbeat_interval);
|
conn.stopHeart = sendHeart(conn, d.heartbeat_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ready(conn: ConnectionData, d: any) {
|
function ready(conn: ConnectionData, d: any) {
|
||||||
|
@ -65,8 +46,9 @@ function ready(conn: ConnectionData, d: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function resumed(conn: ConnectionData) {
|
function resumed(conn: ConnectionData) {
|
||||||
console.log("Resumed success");
|
|
||||||
conn.context.ready = true;
|
conn.context.ready = true;
|
||||||
|
conn.context.reconnect = 0;
|
||||||
|
setSpeaking(conn, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sessionDescription(conn: ConnectionData, d: any) {
|
function sessionDescription(conn: ConnectionData, d: any) {
|
||||||
|
@ -75,6 +57,7 @@ function sessionDescription(conn: ConnectionData, d: any) {
|
||||||
conn.secret = new Uint8Array(secret);
|
conn.secret = new Uint8Array(secret);
|
||||||
conn.mode = mode;
|
conn.mode = mode;
|
||||||
conn.context.ready = true;
|
conn.context.ready = true;
|
||||||
|
conn.context.reconnect = 0;
|
||||||
setSpeaking(conn, true);
|
setSpeaking(conn, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +66,12 @@ function speaking(conn: ConnectionData, d: any) {
|
||||||
const ssrc = Number(d.ssrc);
|
const ssrc = Number(d.ssrc);
|
||||||
setUserSSRC(conn, user_id, ssrc);
|
setUserSSRC(conn, user_id, ssrc);
|
||||||
}
|
}
|
||||||
function heartbeatACK() {}
|
|
||||||
|
function heartbeatACK(conn: ConnectionData, d: number) {
|
||||||
|
if (conn.context.lastHeart === d) {
|
||||||
|
conn.context.missedHeart = 0;
|
||||||
|
conn.context.lastHeart = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clientDisconnect() {}
|
function clientDisconnect() {}
|
||||||
|
|
||||||
function undocumented() {}
|
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
import { VoiceOpcodes } from "../../deps.ts";
|
import { VoiceOpcodes } from "../../deps.ts";
|
||||||
import { setDriftlessTimeout } from "npm:driftless";
|
import { setDriftlessTimeout } from "npm:driftless";
|
||||||
|
import { ConnectionData } from "../mod.ts";
|
||||||
|
|
||||||
function createHeartBeat(time: number) {
|
function sendHeartBeat(conn: ConnectionData) {
|
||||||
return JSON.stringify({
|
if (conn.context.lastHeart !== undefined) {
|
||||||
op: VoiceOpcodes.Heartbeat,
|
conn.context.missedHeart++;
|
||||||
d: time,
|
}
|
||||||
});
|
conn.context.lastHeart = Date.now();
|
||||||
|
conn.ws?.send(
|
||||||
|
JSON.stringify({
|
||||||
|
op: VoiceOpcodes.Heartbeat,
|
||||||
|
d: conn.context.lastHeart,
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendHeart(ws: WebSocket, interval: number) {
|
export function sendHeart(conn: ConnectionData, interval: number) {
|
||||||
let last = Date.now();
|
let last = Date.now();
|
||||||
let timestamp = 0;
|
if (conn.ws?.readyState === WebSocket.OPEN) {
|
||||||
const heartbeat = createHeartBeat(timestamp);
|
sendHeartBeat(conn);
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
|
||||||
ws.send(heartbeat);
|
|
||||||
}
|
}
|
||||||
let done = false;
|
let done = false;
|
||||||
const repeatBeat = () => {
|
const repeatBeat = () => {
|
||||||
if (done || ws.readyState !== WebSocket.OPEN) {
|
if (done || conn.ws?.readyState !== WebSocket.OPEN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (conn.context.missedHeart >= 3) {
|
||||||
|
console.log("Missed too many heartbeats, attempting reconnect");
|
||||||
|
conn.ws?.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timestamp += interval;
|
|
||||||
const heartbeat = createHeartBeat(timestamp);
|
|
||||||
last = Date.now();
|
last = Date.now();
|
||||||
ws.send(heartbeat);
|
sendHeartBeat(conn);
|
||||||
setDriftlessTimeout(repeatBeat, interval + (last - Date.now()));
|
setDriftlessTimeout(repeatBeat, interval + (last - Date.now()));
|
||||||
};
|
};
|
||||||
setDriftlessTimeout(repeatBeat, interval + (last - Date.now()));
|
setDriftlessTimeout(repeatBeat, interval + (last - Date.now()));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { VoiceOpcodes } from "../../deps.ts";
|
import { VoiceCloseEventCodes } from "../../deps.ts";
|
||||||
import { ConnectionData } from "../connection-data.ts";
|
import { ConnectionData } from "../connection-data.ts";
|
||||||
import { ServerVoiceOpcodes, socketHandlers } from "./handlers.ts";
|
import { socketHandlers } from "./handlers.ts";
|
||||||
|
import { SendVoiceOpcodes } from "./opcodes.ts";
|
||||||
|
|
||||||
export function connectWebSocket(
|
export function connectWebSocket(
|
||||||
conn: ConnectionData,
|
conn: ConnectionData,
|
||||||
|
@ -19,7 +20,7 @@ export function connectWebSocket(
|
||||||
const ws = new WebSocket(`wss://${endpoint}?v=4`);
|
const ws = new WebSocket(`wss://${endpoint}?v=4`);
|
||||||
conn.ws = ws;
|
conn.ws = ws;
|
||||||
const identifyRequest = JSON.stringify({
|
const identifyRequest = JSON.stringify({
|
||||||
op: VoiceOpcodes.Identify,
|
op: SendVoiceOpcodes.Identify,
|
||||||
d: {
|
d: {
|
||||||
server_id: guildId.toString(),
|
server_id: guildId.toString(),
|
||||||
user_id: userId.toString(),
|
user_id: userId.toString(),
|
||||||
|
@ -28,7 +29,7 @@ export function connectWebSocket(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const resumeRequest = JSON.stringify({
|
const resumeRequest = JSON.stringify({
|
||||||
op: VoiceOpcodes.Resume,
|
op: SendVoiceOpcodes.Resume,
|
||||||
d: {
|
d: {
|
||||||
server_id: guildId.toString(),
|
server_id: guildId.toString(),
|
||||||
session_id: sessionId,
|
session_id: sessionId,
|
||||||
|
@ -69,7 +70,7 @@ function handleOpen(
|
||||||
|
|
||||||
function handleMessage(conn: ConnectionData, ev: MessageEvent<any>) {
|
function handleMessage(conn: ConnectionData, ev: MessageEvent<any>) {
|
||||||
const data = JSON.parse(ev.data);
|
const data = JSON.parse(ev.data);
|
||||||
socketHandlers[data.op as ServerVoiceOpcodes](conn, data.d);
|
socketHandlers[data.op]?.(conn, data.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClose(
|
function handleClose(
|
||||||
|
@ -80,15 +81,19 @@ function handleClose(
|
||||||
) {
|
) {
|
||||||
conn.stopHeart();
|
conn.stopHeart();
|
||||||
conn.context.ready = false;
|
conn.context.ready = false;
|
||||||
if (event.code < 4000) {
|
conn.context.speaking = false;
|
||||||
console.log("The socket lost its connection for some reason");
|
conn.context.lastHeart = undefined;
|
||||||
conn.resume = true;
|
conn.context.missedHeart = 0;
|
||||||
connectWebSocket(conn, userId, guildId);
|
if (VoiceCloseEventCodes.Disconnect === event.code) {
|
||||||
} else if (event.code === 4014) {
|
console.log("Couldn't reconnect :(");
|
||||||
conn.context.speaking = false;
|
return;
|
||||||
} else if (event.code === 4006) {
|
|
||||||
conn.context.speaking = false;
|
|
||||||
}
|
}
|
||||||
|
if (conn.context.reconnect >= 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
conn.context.reconnect++;
|
||||||
|
conn.resume = true;
|
||||||
|
connectWebSocket(conn, userId, guildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { VoiceOpcodes } from "../../deps.ts";
|
||||||
|
|
||||||
|
export enum ReceiveVoiceOpcodes {
|
||||||
|
/** Complete the websocket handshake. */
|
||||||
|
Ready = VoiceOpcodes.Ready,
|
||||||
|
/** Describe the session. */
|
||||||
|
SessionDescription = VoiceOpcodes.SessionDescription,
|
||||||
|
/** Indicate which users are speaking. */
|
||||||
|
Speaking = VoiceOpcodes.Speaking,
|
||||||
|
/** Sent to acknowledge a received client heartbeat. */
|
||||||
|
HeartbeatACK = VoiceOpcodes.HeartbeatACK,
|
||||||
|
/** Time to wait between sending heartbeats in milliseconds. */
|
||||||
|
Hello = VoiceOpcodes.Hello,
|
||||||
|
/** Acknowledge a successful session resume. */
|
||||||
|
Resumed = VoiceOpcodes.Resumed,
|
||||||
|
/** A client has disconnected from the voice channel */
|
||||||
|
ClientDisconnect = VoiceOpcodes.ClientDisconnect,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SendVoiceOpcodes {
|
||||||
|
/** Begin a voice websocket connection. */
|
||||||
|
Identify = VoiceOpcodes.Identify,
|
||||||
|
/** Select the voice protocol. */
|
||||||
|
SelectProtocol = VoiceOpcodes.SelectProtocol,
|
||||||
|
/** Keep the websocket connection alive. */
|
||||||
|
Heartbeat = VoiceOpcodes.Heartbeat,
|
||||||
|
/** Indicate which users are speaking. */
|
||||||
|
Speaking = VoiceOpcodes.Speaking,
|
||||||
|
/** Resume a connection. */
|
||||||
|
Resume = VoiceOpcodes.Resume,
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export async function* streamAsyncIterator<T>(stream: ReadableStream<T>) {
|
export async function* streamAsyncIterator(stream: ReadableStream) {
|
||||||
// Get a lock on the stream
|
// Get a lock on the stream
|
||||||
const reader = stream.getReader();
|
const reader = stream.getReader();
|
||||||
|
|
||||||
|
|
4
utils.ts
4
utils.ts
|
@ -1,6 +1,6 @@
|
||||||
import { ytdl } from "https://deno.land/x/ytdl_core@v0.1.1/mod.ts";
|
import { ytdl } from "https://deno.land/x/ytdl_core@v0.1.1/mod.ts";
|
||||||
import { Bot } from "https://deno.land/x/discordeno@17.0.1/bot.ts";
|
import { Bot } from "https://deno.land/x/discordeno@18.0.1/bot.ts";
|
||||||
import { connectToVoiceChannel } from "https://deno.land/x/discordeno@17.0.1/helpers/guilds/mod.ts";
|
import { connectToVoiceChannel } from "https://deno.land/x/discordeno@18.0.1/helpers/guilds/mod.ts";
|
||||||
import { configs } from "./configs.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, type BigString, type Embed, type InteractionCallbackData, type InteractionResponse } from "./deps.ts";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue