Formatting changes + Update version to 1.0.0

This commit is contained in:
Max Gorley 2025-05-11 22:49:14 -05:00
parent e728666332
commit 27c72c53eb
12 changed files with 3372 additions and 149 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ deploy-commands*.js
delete-command-*.js delete-command-*.js
*.wav *.wav
*.mp3 *.mp3
.vscode/*

View File

@ -1,9 +1,13 @@
const { EmbedBuilder, MessageFlags, SlashCommandBuilder } = require('discord.js'); const {
EmbedBuilder,
MessageFlags,
SlashCommandBuilder,
} = require("discord.js");
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('help') .setName("help")
.setDescription('Show the help page'), .setDescription("Show the help page"),
async execute(interaction) { async execute(interaction) {
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle("O-Bot Help") .setTitle("O-Bot Help")
@ -12,18 +16,18 @@ module.exports = {
{ {
name: "Commands", name: "Commands",
value: "`/pi`: Make O-Bot say something in text chat\n\n`/voice [type]`: Make O-Bot join the voice channel you're currently in and speak. `type` can be `Normal`, `Alt`, `JP`, or `JP Alt`.\nIf left blank, the default is `Normal`.\n\n`/radio`: Enjoy listening to high-quality rips all day long with a 24/7 radio featuring SiIvaGunner's finest! Also available [here](https://radio.gizmo4487.dev).\n\n`/leave`: Disconnect O-Bot from the voice channel\n\n`/help`: Show this page", value: "`/pi`: Make O-Bot say something in text chat\n\n`/voice [type]`: Make O-Bot join the voice channel you're currently in and speak. `type` can be `Normal`, `Alt`, `JP`, or `JP Alt`.\nIf left blank, the default is `Normal`.\n\n`/radio`: Enjoy listening to high-quality rips all day long with a 24/7 radio featuring SiIvaGunner's finest! Also available [here](https://radio.gizmo4487.dev).\n\n`/leave`: Disconnect O-Bot from the voice channel\n\n`/help`: Show this page",
inline: false inline: false,
}, },
{ {
name: "YouTube", name: "YouTube",
value: "[gizmo4487](https://youtube.com/@gizmo4487)", value: "[gizmo4487](https://youtube.com/@gizmo4487)",
inline: true inline: true,
}, },
{ {
name: "Twitch", name: "Twitch",
value: "[notengonombreusario](https://twitch.tv/notengonombreusario)", value: "[notengonombreusario](https://twitch.tv/notengonombreusario)",
inline: true inline: true,
}, }
) )
.setColor("#ffe511") .setColor("#ffe511")
.setFooter({ .setFooter({
@ -31,6 +35,9 @@ module.exports = {
iconURL: "https://gizmo4487.dev/O.jpg", iconURL: "https://gizmo4487.dev/O.jpg",
}); });
await interaction.reply({ embeds: [embed], flags: MessageFlags.Ephemeral }); await interaction.reply({
embeds: [embed],
flags: MessageFlags.Ephemeral,
});
}, },
}; };

View File

@ -1,10 +1,10 @@
const { SlashCommandBuilder } = require('discord.js'); const { SlashCommandBuilder } = require("discord.js");
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('pi') .setName("pi")
.setDescription('Make O-Bot say something'), .setDescription("Make O-Bot say something"),
async execute(interaction) { async execute(interaction) {
await interaction.reply('Pipi? Pipi-pipipipipi!'); await interaction.reply("Pipi? Pipi-pipipipipi!");
}, },
}; };

View File

@ -1,33 +1,35 @@
const { createAudioResource, createAudioPlayer, NoSubscriberBehavior } = require('@discordjs/voice'); const {
createAudioResource,
createAudioPlayer,
NoSubscriberBehavior,
} = require("@discordjs/voice");
class RadioPlayer { class RadioPlayer {
static audioPlayer = null; static audioPlayer = null;
static async getAudioPlayer(url) { static async getAudioPlayer(url) {
if(this.audioPlayer == null) { if (this.audioPlayer == null) {
let data = await fetch(url, { let data = await fetch(url, {
headers: { headers: {
'User-Agent': 'O-Bot' "User-Agent": "O-Bot",
}} },
); });
if(data.status == 200) { if (data.status == 200) {
console.log('Creating audio resource'); console.log("Creating audio resource");
var fileStream = data.body; var fileStream = data.body;
var res = createAudioResource(fileStream, {inlineVolume: true}); var res = createAudioResource(fileStream, {
//res.volume.setVolume(2); inlineVolume: true,
});
this.audioPlayer = createAudioPlayer({ this.audioPlayer = createAudioPlayer({
behaviors: {noSubscriber: NoSubscriberBehavior.Play}, behaviors: { noSubscriber: NoSubscriberBehavior.Play },
}); });
this.audioPlayer.play(res); this.audioPlayer.play(res);
return this.audioPlayer; return this.audioPlayer;
} else {
throw Error("Radio is down!");
} }
else { } else {
throw Error('Radio is down!');
}
}
else {
return this.audioPlayer; return this.audioPlayer;
} }
} }
} }
module.exports = RadioPlayer; module.exports = RadioPlayer;

View File

@ -1,11 +1,10 @@
function randomHex(){ function randomHex() {
let hex=""; let hex = "";
let randNum = 0; let randNum = 0;
randNum = (Math.floor(Math.random()*Math.floor(41))); randNum = Math.floor(Math.random() * Math.floor(41));
if(randNum<16){ if (randNum < 16) {
hex = "0" + randNum.toString(16); hex = "0" + randNum.toString(16);
} } else {
else{
hex = randNum.toString(16); hex = randNum.toString(16);
} }

View File

@ -1,67 +1,59 @@
const { MessageFlags } = require('discord.js'); const { MessageFlags } = require("discord.js");
const { createAudioPlayer, createAudioResource, getVoiceConnection, joinVoiceChannel } = require('@discordjs/voice'); const {
const RadioPlayer = require('./RadioPlayer.js'); createAudioPlayer,
async function play(interaction, sound){ createAudioResource,
try{ getVoiceConnection,
joinVoiceChannel,
} = require("@discordjs/voice");
const RadioPlayer = require("./RadioPlayer.js");
async function play(interaction, sound) {
try {
const member = interaction.member; const member = interaction.member;
const VC = member.voice.channel; const VC = member.voice.channel;
if(!VC){ if (!VC) {
return( return {
{ content: "Join a voice channel and try again!",
content: 'Join a voice channel and try again!', flags: MessageFlags.Ephemeral,
flags: MessageFlags.Ephemeral };
} } else {
);
}
else{
var connection = joinVoiceChannel({ var connection = joinVoiceChannel({
channelId: VC.id, channelId: VC.id,
guildId: VC.guild.id, guildId: VC.guild.id,
adapterCreator: VC.guild.voiceAdapterCreator, adapterCreator: VC.guild.voiceAdapterCreator,
}); });
if(sound.startsWith('http')) { var player = null;
var player = await RadioPlayer.getAudioPlayer(sound); if (sound.startsWith("http")) {
player = await RadioPlayer.getAudioPlayer(sound);
connection.subscribe(player); connection.subscribe(player);
} } else {
else { console.log("Playing local file");
console.log('Playing local file');
var resource = createAudioResource(sound); var resource = createAudioResource(sound);
var player = createAudioPlayer(); player = createAudioPlayer();
//console.log('Playing ' + sound);
connection.subscribe(player); connection.subscribe(player);
player.play(resource); player.play(resource);
} }
} }
} catch (error) {
} catch(error){
console.error(error); console.error(error);
return( return {
{ content:
content: 'Something went wrong! Do I have permission to join the voice channel and speak?', "Something went wrong! Do I have permission to join the voice channel and speak?",
flags: MessageFlags.Ephemeral flags: MessageFlags.Ephemeral,
};
} }
); return "Now speaking in voice channel!";
}
return('Now speaking in voice channel!');
} }
function disconnect(interaction) { function disconnect(interaction) {
const connection = getVoiceConnection(interaction.guildId); const connection = getVoiceConnection(interaction.guildId);
if(connection) { if (connection) {
connection.destroy(); connection.destroy();
return("Bye!"); return "Bye!";
} } else {
else { return {
return( content: "Can't disconnect me because I'm not in a voice channel!",
{ flags: MessageFlags.Ephemeral,
content: 'Can\'t disconnect me because I\'m not in a voice channel!', };
flags: MessageFlags.Ephemeral
}
);
} }
} }
module.exports = { play, disconnect }; module.exports = { play, disconnect };

View File

@ -1,6 +1,6 @@
const { SlashCommandBuilder } = require('discord.js'); const { SlashCommandBuilder } = require('discord.js');
const vcutil = require('../util/vc.js'); const vcutil = require('../util/vc.js');
const util = require('../util/util.js');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('leave') .setName('leave')

View File

@ -18,7 +18,7 @@ module.exports = {
)), )),
async execute(interaction) { async execute(interaction) {
const voiceOption = interaction.options.getString('type') ?? 'normal'; const voiceOption = interaction.options.getString('type') ?? 'normal';
const prefix = 'o_sound' + (voiceOption!='normal'?'/' + voiceOption:''); const prefix = 'o_sound' + (voiceOption != 'normal' ? '/' + voiceOption : '');
const response = await vcutil.play(interaction, prefix + "/000000" + util.randomHex() + ".wav"); const response = await vcutil.play(interaction, prefix + "/000000" + util.randomHex() + ".wav");
await interaction.reply(response); await interaction.reply(response);
}, },

10
eslint.config.mjs Normal file
View File

@ -0,0 +1,10 @@
import js from "@eslint/js";
import globals from "globals";
import { defineConfig } from "eslint/config";
export default defineConfig([
{ files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"] },
{ files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } },
{ files: ["**/*.{js,mjs,cjs}"], languageOptions: { globals: globals.node } },
]);

View File

@ -1,5 +1,4 @@
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js'); const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js');
const fetch = require('node-fetch');
const fs = require('node:fs'); const fs = require('node:fs');
const path = require('node:path'); const path = require('node:path');
@ -9,7 +8,7 @@ const bot = new Client({
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildVoiceStates,
], ],
autoReconnect:true, autoReconnect: true,
}); });
bot.commands = new Collection(); bot.commands = new Collection();
@ -17,13 +16,13 @@ bot.commands = new Collection();
const cmdFoldersPath = path.join(__dirname, 'cmd'); const cmdFoldersPath = path.join(__dirname, 'cmd');
const cmdFolders = fs.readdirSync(cmdFoldersPath); const cmdFolders = fs.readdirSync(cmdFoldersPath);
for(const folder of cmdFolders) { for (const folder of cmdFolders) {
const cmdPath = path.join(cmdFoldersPath, folder); const cmdPath = path.join(cmdFoldersPath, folder);
const cmdFiles = fs.readdirSync(cmdPath).filter(file => file.endsWith('.js')); const cmdFiles = fs.readdirSync(cmdPath).filter(file => file.endsWith('.js'));
for(const file of cmdFiles) { for (const file of cmdFiles) {
const filePath = path.join(cmdPath, file); const filePath = path.join(cmdPath, file);
const cmd = require(filePath); const cmd = require(filePath);
if('data' in cmd && 'execute' in cmd) { if ('data' in cmd && 'execute' in cmd) {
console.log('Adding command: ' + cmd.data.name); console.log('Adding command: ' + cmd.data.name);
bot.commands.set(cmd.data.name, cmd); bot.commands.set(cmd.data.name, cmd);
} }
@ -41,19 +40,19 @@ bot.once('ready', () => {
// Reconnecting // Reconnecting
bot.on("reconnecting", () => { bot.on("reconnecting", () => {
console.log("Reconnecting!"); console.log("Reconnecting!");
}); });
// Resume // Resume
bot.on("resume", () => { bot.on("resume", () => {
console.log("Connection restored!"); console.log("Connection restored!");
}); });
// Handle slash commands // Handle slash commands
bot.on(Events.InteractionCreate, async interaction => { bot.on(Events.InteractionCreate, async interaction => {
if(!interaction.isChatInputCommand()) return; if (!interaction.isChatInputCommand()) return;
const cmd = interaction.client.commands.get(interaction.commandName); const cmd = interaction.client.commands.get(interaction.commandName);
if(!cmd) { if (!cmd) {
console.error('No matching command ' + interaction.commandName + ' was found!'); console.error('No matching command ' + interaction.commandName + ' was found!');
return; return;
} }
@ -61,10 +60,10 @@ bot.on(Events.InteractionCreate, async interaction => {
try { try {
await cmd.execute(interaction); await cmd.execute(interaction);
} }
catch(error) { catch (error) {
const errorMsg = `Uh-oh...something went wrong. Try again later!`; const errorMsg = `Uh-oh...something went wrong. Try again later!`;
console.error(error); console.error(error);
if(interaction.replied || interaction.deferred) { if (interaction.replied || interaction.deferred) {
await interaction.followUp({ await interaction.followUp({
content: errorMsg, content: errorMsg,
flags: MessageFlags.Ephemeral flags: MessageFlags.Ephemeral

3212
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "O-Bot", "name": "O-Bot",
"version": "0.1.0", "version": "1.0.0",
"description": "Pipipi-pipipipi!", "description": "Pipipi-pipipipi!",
"main": "o-bot.js", "main": "o-bot.js",
"author": "gizmo4487", "author": "gizmo4487",
@ -19,5 +19,10 @@
"opusscript": "^0.1.1", "opusscript": "^0.1.1",
"xmlhttprequest": "^1.8.0", "xmlhttprequest": "^1.8.0",
"zlib-sync": "^0.1.10" "zlib-sync": "^0.1.10"
},
"devDependencies": {
"@eslint/js": "^9.26.0",
"eslint": "^9.26.0",
"globals": "^16.1.0"
} }
} }