basic slash commands bot
This commit is contained in:
parent
5239e5f9cc
commit
b97e8e61fc
11 changed files with 239 additions and 106 deletions
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"printWidth": 200,
|
||||
"trailingComma": "none",
|
||||
"singleQuote": false,
|
||||
"tabWidth": 4,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const config = {
|
||||
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
};
|
||||
};
|
||||
|
|
233
example/index.ts
233
example/index.ts
|
@ -1,79 +1,200 @@
|
|||
import { Client, Message } from "discord.js";
|
||||
import { Player, Queue } from "../src/index";
|
||||
import { Client, GuildMember, Message, TextChannel } from "discord.js";
|
||||
import { Player, Queue, Track } from "../src/index";
|
||||
import { config } from "./config";
|
||||
// use this in prod.
|
||||
// import { Player, Queue } from "discord-player";
|
||||
|
||||
const client = new Client({
|
||||
intents: ['GUILD_VOICE_STATES', 'GUILD_MESSAGES', 'GUILDS']
|
||||
intents: ["GUILD_VOICE_STATES", "GUILD_MESSAGES", "GUILDS"]
|
||||
});
|
||||
|
||||
client.on("ready", () => {
|
||||
console.log("Bot is online!");
|
||||
client.user.setActivity({
|
||||
name: "🎶 | Music Time",
|
||||
type: "LISTENING"
|
||||
});
|
||||
});
|
||||
client.on("error", console.error);
|
||||
client.on("warn", console.warn);
|
||||
|
||||
// instantiate the player
|
||||
const player = new Player(client);
|
||||
|
||||
player.on("error", console.error);
|
||||
|
||||
player.on("trackStart", (queue, track) => {
|
||||
const guildQueue = queue as Queue<Message>;
|
||||
guildQueue.metadata.channel.send(`🎶 | Now playing: **${track.title}** in **${guildQueue.connection.channel.name}**!`);
|
||||
const guildQueue = queue as Queue<TextChannel>;
|
||||
guildQueue.metadata.send(`🎶 | Started playing: **${track.title}** in **${guildQueue.connection.channel.name}**!`);
|
||||
});
|
||||
|
||||
client.on("ready", () => console.log("Bot is online!"));
|
||||
player.on("trackAdd", (queue, track) => {
|
||||
const guildQueue = queue as Queue<TextChannel>;
|
||||
guildQueue.metadata.send(`🎶 | Track **${track.title}** queued!`);
|
||||
});
|
||||
|
||||
client.on("message", async message => {
|
||||
if (!client.application.owner) await client.application.fetch();
|
||||
if (message.author.id !== client.application.owner.id) return;
|
||||
client.on("message", async (message) => {
|
||||
if (message.author.bot || !message.guild) return;
|
||||
if (!client.application?.owner) await client.application?.fetch();
|
||||
|
||||
if (message.content.startsWith("!np") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
return void message.channel.send(`Now Playing: **${conn.current.title}** (Played **${Math.floor(conn.connection.streamTime / 1000)} seconds**)`);
|
||||
if (message.content === "!deploy" && message.author.id === client.application?.owner?.id) {
|
||||
await message.guild.commands.set([
|
||||
{
|
||||
name: "play",
|
||||
description: "Plays a song from youtube",
|
||||
options: [
|
||||
{
|
||||
name: "query",
|
||||
type: "STRING",
|
||||
description: "The song you want to play",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "volume",
|
||||
description: "Sets music volume",
|
||||
options: [
|
||||
{
|
||||
name: "amount",
|
||||
type: "INTEGER",
|
||||
description: "The volume amount to set (0-100)",
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "skip",
|
||||
description: "Skip to the current song"
|
||||
},
|
||||
{
|
||||
name: "queue",
|
||||
description: "See the queue"
|
||||
},
|
||||
{
|
||||
name: "pause",
|
||||
description: "Pause the current song"
|
||||
},
|
||||
{
|
||||
name: "resume",
|
||||
description: "Resume the current song"
|
||||
},
|
||||
{
|
||||
name: "stop",
|
||||
description: "Stop the player"
|
||||
},
|
||||
{
|
||||
name: "np",
|
||||
description: "Now Playing"
|
||||
}
|
||||
]);
|
||||
|
||||
await message.reply("Deployed!");
|
||||
}
|
||||
});
|
||||
|
||||
client.on("interaction", async (interaction) => {
|
||||
if (!interaction.isCommand() || !interaction.guildID) return;
|
||||
|
||||
if (!(interaction.member instanceof GuildMember) || !interaction.member.voice.channel) {
|
||||
return void interaction.reply({ content: "You are not in a voice channel!", ephemeral: true });
|
||||
}
|
||||
|
||||
if (message.content.startsWith("!pause") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
conn.setPaused(true);
|
||||
return void message.channel.send("Paused!");
|
||||
if (interaction.guild.me.voice.channelID && interaction.member.voice.channelID !== interaction.guild.me.voice.channelID) {
|
||||
return void interaction.reply({ content: "You are not in my voice channel!", ephemeral: true });
|
||||
}
|
||||
|
||||
if (message.content.startsWith("!resume") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
conn.setPaused(false);
|
||||
return void message.channel.send("Resumed!");
|
||||
}
|
||||
if (interaction.commandName === "play") {
|
||||
await interaction.defer();
|
||||
|
||||
if (message.content.startsWith("!skip") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
conn.skip();
|
||||
return void message.channel.send("Done!");
|
||||
}
|
||||
const query = interaction.options.get("query")!.value! as string;
|
||||
const searchResult = (await player.search(query, interaction.user).catch(() => [])) as Track[];
|
||||
if (!searchResult.length) return void interaction.followUp({ content: "No results were found!" });
|
||||
|
||||
if (message.content.startsWith("!queue") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
return void message.channel.send({ content: conn.toString(), split: true });
|
||||
}
|
||||
|
||||
if (message.content.startsWith("!vol") && message.guild.me.voice.channelID) {
|
||||
const conn = player.getQueue(message.guild.id);
|
||||
if (!conn) return;
|
||||
conn.connection.setVolume(parseInt(message.content.slice(4).trim()));
|
||||
return void message.channel.send("Volume changed!");
|
||||
}
|
||||
|
||||
if (message.content.startsWith("!p") && message.member.voice.channelID) {
|
||||
const queue = player.createQueue<Message>(message.guild, {
|
||||
metadata: message
|
||||
const queue = await player.createQueue(interaction.guild, {
|
||||
metadata: interaction.channel
|
||||
});
|
||||
const song = await player.search(message.content.slice(2).trim(), message.author).then(x => x[0]);
|
||||
queue.addTrack(song);
|
||||
|
||||
if (!queue.connection) {
|
||||
queue.connect(message.member.voice.channel)
|
||||
.then(async q => {
|
||||
await q.play();
|
||||
});
|
||||
} else {
|
||||
message.channel.send(`🎶 | Queued: **${song.title}**!`);
|
||||
try {
|
||||
if (!queue.connection) await queue.connect(interaction.member.voice.channel);
|
||||
} catch {
|
||||
void player.deleteQueue(interaction.guildID);
|
||||
return void interaction.followUp({ content: "Could not join your voice channel!" });
|
||||
}
|
||||
|
||||
await interaction.followUp({ content: "⏱ | Loading your track..." });
|
||||
await queue.play(searchResult[0]);
|
||||
} else if (interaction.commandName === "volume") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
const vol = interaction.options.get("amount");
|
||||
if (!vol) return void interaction.followUp({ content: `🎧 | Current volume is **${queue.volume}**%!` });
|
||||
if ((vol.value as number) < 0 || (vol.value as number) > 100) return void interaction.followUp({ content: "❌ | Volume range must be 0-100" });
|
||||
const success = queue.setVolume(vol.value as number);
|
||||
return void interaction.followUp({
|
||||
content: success ? `✅ | Volume set to **${vol.value}%**!` : "❌ | Something went wrong!"
|
||||
});
|
||||
} else if (interaction.commandName === "skip") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
const currentTrack = queue.current;
|
||||
const success = queue.skip();
|
||||
return void interaction.followUp({
|
||||
content: success ? `✅ | Skipped **${currentTrack}**!` : "❌ | Something went wrong!"
|
||||
});
|
||||
} else if (interaction.commandName === "queue") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
const currentTrack = queue.current;
|
||||
const tracks = queue.tracks
|
||||
.slice(0, 10)
|
||||
.map((m, i) => {
|
||||
return `${i + 1}. **${m.title}**`;
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
return void interaction.followUp({
|
||||
embeds: [
|
||||
{
|
||||
title: "Server Queue",
|
||||
description: `${tracks}${queue.tracks.length > tracks.length ? `...${queue.tracks.length - tracks.length} more tracks` : ""}`,
|
||||
color: 0xff0000,
|
||||
fields: [{ name: "Now Playing", value: `🎶 | **${currentTrack.title}**` }]
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (interaction.commandName === "pause") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
const success = queue.setPaused(true);
|
||||
return void interaction.followUp({ content: success ? "⏸ | Paused!" : "❌ | Something went wrong!" });
|
||||
} else if (interaction.commandName === "resume") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
const success = queue.setPaused(false);
|
||||
return void interaction.followUp({ content: success ? "▶ | Resumed!" : "❌ | Something went wrong!" });
|
||||
} else if (interaction.commandName === "stop") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
queue.destroy();
|
||||
return void interaction.followUp({ content: "🛑 | Stopped the player!" });
|
||||
} else if (interaction.commandName === "np") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||
return void interaction.followUp({ content: `🎶 | Current song: **${queue.current.title}**!` });
|
||||
} else {
|
||||
interaction.reply({
|
||||
content: "Unknown command!",
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
client.login(config.token);
|
||||
client.login(config.token);
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
],
|
||||
"scripts": {
|
||||
"test": "cd example && ts-node index.ts",
|
||||
"build": "tsc",
|
||||
"format": "prettier --write \"src/**/*.ts\"",
|
||||
"build": "rimraf lib && tsc",
|
||||
"format": "prettier --write \"src/**/*.ts\" \"example/**/*.ts\"",
|
||||
"lint": "tslint -p tsconfig.json",
|
||||
"docs": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json",
|
||||
"docs:test": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml"
|
||||
|
@ -68,10 +68,11 @@
|
|||
"@types/node": "^14.14.41",
|
||||
"@types/ws": "^7.4.1",
|
||||
"discord-api-types": "^0.18.1",
|
||||
"discord.js": "^13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10",
|
||||
"discord.js": "^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7",
|
||||
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
||||
"jsdoc-babel": "^0.5.0",
|
||||
"prettier": "^2.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
|
|
|
@ -31,6 +31,12 @@ class DiscordPlayer extends EventEmitter<PlayerEvents> {
|
|||
return this.queues.get(guild) as Queue<T>;
|
||||
}
|
||||
|
||||
deleteQueue<T = unknown>(guild: Snowflake) {
|
||||
const prev = this.getQueue<T>(guild);
|
||||
this.queues.delete(guild);
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search tracks
|
||||
* @param {string|Track} query The search query
|
||||
|
|
|
@ -45,8 +45,7 @@ class Queue<T = unknown> {
|
|||
}
|
||||
|
||||
async connect(channel: StageChannel | VoiceChannel) {
|
||||
if (!["stage", "voice"].includes(channel?.type))
|
||||
throw new TypeError(`Channel type must be voice or stage, got ${channel?.type}!`);
|
||||
if (!["stage", "voice"].includes(channel?.type)) throw new TypeError(`Channel type must be voice or stage, got ${channel?.type}!`);
|
||||
const connection = await this.player.voiceUtils.connect(channel);
|
||||
this.connection = connection;
|
||||
|
||||
|
@ -69,6 +68,7 @@ class Queue<T = unknown> {
|
|||
|
||||
addTrack(track: Track) {
|
||||
this.addTracks([track]);
|
||||
this.player.emit("trackAdd", this, track);
|
||||
}
|
||||
|
||||
addTracks(tracks: Track[]) {
|
||||
|
@ -86,12 +86,21 @@ class Queue<T = unknown> {
|
|||
this.connection.audioResource.encoder.setBitrate(bitrate);
|
||||
}
|
||||
|
||||
setVolume(amount: number) {
|
||||
if (!this.connection) return false;
|
||||
return this.connection.setVolume(amount);
|
||||
}
|
||||
|
||||
get volume() {
|
||||
if (!this.connection) return 100;
|
||||
return this.connection.volume;
|
||||
}
|
||||
|
||||
async play(src?: Track, options: PlayOptions = {}) {
|
||||
if (!this.connection || !this.connection.voiceConnection)
|
||||
throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
||||
if (!this.connection || !this.connection.voiceConnection) throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
||||
if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src);
|
||||
const track = options.filtersUpdate ? this.current : src ?? this.tracks.shift();
|
||||
if (!track) return;
|
||||
|
||||
let stream;
|
||||
if (["youtube", "spotify"].includes(track.raw.source)) {
|
||||
stream = ytdl(track.raw.source === "spotify" ? track.raw.engine : track.url, {
|
||||
|
@ -102,18 +111,13 @@ class Queue<T = unknown> {
|
|||
seek: options.seek
|
||||
});
|
||||
} else {
|
||||
stream = ytdl.arbitraryStream(
|
||||
track.raw.source === "soundcloud"
|
||||
? await track.raw.engine.downloadProgressive()
|
||||
: (track.raw.engine as string),
|
||||
{
|
||||
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
||||
opusEncoded: false,
|
||||
fmt: "s16le",
|
||||
encoderArgs: options.encoderArgs ?? [],
|
||||
seek: options.seek
|
||||
}
|
||||
);
|
||||
stream = ytdl.arbitraryStream(track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : (track.raw.engine as string), {
|
||||
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
||||
opusEncoded: false,
|
||||
fmt: "s16le",
|
||||
encoderArgs: options.encoderArgs ?? [],
|
||||
seek: options.seek
|
||||
});
|
||||
}
|
||||
|
||||
const resource: AudioResource<Track> = this.connection.createStream(stream, {
|
||||
|
@ -124,12 +128,12 @@ class Queue<T = unknown> {
|
|||
const dispatcher = await this.connection.playStream(resource);
|
||||
dispatcher.setVolume(this.options.initialVolume);
|
||||
|
||||
dispatcher.on("start", () => {
|
||||
dispatcher.once("start", () => {
|
||||
this.playing = true;
|
||||
if (!options.filtersUpdate) this.player.emit("trackStart", this, this.current);
|
||||
});
|
||||
|
||||
dispatcher.on("finish", () => {
|
||||
dispatcher.once("finish", () => {
|
||||
this.playing = false;
|
||||
if (options.filtersUpdate) return;
|
||||
|
||||
|
@ -138,9 +142,12 @@ class Queue<T = unknown> {
|
|||
this.player.emit("queueEnd", this);
|
||||
} else {
|
||||
const nextTrack = this.tracks.shift();
|
||||
this.play(nextTrack);
|
||||
this.play(nextTrack, { immediate: true });
|
||||
}
|
||||
});
|
||||
|
||||
dispatcher.on("error", (e) => this.player.emit("error", this, e));
|
||||
dispatcher.on("debug", (msg) => this.player.emit("debug", this, msg));
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
|
|
|
@ -51,16 +51,11 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
}
|
||||
} else if (newState.status === VoiceConnectionStatus.Destroyed) {
|
||||
this.end();
|
||||
} else if (
|
||||
!this.connectPromise &&
|
||||
(newState.status === VoiceConnectionStatus.Connecting ||
|
||||
newState.status === VoiceConnectionStatus.Signalling)
|
||||
) {
|
||||
} else if (!this.connectPromise && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) {
|
||||
this.connectPromise = entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000)
|
||||
.then(() => undefined)
|
||||
.catch(() => {
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)
|
||||
this.voiceConnection.destroy();
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed) this.voiceConnection.destroy();
|
||||
})
|
||||
.finally(() => (this.connectPromise = undefined));
|
||||
}
|
||||
|
@ -140,8 +135,7 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
async playStream(resource: AudioResource<Track> = this.audioResource) {
|
||||
if (!resource) throw new PlayerError("Audio resource is not available!");
|
||||
if (!this.audioResource) this.audioResource = resource;
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready)
|
||||
await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
||||
this.audioPlayer.play(resource);
|
||||
|
||||
return this;
|
||||
|
@ -155,6 +149,12 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
return true;
|
||||
}
|
||||
|
||||
get volume() {
|
||||
if (!this.audioResource || !this.audioResource.volume) return 100;
|
||||
const currentVol = this.audioResource.volume.volume;
|
||||
return Math.round(Math.pow(currentVol, 1 / 1.660964) * 200);
|
||||
}
|
||||
|
||||
get streamTime() {
|
||||
if (!this.audioResource) return 0;
|
||||
return this.audioResource.playbackDuration;
|
||||
|
|
|
@ -119,7 +119,8 @@ export interface PlayerEvents {
|
|||
botDisconnect: () => any;
|
||||
channelEmpty: () => any;
|
||||
connectionCreate: () => any;
|
||||
error: () => any;
|
||||
debug: (queue: Queue, message: string) => any;
|
||||
error: (queue: Queue, error: Error) => any;
|
||||
musicStop: () => any;
|
||||
noResults: () => any;
|
||||
playlistAdd: () => any;
|
||||
|
@ -130,7 +131,7 @@ export interface PlayerEvents {
|
|||
searchCancel: () => any;
|
||||
searchInvalidResponse: () => any;
|
||||
searchResults: () => any;
|
||||
trackAdd: () => any;
|
||||
trackAdd: (queue: Queue, track: Track) => any;
|
||||
trackStart: (queue: Queue, track: Track) => any;
|
||||
}
|
||||
|
||||
|
@ -143,4 +144,7 @@ export interface PlayOptions {
|
|||
|
||||
/** Time to seek to before playing */
|
||||
seek?: number;
|
||||
|
||||
/** If it should start playing provided track immediately */
|
||||
immediate?: boolean;
|
||||
}
|
||||
|
|
|
@ -70,15 +70,11 @@ const FilterList = {
|
|||
},
|
||||
|
||||
get names() {
|
||||
return Object.keys(this).filter(
|
||||
(p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function"
|
||||
);
|
||||
return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function");
|
||||
},
|
||||
|
||||
get length() {
|
||||
return Object.keys(this).filter(
|
||||
(p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function"
|
||||
).length;
|
||||
return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function").length;
|
||||
},
|
||||
|
||||
toString() {
|
||||
|
|
|
@ -6,11 +6,9 @@ import { validateURL as SoundcloudValidateURL } from "soundcloud-scraper";
|
|||
|
||||
// scary things below *sigh*
|
||||
const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/;
|
||||
const spotifyPlaylistRegex =
|
||||
/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
||||
const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
||||
const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/;
|
||||
const vimeoRegex =
|
||||
/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
||||
const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
||||
const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/;
|
||||
const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/;
|
||||
const attachmentRegex =
|
||||
|
|
|
@ -1860,10 +1860,10 @@ discord.js-docgen@discordjs/docgen#ts-patch:
|
|||
tsubaki "^1.3.2"
|
||||
yargs "^14.0.0"
|
||||
|
||||
discord.js@^13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10:
|
||||
version "13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10.tgz#0fe3389e4befffd429ba37fc669b9153e87f33e5"
|
||||
integrity sha512-VuGJMzXStqeeHmB3DDEShGHXGey215573kkbFxQinzrFYt1UNnQZ5d1ZmB7Y0oY3JSivpv3Whc5M/YtH41NMXQ==
|
||||
discord.js@^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7:
|
||||
version "13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7.tgz#5baa6c758b970a1e6175d06373d4ab33eb6a4164"
|
||||
integrity sha512-nzbmF5MLSjpdr8DS7SpC9q291NQ8XkHlledM4lz+uFJ4YgnMmTpi6e0FgF7v2kpTJPqTsXDRY3rWBv6Dat+08A==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^0.1.6"
|
||||
"@discordjs/form-data" "^3.0.1"
|
||||
|
|
Loading…
Reference in a new issue