Compare commits

..

4 commits

Author SHA1 Message Date
1f8c5585dc Some utility 2022-06-17 01:25:43 +02:00
c8fc925d35 Converted to slash 2022-06-17 01:25:35 +02:00
fc2e898025 node-fetch 2022-06-17 01:25:14 +02:00
1d4c7feb56 Convert to ES6 2022-06-17 01:25:05 +02:00
12 changed files with 397 additions and 73 deletions

View file

@ -7,6 +7,7 @@
"parserOptions": { "parserOptions": {
"ecmaVersion": 2021 "ecmaVersion": 2021
}, },
"sourceType": "module",
"rules": { "rules": {
"arrow-spacing": ["warn", { "before": true, "after": true }], "arrow-spacing": ["warn", { "before": true, "after": true }],
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }], "brace-style": ["error", "stroustrup", { "allowSingleLine": true }],

View file

@ -1,10 +1,11 @@
const { SlashCommandBuilder } = require('@discordjs/builders'); import { SlashCommandBuilder } from '@discordjs/builders';
const { MessageEmbed, MessageActionRow, MessageSelectMenu } = require('discord.js'); import { MessageEmbed, MessageActionRow, MessageSelectMenu } from 'discord.js';
const { exec } = require('node:child_process'); import { exec } from 'node:child_process';
const fs = require('node:fs'); import fs from 'node:fs';
const os = require('node:os'); import os from 'node:os';
import utils from '../utils/videos.js';
module.exports = { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('download') .setName('download')
.setDescription('Download a video.') .setDescription('Download a video.')
@ -99,7 +100,7 @@ async function download(url, interaction) {
if (interaction.values[1]) format += '+' + interaction.values[1]; if (interaction.values[1]) format += '+' + interaction.values[1];
} }
downloadVideo(url, interaction.id, format) utils.downloadVideo(url, interaction.id, format)
.then(async () => { .then(async () => {
const file = fs.readdirSync(os.tmpdir()).filter(fn => fn.startsWith(interaction.id)); const file = fs.readdirSync(os.tmpdir()).filter(fn => fn.startsWith(interaction.id));
const output = `${os.tmpdir()}/${file}`; const output = `${os.tmpdir()}/${file}`;
@ -112,7 +113,7 @@ async function download(url, interaction) {
await interaction.followUp('Uh oh! The video you tried to download is too big!', { ephemeral: true }); await interaction.followUp('Uh oh! The video you tried to download is too big!', { ephemeral: true });
} }
else if (fileSize > 8) { else if (fileSize > 8) {
const fileURL = await upload(output) const fileURL = await utils.upload(output)
.catch(err => { .catch(err => {
console.error(err); console.error(err);
}); });
@ -130,31 +131,3 @@ async function download(url, interaction) {
}); });
return; return;
} }
async function downloadVideo(url, output, format) {
await new Promise((resolve, reject) => {
exec(`./bin/yt-dlp -f ${format} ${url} -o "${os.tmpdir()}/${output}.%(ext)s" --force-overwrites`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}
async function upload(file) {
return await new Promise((resolve, reject) => {
exec(`./bin/upload.sh ${file}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}

View file

@ -1,6 +1,6 @@
const { SlashCommandBuilder } = require('@discordjs/builders'); import { SlashCommandBuilder } from '@discordjs/builders';
module.exports = { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('ping') .setName('ping')
.setDescription('Replies with Pong!'), .setDescription('Replies with Pong!'),

41
commands/reddit.js Normal file
View file

@ -0,0 +1,41 @@
import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed } from 'discord.js';
import fetch from 'node-fetch'
export default {
data: new SlashCommandBuilder()
.setName('reddit')
.setDescription('Send random images from the subreddit you choose')
.addStringOption(option =>
option.setName('subreddit')
.setDescription('The subreddit you wish to see')
.setRequired(true)),
async execute(interaction) {
await interaction.deferReply({ ephemeral: false });
fetch('https://www.reddit.com/r/' + interaction.options.getString('subreddit') + '.json?limit=100').then((response) => {
return response.json();
}).then((response) => {
if (response.error == 404) {
return interaction.editReply('Not a valid subreddit');
}
if (response.data.dist == 0) {
return interaction.editReply('Not a valid subreddit');
}
const i = Math.floor((Math.random() * response.data.children.length));
if (response.data.children[i].data.over_18 == true && !interaction.channel.nsfw) {
return interaction.editReply('No nsfw');
}
const redditEmbed = new MessageEmbed()
.setColor(interaction.member ? interaction.member.displayHexColor : 'NAVY')
.setTitle(response.data.children[i].data.title)
.setDescription(response.data.children[i].data.selftext)
.setURL('https://reddit.com' + response.data.children[i].data.permalink)
.setFooter(`/r/${response.data.children[i].data.subreddit} | ⬆ ${response.data.children[i].data.ups} 🗨 ${response.data.children[i].data.num_comments}`);
interaction.editReply({ embeds: [redditEmbed]});
interaction.followUp(response.data.children[i].data.url);
});
},
};

79
commands/vid2gif.js Normal file
View file

@ -0,0 +1,79 @@
import { SlashCommandBuilder } from '@discordjs/builders';
import utils from '../utils/videos.js';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { exec } from 'node:child_process';
export default {
data: new SlashCommandBuilder()
.setName('vid2gif')
.setDescription('Convert your video into a gif.')
.addStringOption(option =>
option.setName('url')
.setDescription('URL of the video you want to convert')
.setRequired(true)),
async execute(interaction) {
await interaction.deferReply({ ephemeral: false });
const url = interaction.options.getString('url');
utils.downloadVideo(url, interaction.id)
.then(async () => {
const file = fs.readdirSync(os.tmpdir()).filter(fn => fn.startsWith(interaction.id));
const output = `${os.tmpdir()}/${file}`;
const gifskiOutput = output.replace(path.extname(output), '.gif');
const gifsicleOutput = output.replace(path.extname(output), 'gifsicle.gif');
await utils.ffmpeg(`-i ${output} ${os.tmpdir()}/frame${interaction.id}%04d.png`); // Extract every frame for gifski
await gifski(gifskiOutput, `${os.tmpdir()}/frame${interaction.id}*`); // Make it look better
await gifsicle(gifskiOutput, gifsicleOutput); // Optimize it
const fileStat = fs.statSync(gifsicleOutput);
const fileSize = fileStat.size / 1000000.0;
if (fileSize > 100) {
await interaction.deleteReply();
await interaction.followUp('Uh oh! The video once converted is too big!', { ephemeral: true });
}
else if (fileSize > 8) {
const fileURL = await utils.upload(gifsicleOutput)
.catch(err => {
console.error(err);
});
await interaction.editReply({ content: `File was bigger than 8 mb. It has been uploaded to an external site.\n${fileURL}`, ephemeral: false });
}
else {
await interaction.editReply({ files: [gifsicleOutput], ephemeral: false });
}
});
},
};
async function gifski(output, input) {
return await new Promise((resolve, reject) => {
exec(`gifski -o ${output} ${input}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}
async function gifsicle(input, output) {
return await new Promise((resolve, reject) => {
exec(`gifsicle --scale 0.5 -O3 -i ${input} -o ${output}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}

View file

@ -20,6 +20,23 @@ const commands = [
option.setName('advanced') option.setName('advanced')
.setDescription('Choose the quality of the video.') .setDescription('Choose the quality of the video.')
.setRequired(false)), .setRequired(false)),
new SlashCommandBuilder()
.setName('reddit')
.setDescription('Send random images from the subreddit you choose')
.addStringOption(option =>
option.setName('subreddit')
.setDescription('The subreddit you wish to see')
.setRequired(true)),
new SlashCommandBuilder()
.setName('vid2gif')
.setDescription('Convert your video into a gif.')
.addStringOption(option =>
option.setName('url')
.setDescription('URL of the video you want to convert')
.setRequired(true)),
] ]
.map(command => command.toJSON()); .map(command => command.toJSON());

View file

@ -1,4 +1,4 @@
module.exports = { export default {
name: 'interactionCreate', name: 'interactionCreate',
async execute(interaction) { async execute(interaction) {
const client = interaction.client; const client = interaction.client;

View file

@ -1,9 +1,10 @@
const { exec } = require('node:child_process'); import { exec } from 'node:child_process';
const https = require('node:https'); import https from 'node:https';
require('dotenv').config(); import dotenv from 'dotenv'
dotenv.config();
const { uptimeURL, uptimeInterval } = process.env; const { uptimeURL, uptimeInterval } = process.env;
module.exports = { export default {
name: 'ready', name: 'ready',
once: true, once: true,
async execute(client) { async execute(client) {

View file

@ -1,9 +1,14 @@
const fs = require('node:fs'); import fs from 'node:fs';
const path = require('node:path'); import path from 'node:path';
const { Client, Collection, Intents } = require('discord.js'); import { fileURLToPath } from 'node:url';
require('dotenv').config(); import { Client, Collection, Intents } from 'discord.js';
import dotenv from 'dotenv'
dotenv.config()
const { token } = process.env; const { token } = process.env;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const client = new Client({ intents: [Intents.FLAGS.GUILDS] }); const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
// Load commands from the commands folder // Load commands from the commands folder
@ -13,7 +18,8 @@ const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('
for (const file of commandFiles) { for (const file of commandFiles) {
const filePath = path.join(commandsPath, file); const filePath = path.join(commandsPath, file);
const command = require(filePath); let command = await import(filePath);
command = command.default;
client.commands.set(command.data.name, command); client.commands.set(command.data.name, command);
} }
@ -24,7 +30,8 @@ const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'
for (const file of eventFiles) { for (const file of eventFiles) {
const filePath = path.join(eventsPath, file); const filePath = path.join(eventsPath, file);
const event = require(filePath); let event = await import(filePath);
event = event.default;
if (event.once) { if (event.once) {
client.once(event.name, (...args) => event.execute(...args)); client.once(event.name, (...args) => event.execute(...args));
} }

200
package-lock.json generated
View file

@ -13,7 +13,8 @@
"@discordjs/rest": "^0.4.1", "@discordjs/rest": "^0.4.1",
"discord-api-types": "^0.33.1", "discord-api-types": "^0.33.1",
"discord.js": "^13.7.0", "discord.js": "^13.7.0",
"dotenv": "^16.0.1" "dotenv": "^16.0.1",
"node-fetch": "^3.2.6"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.16.0" "eslint": "^8.16.0"
@ -79,6 +80,25 @@
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz",
"integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg==" "integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg=="
}, },
"node_modules/@discordjs/rest/node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/@eslint/eslintrc": { "node_modules/@eslint/eslintrc": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@ -354,6 +374,14 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -415,6 +443,25 @@
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz",
"integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw==" "integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw=="
}, },
"node_modules/discord.js/node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/doctrine": { "node_modules/doctrine": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@ -621,6 +668,28 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true "dev": true
}, },
"node_modules/fetch-blob": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz",
"integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/file-entry-cache": { "node_modules/file-entry-cache": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -665,6 +734,17 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -896,23 +976,39 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true "dev": true
}, },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.6.7", "version": "3.2.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
}, },
"engines": { "engines": {
"node": "4.x || >=6.0.0" "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}, },
"peerDependencies": { "funding": {
"encoding": "^0.1.0" "type": "opencollective",
}, "url": "https://opencollective.com/node-fetch"
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
} }
}, },
"node_modules/once": { "node_modules/once": {
@ -1091,7 +1187,7 @@
"node_modules/tr46": { "node_modules/tr46": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
}, },
"node_modules/ts-mixer": { "node_modules/ts-mixer": {
"version": "6.0.1", "version": "6.0.1",
@ -1142,15 +1238,23 @@
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
"dev": true "dev": true
}, },
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"engines": {
"node": ">= 8"
}
},
"node_modules/webidl-conversions": { "node_modules/webidl-conversions": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
}, },
"node_modules/whatwg-url": { "node_modules/whatwg-url": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": { "dependencies": {
"tr46": "~0.0.3", "tr46": "~0.0.3",
"webidl-conversions": "^3.0.0" "webidl-conversions": "^3.0.0"
@ -1257,6 +1361,14 @@
"version": "0.29.0", "version": "0.29.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz",
"integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg==" "integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
} }
} }
}, },
@ -1471,6 +1583,11 @@
"which": "^2.0.1" "which": "^2.0.1"
} }
}, },
"data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -1516,6 +1633,14 @@
"version": "0.30.0", "version": "0.30.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz",
"integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw==" "integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
} }
} }
}, },
@ -1673,6 +1798,15 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true "dev": true
}, },
"fetch-blob": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz",
"integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==",
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
},
"file-entry-cache": { "file-entry-cache": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -1708,6 +1842,14 @@
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
} }
}, },
"formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"requires": {
"fetch-blob": "^3.1.2"
}
},
"fs.realpath": { "fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -1888,12 +2030,19 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true "dev": true
}, },
"node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
},
"node-fetch": { "node-fetch": {
"version": "2.6.7", "version": "3.2.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==",
"requires": { "requires": {
"whatwg-url": "^5.0.0" "data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
} }
}, },
"once": { "once": {
@ -2021,7 +2170,7 @@
"tr46": { "tr46": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
}, },
"ts-mixer": { "ts-mixer": {
"version": "6.0.1", "version": "6.0.1",
@ -2063,15 +2212,20 @@
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
"dev": true "dev": true
}, },
"web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
},
"webidl-conversions": { "webidl-conversions": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
}, },
"whatwg-url": { "whatwg-url": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"requires": { "requires": {
"tr46": "~0.0.3", "tr46": "~0.0.3",
"webidl-conversions": "^3.0.0" "webidl-conversions": "^3.0.0"

View file

@ -6,6 +6,7 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"type": "module",
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
@ -14,7 +15,8 @@
"@discordjs/rest": "^0.4.1", "@discordjs/rest": "^0.4.1",
"discord-api-types": "^0.33.1", "discord-api-types": "^0.33.1",
"discord.js": "^13.7.0", "discord.js": "^13.7.0",
"dotenv": "^16.0.1" "dotenv": "^16.0.1",
"node-fetch": "^3.2.6"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.16.0" "eslint": "^8.16.0"

49
utils/videos.js Normal file
View file

@ -0,0 +1,49 @@
import os from 'node:os';
import { exec } from 'node:child_process';
export default {
downloadVideo,
upload,
ffmpeg
};
async function downloadVideo(url, output, format = 'bestvideo*+bestaudio/best') {
await new Promise((resolve, reject) => {
exec(`./bin/yt-dlp -f ${format} ${url} -o "${os.tmpdir()}/${output}.%(ext)s" --force-overwrites`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}
async function upload(file) {
return await new Promise((resolve, reject) => {
exec(`./bin/upload.sh ${file}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}
async function ffmpeg(command) {
return await new Promise((resolve, reject) => {
exec(`ffmpeg ${command}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout);
});
});
}