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

3
.gitignore vendored
View File

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

View File

@ -1,36 +1,43 @@
const { EmbedBuilder, MessageFlags, SlashCommandBuilder } = require('discord.js');
const {
EmbedBuilder,
MessageFlags,
SlashCommandBuilder,
} = require("discord.js");
module.exports = {
data: new SlashCommandBuilder()
.setName('help')
.setDescription('Show the help page'),
.setName("help")
.setDescription("Show the help page"),
async execute(interaction) {
const embed = new EmbedBuilder()
.setTitle("O-Bot Help")
.setDescription("Type `/` to view a list of commands.")
.addFields(
{
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",
inline: false
},
{
name: "YouTube",
value: "[gizmo4487](https://youtube.com/@gizmo4487)",
inline: true
},
{
name: "Twitch",
value: "[notengonombreusario](https://twitch.tv/notengonombreusario)",
inline: true
},
)
.setColor("#ffe511")
.setFooter({
text: "Created by gizmo4487",
iconURL: "https://gizmo4487.dev/O.jpg",
});
.setTitle("O-Bot Help")
.setDescription("Type `/` to view a list of commands.")
.addFields(
{
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",
inline: false,
},
{
name: "YouTube",
value: "[gizmo4487](https://youtube.com/@gizmo4487)",
inline: true,
},
{
name: "Twitch",
value: "[notengonombreusario](https://twitch.tv/notengonombreusario)",
inline: true,
}
)
.setColor("#ffe511")
.setFooter({
text: "Created by gizmo4487",
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 = {
data: new SlashCommandBuilder()
.setName('pi')
.setDescription('Make O-Bot say something'),
.setName("pi")
.setDescription("Make O-Bot say something"),
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 {
static audioPlayer = null;
static audioPlayer = null;
static async getAudioPlayer(url) {
if(this.audioPlayer == null) {
let data = await fetch(url, {
headers: {
'User-Agent': 'O-Bot'
}}
);
if(data.status == 200) {
console.log('Creating audio resource');
var fileStream = data.body;
var res = createAudioResource(fileStream, {inlineVolume: true});
//res.volume.setVolume(2);
this.audioPlayer = createAudioPlayer({
behaviors: {noSubscriber: NoSubscriberBehavior.Play},
});
this.audioPlayer.play(res);
return this.audioPlayer;
}
else {
throw Error('Radio is down!');
}
}
else {
return this.audioPlayer;
}
}
static async getAudioPlayer(url) {
if (this.audioPlayer == null) {
let data = await fetch(url, {
headers: {
"User-Agent": "O-Bot",
},
});
if (data.status == 200) {
console.log("Creating audio resource");
var fileStream = data.body;
var res = createAudioResource(fileStream, {
inlineVolume: true,
});
this.audioPlayer = createAudioPlayer({
behaviors: { noSubscriber: NoSubscriberBehavior.Play },
});
this.audioPlayer.play(res);
return this.audioPlayer;
} else {
throw Error("Radio is down!");
}
} else {
return this.audioPlayer;
}
}
}
module.exports = RadioPlayer;
module.exports = RadioPlayer;

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ module.exports = {
)),
async execute(interaction) {
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");
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 fetch = require('node-fetch');
const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js');
const fs = require('node:fs');
const path = require('node:path');
@ -9,7 +8,7 @@ const bot = new Client({
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates,
],
autoReconnect:true,
autoReconnect: true,
});
bot.commands = new Collection();
@ -17,13 +16,13 @@ bot.commands = new Collection();
const cmdFoldersPath = path.join(__dirname, 'cmd');
const cmdFolders = fs.readdirSync(cmdFoldersPath);
for(const folder of cmdFolders) {
for (const folder of cmdFolders) {
const cmdPath = path.join(cmdFoldersPath, folder);
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 cmd = require(filePath);
if('data' in cmd && 'execute' in cmd) {
if ('data' in cmd && 'execute' in cmd) {
console.log('Adding command: ' + cmd.data.name);
bot.commands.set(cmd.data.name, cmd);
}
@ -35,25 +34,25 @@ for(const folder of cmdFolders) {
// End slash command setup
// Display console message when logged in
bot.once('ready', () => {
console.log('O-Bot is ready!');
console.log('O-Bot is ready!');
});
// Reconnecting
bot.on("reconnecting", () => {
console.log("Reconnecting!");
});
});
// Resume
bot.on("resume", () => {
console.log("Connection restored!");
});
});
// Handle slash commands
bot.on(Events.InteractionCreate, async interaction => {
if(!interaction.isChatInputCommand()) return;
if (!interaction.isChatInputCommand()) return;
const cmd = interaction.client.commands.get(interaction.commandName);
if(!cmd) {
if (!cmd) {
console.error('No matching command ' + interaction.commandName + ' was found!');
return;
}
@ -61,10 +60,10 @@ bot.on(Events.InteractionCreate, async interaction => {
try {
await cmd.execute(interaction);
}
catch(error) {
catch (error) {
const errorMsg = `Uh-oh...something went wrong. Try again later!`;
console.error(error);
if(interaction.replied || interaction.deferred) {
if (interaction.replied || interaction.deferred) {
await interaction.followUp({
content: errorMsg,
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",
"version": "0.1.0",
"version": "1.0.0",
"description": "Pipipi-pipipipi!",
"main": "o-bot.js",
"author": "gizmo4487",
@ -19,5 +19,10 @@
"opusscript": "^0.1.1",
"xmlhttprequest": "^1.8.0",
"zlib-sync": "^0.1.10"
},
"devDependencies": {
"@eslint/js": "^9.26.0",
"eslint": "^9.26.0",
"globals": "^16.1.0"
}
}