Compare commits
2 commits
e60d1772ba
...
ea57995b75
| Author | SHA1 | Date | |
|---|---|---|---|
| ea57995b75 | |||
| 277b25e451 |
3 changed files with 239 additions and 223 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -130,7 +130,7 @@ dist
|
||||||
.pnp.*
|
.pnp.*
|
||||||
lavalink/
|
lavalink/
|
||||||
Lavalink.jar
|
Lavalink.jar
|
||||||
settings.json# Devenv
|
# Devenv
|
||||||
.devenv*
|
.devenv*
|
||||||
devenv.local.nix
|
devenv.local.nix
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"requestChannels":{"777923126981558282":{"channelId":"1219764003421556816","messageId":"1296249229009752138"}}}
|
{"requestChannels":{"777923126981558282":{"channelId":"1334001448832335945","messageId":"1334034171164753973"}}}
|
||||||
444
src/index.ts
444
src/index.ts
|
|
@ -1,5 +1,5 @@
|
||||||
|
// Import discord.js
|
||||||
import {
|
import {
|
||||||
type APIEmbed,
|
|
||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
|
|
@ -8,36 +8,59 @@ import {
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
GatewayIntentBits,
|
GatewayIntentBits,
|
||||||
type Message,
|
type Message,
|
||||||
SlashCommandBuilder,
|
|
||||||
Interaction,
|
Interaction,
|
||||||
} from "npm:discord.js";
|
} from "discord.js";
|
||||||
|
|
||||||
import { Connectors, Track } from "shoukaku";
|
// Import shoukaku
|
||||||
|
import { Connectors } from "shoukaku";
|
||||||
|
|
||||||
|
// Import kazagumo
|
||||||
import {
|
import {
|
||||||
Kazagumo,
|
Kazagumo,
|
||||||
type KazagumoPlayer,
|
type KazagumoPlayer,
|
||||||
type KazagumoTrack,
|
type KazagumoTrack,
|
||||||
type Payload,
|
type Payload,
|
||||||
} from "npm:kazagumo";
|
} from "kazagumo";
|
||||||
|
|
||||||
import KazagumoPlugin from "npm:kazagumo-spotify";
|
// Import spotify and deezer plugins
|
||||||
import prettyMilliseconds from "npm:pretty-ms";
|
import KazagumoPlugin from "kazagumo-spotify";
|
||||||
|
import Deezer from "kazagumo-deezer";
|
||||||
|
|
||||||
|
// Import pretty-ms for better time formatting
|
||||||
|
import prettyMilliseconds from "pretty-ms";
|
||||||
|
|
||||||
|
// Import dotenv
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
|
||||||
|
// Enable writing and reading files
|
||||||
|
import { readFileSync, writeFileSync } from "fs";
|
||||||
|
|
||||||
|
//Import process
|
||||||
|
import process from "process";
|
||||||
|
|
||||||
|
// Set GatewayIntents
|
||||||
const { Guilds, GuildVoiceStates, GuildMessages, MessageContent } =
|
const { Guilds, GuildVoiceStates, GuildMessages, MessageContent } =
|
||||||
GatewayIntentBits;
|
GatewayIntentBits;
|
||||||
|
|
||||||
import * as dotenv from "npm:dotenv";
|
// Setup dotenv
|
||||||
import { readFileSync, writeFileSync } from "node:fs";
|
|
||||||
|
|
||||||
import process from "node:process";
|
|
||||||
import Deezer from "npm:kazagumo-deezer";
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
// Check if spotify is setup
|
||||||
if (!process.env.SPOTIFY_ID || !process.env.SPOTIFY_SECRET) {
|
if (!process.env.SPOTIFY_ID || !process.env.SPOTIFY_SECRET) {
|
||||||
throw "Spotify Credentials missing";
|
throw "Spotify Credentials missing";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define settings interface
|
||||||
|
interface requestChannels {
|
||||||
|
[guildId: string]: {
|
||||||
|
channelId: string;
|
||||||
|
messageId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
interface settings {
|
||||||
|
requestChannels: requestChannels;
|
||||||
|
}
|
||||||
|
// Initialize and load settings from file
|
||||||
let settings: settings;
|
let settings: settings;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -46,6 +69,7 @@ try {
|
||||||
settings = { requestChannels: {} }; // Init if no data found
|
settings = { requestChannels: {} }; // Init if no data found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup lavalink config
|
||||||
const Nodes = [
|
const Nodes = [
|
||||||
{
|
{
|
||||||
name: "lavalink",
|
name: "lavalink",
|
||||||
|
|
@ -55,19 +79,26 @@ const Nodes = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Setup discord client
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: [Guilds, GuildVoiceStates, GuildMessages, MessageContent],
|
intents: [Guilds, GuildVoiceStates, GuildMessages, MessageContent],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Setup kazagumo
|
||||||
const kazagumo = new Kazagumo(
|
const kazagumo = new Kazagumo(
|
||||||
{
|
{
|
||||||
|
// Set youtube as fallback search engine
|
||||||
defaultSearchEngine: "youtube",
|
defaultSearchEngine: "youtube",
|
||||||
|
|
||||||
|
// Setup support for sharding i guess? Only here cause the shoukaku example says its important
|
||||||
send: (guildId: string, payload: Payload) => {
|
send: (guildId: string, payload: Payload) => {
|
||||||
const guild = client.guilds.cache.get(guildId);
|
const guild = client.guilds.cache.get(guildId);
|
||||||
if (guild) guild.shard.send(payload);
|
if (guild) guild.shard.send(payload);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Setup plugins
|
||||||
plugins: [
|
plugins: [
|
||||||
new Deezer({playlistLimit:20}),
|
new Deezer(),
|
||||||
new KazagumoPlugin({
|
new KazagumoPlugin({
|
||||||
clientId: process.env.SPOTIFY_ID,
|
clientId: process.env.SPOTIFY_ID,
|
||||||
clientSecret: process.env.SPOTIFY_SECRET,
|
clientSecret: process.env.SPOTIFY_SECRET,
|
||||||
|
|
@ -82,32 +113,102 @@ const kazagumo = new Kazagumo(
|
||||||
Nodes
|
Nodes
|
||||||
);
|
);
|
||||||
|
|
||||||
interface requestChannels {
|
|
||||||
[guildId: string]: {
|
// Setup empty embed
|
||||||
channelId: string;
|
const emptyEmbed = new EmbedBuilder()
|
||||||
messageId: string;
|
.setAuthor({
|
||||||
};
|
name: "Moe",
|
||||||
}
|
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
||||||
interface settings {
|
})
|
||||||
requestChannels: requestChannels;
|
.setTitle("Nothing is being played right now")
|
||||||
}
|
.setDescription("Enter message to search")
|
||||||
|
.addFields(
|
||||||
|
{
|
||||||
|
name: "Author",
|
||||||
|
value: "None",
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Duration",
|
||||||
|
value: "NaN:NaN",
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.setColor("#ff0047");
|
||||||
|
// Setup buttons
|
||||||
|
const play = new ButtonBuilder()
|
||||||
|
.setCustomId("play")
|
||||||
|
.setLabel("Play/Pause")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("889943073793122355");
|
||||||
|
|
||||||
|
const stop = new ButtonBuilder()
|
||||||
|
.setCustomId("stop")
|
||||||
|
.setLabel("Stop Playing")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("889943074258694184");
|
||||||
|
|
||||||
|
const skip = new ButtonBuilder()
|
||||||
|
.setCustomId("skip")
|
||||||
|
.setLabel("Skip Song")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("889943074233516072");
|
||||||
|
|
||||||
|
const loop = new ButtonBuilder()
|
||||||
|
.setCustomId("loop")
|
||||||
|
.setLabel("Loop Song")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("889943073667289099");
|
||||||
|
|
||||||
|
const shuffle = new ButtonBuilder()
|
||||||
|
.setCustomId("shuffle")
|
||||||
|
.setLabel("Shuffle Queue")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("890325437962678352");
|
||||||
|
|
||||||
|
const seek = new ButtonBuilder()
|
||||||
|
.setCustomId("seek")
|
||||||
|
.setLabel("Seek Forward")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("890325511878889504");
|
||||||
|
|
||||||
|
const previous = new ButtonBuilder()
|
||||||
|
.setCustomId("previous")
|
||||||
|
.setLabel("Previous Song")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
.setEmoji("890325512071831562");
|
||||||
|
|
||||||
|
// Add buttons to action row
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||||
|
play,
|
||||||
|
stop,
|
||||||
|
skip,
|
||||||
|
loop
|
||||||
|
);
|
||||||
|
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||||
|
shuffle,
|
||||||
|
seek,
|
||||||
|
previous
|
||||||
|
);
|
||||||
|
|
||||||
client.on("ready", () => {
|
client.on("ready", () => {
|
||||||
// console.log(client)
|
|
||||||
console.log(`${client.user!.tag}·Ready!`);
|
console.log(`${client.user!.tag}·Ready!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
kazagumo.shoukaku.on("ready", (name: string) =>
|
kazagumo.shoukaku.on("ready", (name: string) =>
|
||||||
console.log(`Lavalink ${name}: Ready!`)
|
console.log(`Lavalink ${name}: Ready!`)
|
||||||
);
|
);
|
||||||
|
|
||||||
kazagumo.shoukaku.on("error", (name: string, error: Error) =>
|
kazagumo.shoukaku.on("error", (name: string, error: Error) =>
|
||||||
console.error(`Lavalink ${name}: Error Caught,`, error)
|
console.error(`Lavalink ${name}: Error Caught,`, error)
|
||||||
);
|
);
|
||||||
|
|
||||||
kazagumo.shoukaku.on("close", (name: string, code: unknown, reason: unknown) =>
|
kazagumo.shoukaku.on("close", (name: string, code: unknown, reason: unknown) =>
|
||||||
console.warn(
|
console.warn(
|
||||||
`Lavalink ${name}: Closed, Code ${code}, Reason ${reason || "No reason"}`
|
`Lavalink ${name}: Closed, Code ${code}, Reason ${reason || "No reason"}`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
kazagumo.shoukaku.on("debug", (name: string, info: string) =>
|
kazagumo.shoukaku.on("debug", (name: string, info: string) =>
|
||||||
console.debug(`Lavalink ${name}: Debug,`, info)
|
console.debug(`Lavalink ${name}: Debug,`, info)
|
||||||
);
|
);
|
||||||
|
|
@ -118,156 +219,119 @@ kazagumo.shoukaku.on("disconnect", (name: string, count: number) => {
|
||||||
console.warn(`Lavalink ${name}: Disconnected`);
|
console.warn(`Lavalink ${name}: Disconnected`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
kazagumo.on("playerStart", (player: KazagumoPlayer, track: KazagumoTrack) => {
|
kazagumo.on("playerStart", (player: KazagumoPlayer, track: KazagumoTrack) => {
|
||||||
|
// Exit if player is not initialized yet
|
||||||
if (!player.textId) return;
|
if (!player.textId) return;
|
||||||
const channel = client.channels.cache.get(player.textId);
|
const channel = client.channels.cache.get(player.textId);
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
if (channel.type === ChannelType.GuildText) {
|
if (channel.type === ChannelType.GuildText) {
|
||||||
channel
|
// TODO:Also update player embed
|
||||||
.send({
|
channel.send({
|
||||||
content: `Now playing **${track.title}** by **${track.author}**`,
|
content: `Now playing **${track.title}** by **${track.author}**`,
|
||||||
})
|
})
|
||||||
.then((x: any) => {
|
.then((x: any) => {
|
||||||
//TODO: Use embed message instead
|
|
||||||
player.data.set("message", x);
|
|
||||||
setTimeout(() => x.delete(), 3000);
|
setTimeout(() => x.delete(), 3000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Called when track ends
|
||||||
kazagumo.on("playerEnd", (player: KazagumoPlayer) => {
|
kazagumo.on("playerEnd", (player: KazagumoPlayer) => {
|
||||||
//TODO: Use embed message instead
|
// Replace old embed with embed of next track
|
||||||
|
let currentTrack = player.queue[0]
|
||||||
|
|
||||||
|
let track_author: string;
|
||||||
|
if (currentTrack.author) {
|
||||||
|
track_author = currentTrack.author;
|
||||||
|
} else {
|
||||||
|
track_author = "";
|
||||||
|
}
|
||||||
|
let track_duration: string;
|
||||||
|
if (currentTrack.length) {
|
||||||
|
track_duration = prettyMilliseconds(currentTrack.length);
|
||||||
|
} else {
|
||||||
|
track_duration = "NaN:NaN";
|
||||||
|
}
|
||||||
|
let track_thumbnail: string;
|
||||||
|
if (currentTrack.thumbnail) {
|
||||||
|
track_thumbnail = currentTrack.thumbnail.toString();
|
||||||
|
} else {
|
||||||
|
track_thumbnail = "NaN:NaN";
|
||||||
|
}
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setAuthor({
|
.setAuthor({
|
||||||
name: "Moe",
|
name: "Now playing",
|
||||||
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
||||||
})
|
})
|
||||||
.setTitle("Nothing is being played right now")
|
.setTitle(
|
||||||
.setDescription("Enter message to search")
|
player.queue.length > 0
|
||||||
|
? `Playing ${player.queue.length} from ${player.data.get("playlist")}`
|
||||||
|
: `Playing ${currentTrack.title}`
|
||||||
|
)
|
||||||
|
.setDescription(`[${currentTrack.title}](${currentTrack.uri})`)
|
||||||
.addFields(
|
.addFields(
|
||||||
{
|
{
|
||||||
name: "Author",
|
name: "Author",
|
||||||
value: "None",
|
value: track_author,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Duration",
|
name: "Duration",
|
||||||
value: "NaN:NaN",
|
value: track_duration,
|
||||||
inline: true,
|
inline: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.setThumbnail(track_thumbnail)
|
||||||
.setColor("#ff0047");
|
.setColor("#ff0047");
|
||||||
|
player.data.get("message")?.edit({ embeds: [embed] });
|
||||||
player.data.get("message")?.edit({ embed: [embed] });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Called when disconnecting
|
||||||
kazagumo.on("playerEmpty", (player: KazagumoPlayer) => {
|
kazagumo.on("playerEmpty", (player: KazagumoPlayer) => {
|
||||||
|
|
||||||
|
// Return if player is not initialized
|
||||||
if (!player.textId) return;
|
if (!player.textId) return;
|
||||||
const channel = client.channels.cache.get(player.textId);
|
const channel = client.channels.cache.get(player.textId);
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
if (channel.type === ChannelType.GuildText) {
|
if (channel.type === ChannelType.GuildText) {
|
||||||
//TODO: Use embed message instead
|
|
||||||
channel
|
// Replace old embed with empty one
|
||||||
.send({ content: "Destroyed player due to inactivity." })
|
// also needed here as playerEnd doesn't get called if only one song is in the queue
|
||||||
|
player.data.get("message")?.edit({ embeds: [emptyEmbed] });
|
||||||
|
|
||||||
|
// Send message before disconnecting
|
||||||
|
channel.send({ content: "Destroyed player due to inactivity." })
|
||||||
.then((x: any) => {
|
.then((x: any) => {
|
||||||
player.data.set("message", x);
|
|
||||||
setTimeout(() => x.delete(), 3000);
|
setTimeout(() => x.delete(), 3000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
player.destroy();
|
player.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Better command handling
|
||||||
|
|
||||||
|
// Called when a new message is send
|
||||||
client.on("messageCreate", async (msg: Message) => {
|
client.on("messageCreate", async (msg: Message) => {
|
||||||
console.log(msg.content);
|
if (msg.author.bot) return; // Ignore bot messages
|
||||||
if (msg.author.bot) return;
|
if (!msg.guild) return; // Ignore dms
|
||||||
if (!msg.guild) return;
|
if (!msg.member) return; // Ignore Interactions
|
||||||
if (!msg.member) return;
|
if (msg.channel.type !== ChannelType.GuildText) return; // Only listen in text channels
|
||||||
if (msg.channel.type !== ChannelType.GuildText) return;
|
|
||||||
|
// If message contains command prefix
|
||||||
if (msg.content.startsWith(".")) {
|
if (msg.content.startsWith(".")) {
|
||||||
|
// Split prefix for easier comparison
|
||||||
let cmd = msg.content.split(".")[1];
|
let cmd = msg.content.split(".")[1];
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
||||||
|
// Initialize channel on server
|
||||||
case "init":
|
case "init":
|
||||||
if (msg.guildId && msg.channelId) {
|
if (msg.guildId && msg.channelId) {
|
||||||
if (!settings.requestChannels[msg.guildId]) {
|
if (!settings.requestChannels[msg.guildId]) {
|
||||||
await msg.delete();
|
await msg.delete();
|
||||||
|
|
||||||
const play = new ButtonBuilder()
|
|
||||||
.setCustomId("play")
|
|
||||||
.setLabel("Play/Pause")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943073793122355");
|
|
||||||
|
|
||||||
const stop = new ButtonBuilder()
|
|
||||||
.setCustomId("stop")
|
|
||||||
.setLabel("Stop Playing")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943074258694184");
|
|
||||||
|
|
||||||
const skip = new ButtonBuilder()
|
|
||||||
.setCustomId("skip")
|
|
||||||
.setLabel("Skip Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943074233516072");
|
|
||||||
|
|
||||||
const loop = new ButtonBuilder()
|
|
||||||
.setCustomId("loop")
|
|
||||||
.setLabel("Loop Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943073667289099");
|
|
||||||
|
|
||||||
const shuffle = new ButtonBuilder()
|
|
||||||
.setCustomId("shuffle")
|
|
||||||
.setLabel("Shuffle Queue")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325437962678352");
|
|
||||||
|
|
||||||
const seek = new ButtonBuilder()
|
|
||||||
.setCustomId("seek")
|
|
||||||
.setLabel("Seek Forward")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325511878889504");
|
|
||||||
|
|
||||||
const previous = new ButtonBuilder()
|
|
||||||
.setCustomId("previous")
|
|
||||||
.setLabel("Previous Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325512071831562");
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
||||||
play,
|
|
||||||
stop,
|
|
||||||
skip,
|
|
||||||
loop
|
|
||||||
);
|
|
||||||
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
||||||
shuffle,
|
|
||||||
seek,
|
|
||||||
previous
|
|
||||||
);
|
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
|
||||||
.setAuthor({
|
|
||||||
name: "Moe",
|
|
||||||
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
|
||||||
})
|
|
||||||
.setTitle("Nothing is being played right now")
|
|
||||||
.setDescription("Enter message to search")
|
|
||||||
.addFields(
|
|
||||||
{
|
|
||||||
name: "Author",
|
|
||||||
value: "None",
|
|
||||||
inline: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Duration",
|
|
||||||
value: "NaN:NaN",
|
|
||||||
inline: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.setColor("#ff0047");
|
|
||||||
|
|
||||||
const response = await msg.channel.send({
|
const response = await msg.channel.send({
|
||||||
embeds: [embed],
|
embeds: [emptyEmbed],
|
||||||
components: [row, row2],
|
components: [row, row2],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -294,29 +358,26 @@ client.on("messageCreate", async (msg: Message) => {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.channel.name === "moe-song-requests") {
|
// Return if guild has not setup bot yet
|
||||||
|
if (!Object.keys(settings.requestChannels).includes(msg.guild.id)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// If the msg channel is the request channel, use message as search query
|
||||||
|
if (msg.channel.id === settings.requestChannels[msg.guild.id].channelId) {
|
||||||
let controls;
|
let controls;
|
||||||
if (!settings.requestChannels[msg.guild.id]) {
|
|
||||||
let answer = await msg.reply("Use .init first");
|
|
||||||
console.log(answer);
|
|
||||||
setTimeout(() => msg.delete(), 3000);
|
|
||||||
setTimeout(() => answer.delete(), 3000);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
let channelId = settings.requestChannels[msg.guild.id].channelId;
|
let channelId = settings.requestChannels[msg.guild.id].channelId;
|
||||||
let messageId = settings.requestChannels[msg.guild.id].messageId;
|
let messageId = settings.requestChannels[msg.guild.id].messageId;
|
||||||
let channel = msg.guild.channels.cache.get(channelId);
|
let requestChannel = msg.guild.channels.cache.get(channelId);
|
||||||
if (channel && channel.type === ChannelType.GuildText) {
|
if (requestChannel && requestChannel.type === ChannelType.GuildText) {
|
||||||
controls = await channel.messages.fetch(messageId);
|
controls = await requestChannel.messages.fetch(messageId);
|
||||||
}
|
}
|
||||||
// let controls = msg.channel.guild
|
// let controls = msg.channel.guild
|
||||||
// get(requestChannels[msg.guild.id]);
|
// get(requestChannels[msg.guild.id]);
|
||||||
// client.channels.fetch(requestChannels[msg.guild.id])
|
// client.channels.fetch(requestChannels[msg.guild.id])
|
||||||
}
|
|
||||||
const query = msg.content;
|
const query = msg.content;
|
||||||
|
|
||||||
const { channel } = msg.member.voice;
|
let voiceChannel = msg.member.voice.channel;
|
||||||
if (!channel) {
|
if (!voiceChannel) {
|
||||||
let answer = await msg.reply(
|
let answer = await msg.reply(
|
||||||
"You need to be in a voice channel to use this command!"
|
"You need to be in a voice channel to use this command!"
|
||||||
);
|
);
|
||||||
|
|
@ -328,19 +389,15 @@ client.on("messageCreate", async (msg: Message) => {
|
||||||
const player = await kazagumo.createPlayer({
|
const player = await kazagumo.createPlayer({
|
||||||
guildId: msg.guild.id,
|
guildId: msg.guild.id,
|
||||||
textId: msg.channel.id,
|
textId: msg.channel.id,
|
||||||
voiceId: channel.id,
|
voiceId: voiceChannel.id,
|
||||||
volume: 40,
|
volume: 40,
|
||||||
});
|
});
|
||||||
player.data.set("message", controls);
|
player.data.set("message", controls);
|
||||||
|
|
||||||
console.log("Player created, Searching with deezer");
|
let result = await kazagumo.search(query, { requester: msg.author, engine: "deezer" })
|
||||||
let result = await kazagumo.search(query, { requester: msg.author, engine: "deezer"})
|
|
||||||
console.log(result.tracks);
|
|
||||||
if (result.tracks.length === 0) {
|
if (result.tracks.length === 0) {
|
||||||
console.log("Searching with youtube");
|
result = await kazagumo.search(query, { requester: msg.author })
|
||||||
result = await kazagumo.search(query, { requester: msg.author})
|
|
||||||
if (result.tracks.length === 0) {
|
if (result.tracks.length === 0) {
|
||||||
console.log("no yt result found")
|
|
||||||
let answer = await msg.reply("No results found!");
|
let answer = await msg.reply("No results found!");
|
||||||
setTimeout(() => answer.delete(), 3000);
|
setTimeout(() => answer.delete(), 3000);
|
||||||
return;
|
return;
|
||||||
|
|
@ -351,60 +408,6 @@ client.on("messageCreate", async (msg: Message) => {
|
||||||
for (const track of result.tracks) player.queue.add(track);
|
for (const track of result.tracks) player.queue.add(track);
|
||||||
else player.queue.add(result.tracks[0]);
|
else player.queue.add(result.tracks[0]);
|
||||||
|
|
||||||
const play = new ButtonBuilder()
|
|
||||||
.setCustomId("play")
|
|
||||||
.setLabel("Play/Pause")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943073793122355");
|
|
||||||
|
|
||||||
const stop = new ButtonBuilder()
|
|
||||||
.setCustomId("stop")
|
|
||||||
.setLabel("Stop Playing")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943074258694184");
|
|
||||||
|
|
||||||
const skip = new ButtonBuilder()
|
|
||||||
.setCustomId("skip")
|
|
||||||
.setLabel("Skip Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943074233516072");
|
|
||||||
|
|
||||||
const loop = new ButtonBuilder()
|
|
||||||
.setCustomId("loop")
|
|
||||||
.setLabel("Loop Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("889943073667289099");
|
|
||||||
|
|
||||||
const shuffle = new ButtonBuilder()
|
|
||||||
.setCustomId("shuffle")
|
|
||||||
.setLabel("Shuffle Queue")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325437962678352");
|
|
||||||
|
|
||||||
const seek = new ButtonBuilder()
|
|
||||||
.setCustomId("seek")
|
|
||||||
.setLabel("Seek Forward")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325511878889504");
|
|
||||||
|
|
||||||
const previous = new ButtonBuilder()
|
|
||||||
.setCustomId("previous")
|
|
||||||
.setLabel("Previous Song")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
.setEmoji("890325512071831562");
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
||||||
play,
|
|
||||||
stop,
|
|
||||||
skip,
|
|
||||||
loop
|
|
||||||
);
|
|
||||||
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
||||||
shuffle,
|
|
||||||
seek,
|
|
||||||
previous
|
|
||||||
);
|
|
||||||
|
|
||||||
let track_author: string;
|
let track_author: string;
|
||||||
if (result.tracks[0].author) {
|
if (result.tracks[0].author) {
|
||||||
track_author = result.tracks[0].author;
|
track_author = result.tracks[0].author;
|
||||||
|
|
@ -448,11 +451,11 @@ client.on("messageCreate", async (msg: Message) => {
|
||||||
)
|
)
|
||||||
.setThumbnail(track_thumbnail)
|
.setThumbnail(track_thumbnail)
|
||||||
.setColor("#ff0047");
|
.setColor("#ff0047");
|
||||||
|
if (result.type === "PLAYLIST") player.data.set("playlist", result.playlistName);
|
||||||
if (!player.playing && !player.paused) player.play();
|
if (!player.playing && !player.paused) player.play();
|
||||||
|
|
||||||
if (controls) {
|
if (controls) {
|
||||||
const response = controls.edit({
|
controls.edit({
|
||||||
embeds: [embed],
|
embeds: [embed],
|
||||||
components: [row, row2],
|
components: [row, row2],
|
||||||
});
|
});
|
||||||
|
|
@ -464,7 +467,6 @@ client.on("messageCreate", async (msg: Message) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("interactionCreate", async (interaction: Interaction) => {
|
client.on("interactionCreate", async (interaction: Interaction) => {
|
||||||
console.log(interaction.id);
|
|
||||||
if (interaction.isButton()) {
|
if (interaction.isButton()) {
|
||||||
const guild = client.guilds.cache.get(interaction.guildId!);
|
const guild = client.guilds.cache.get(interaction.guildId!);
|
||||||
const member = guild?.members.cache.get(interaction.member!.user.id);
|
const member = guild?.members.cache.get(interaction.member!.user.id);
|
||||||
|
|
@ -477,69 +479,83 @@ client.on("interactionCreate", async (interaction: Interaction) => {
|
||||||
// volume: 40
|
// volume: 40
|
||||||
// })
|
// })
|
||||||
switch (interaction.customId) {
|
switch (interaction.customId) {
|
||||||
|
// Toggle Play/Pause
|
||||||
case "play":
|
case "play":
|
||||||
player.pause(!player.paused);
|
player.pause(!player.paused);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Toggled Pause",
|
content: "Toggled Pause",
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Stop playing and disconnect
|
||||||
case "stop":
|
case "stop":
|
||||||
// player.disconnect();
|
|
||||||
|
player.data.get("message")?.edit({ embeds: [emptyEmbed] });
|
||||||
player.destroy();
|
player.destroy();
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Stopped Playing",
|
content: "Stopped Playing",
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip currently playing song
|
||||||
case "skip":
|
case "skip":
|
||||||
player.skip();
|
player.skip();
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Skipped Song",
|
content: "Skipped Song",
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip back to previously playing song
|
||||||
|
case "previous":
|
||||||
|
let track = player.getPrevious(true);
|
||||||
|
await interaction.reply({
|
||||||
|
flags: "Ephemeral",
|
||||||
|
content: "Queued previous song",
|
||||||
|
});
|
||||||
|
player.play(track);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Enable/Disable Looping
|
||||||
case "loop":
|
case "loop":
|
||||||
if (player.loop != "none") {
|
if (player.loop != "none") {
|
||||||
player.setLoop("none");
|
player.setLoop("none");
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Disabled Looping",
|
content: "Disabled Looping",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
player.setLoop("track");
|
player.setLoop("track");
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Started Looping",
|
content: "Started Looping",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Shuffle current queue
|
||||||
case "shuffle":
|
case "shuffle":
|
||||||
player.queue.shuffle();
|
player.queue.shuffle();
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Shuffled Queue",
|
content: "Shuffled Queue",
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO: Skip forward 5 seconds
|
||||||
case "seek":
|
case "seek":
|
||||||
// let position = player.position / 1000;
|
// let position = player.position / 1000;
|
||||||
// position = position | 0;
|
// position = position | 0;
|
||||||
// console.log(position);
|
// console.log(position);
|
||||||
// player.seek(position + 5);
|
// player.seek(position + 5);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
ephemeral: true,
|
flags: "Ephemeral",
|
||||||
content: "Does not work :pensive:",
|
content: "Does not work :pensive:",
|
||||||
// content: "Skipped 5s forward",
|
// content: "Skipped 5s forward",
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "previous":
|
|
||||||
let track = player.getPrevious();
|
|
||||||
await interaction.reply({
|
|
||||||
ephemeral: true,
|
|
||||||
content: "Queued previous song",
|
|
||||||
});
|
|
||||||
player.play(track[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue