Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8f71ad732 | ||
|
|
bc6c1b2066 | ||
|
|
c0a959cfc7 | ||
|
|
6327e98567 | ||
|
|
ad181c4cc0 | ||
|
|
63ba3694d3 | ||
|
|
fe99f09665 | ||
|
|
12a425c3fc | ||
|
|
989cc90797 | ||
|
|
2c48546b22 | ||
|
|
91498377d0 | ||
|
|
b1733995d3 |
18
api/reset_bot.php
Normal file
18
api/reset_bot.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['success' => false, 'error' => 'Invalid request method']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$output = [];
|
||||
$return_var = 0;
|
||||
// Using sudo to run as ubuntu user who owns the pm2 process
|
||||
exec("sudo -u ubuntu /usr/bin/pm2 restart discord-bot 2>&1", $output, $return_var);
|
||||
|
||||
if ($return_var === 0) {
|
||||
echo json_encode(['success' => true, 'message' => 'Bot restarted successfully']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Failed to restart bot', 'details' => implode("\n", $output)]);
|
||||
}
|
||||
BIN
assets/audio/sahur.mp3
Normal file
BIN
assets/audio/sahur.mp3
Normal file
Binary file not shown.
177
audio_assets.php
Normal file
177
audio_assets.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
|
||||
// Handle File Upload
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['audio_file'])) {
|
||||
$file = $_FILES['audio_file'];
|
||||
$filename = 'sahur.mp3'; // Force the name as requested, or we could use $file['name']
|
||||
$targetDir = 'assets/audio/';
|
||||
|
||||
if (!is_dir($targetDir)) {
|
||||
mkdir($targetDir, 0775, true);
|
||||
}
|
||||
|
||||
$targetFile = $targetDir . $filename;
|
||||
$fileType = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
|
||||
// Basic validation
|
||||
if ($fileType != "mp3") {
|
||||
$message = "Maaf, hanya file MP3 yang diizinkan.";
|
||||
$messageType = "error";
|
||||
} elseif ($file['size'] > 5000000) { // 5MB limit
|
||||
$message = "File terlalu besar. Maksimal 5MB.";
|
||||
$messageType = "error";
|
||||
} else {
|
||||
if (move_uploaded_file($file['tmp_name'], $targetFile)) {
|
||||
// Update database record
|
||||
try {
|
||||
$stmt = db()->prepare("INSERT INTO audio_assets (filename, display_name) VALUES (?, ?) ON DUPLICATE KEY UPDATE updated_at = CURRENT_TIMESTAMP");
|
||||
$stmt->execute([$filename, 'Sahur Notification']);
|
||||
$message = "File $filename berhasil diunggah/diperbarui!";
|
||||
$messageType = "success";
|
||||
} catch (Exception $e) {
|
||||
$message = "Gagal menyimpan ke database: " . $e->getMessage();
|
||||
$messageType = "error";
|
||||
}
|
||||
} else {
|
||||
$message = "Terjadi kesalahan saat mengunggah file.";
|
||||
$messageType = "error";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch current assets
|
||||
$assets = db()->query("SELECT * FROM audio_assets")->fetchAll();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Audio Assets Manager - CMS</title>
|
||||
<style>
|
||||
:root {
|
||||
--primary: #007bff;
|
||||
--success: #28a745;
|
||||
--error: #dc3545;
|
||||
--bg: #f8f9fa;
|
||||
--card: #ffffff;
|
||||
--text: #333;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.container {
|
||||
background: var(--card);
|
||||
padding: 2rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 25px rgba(0,0,0,0.05);
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
h1 { font-size: 1.5rem; margin-bottom: 1.5rem; text-align: center; }
|
||||
.alert {
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.alert-success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
|
||||
.alert-error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
|
||||
|
||||
.upload-zone {
|
||||
border: 2px dashed #ddd;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
transition: border-color 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.upload-zone:hover { border-color: var(--primary); }
|
||||
.file-input { display: none; }
|
||||
|
||||
.btn {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 20px;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin-top: 1rem;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.btn:hover { opacity: 0.9; }
|
||||
|
||||
.asset-list { margin-top: 2rem; }
|
||||
.asset-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background: #f1f3f5;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.asset-info small { color: #666; display: block; }
|
||||
audio { width: 100%; margin-top: 10px; height: 35px; }
|
||||
.back-link { display: block; text-align: center; margin-top: 1rem; color: #666; text-decoration: none; font-size: 0.9rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1>Panel Audio Assets</h1>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-<?php echo $messageType; ?>">
|
||||
<?php echo $message; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="" method="POST" enctype="multipart/form-data">
|
||||
<div class="upload-zone" onclick="document.getElementById('audio_file').click()">
|
||||
<p>Klik di sini untuk pilih file MP3 (sahur.mp3)</p>
|
||||
<input type="file" name="audio_file" id="audio_file" class="file-input" accept="audio/mpeg" required>
|
||||
<div id="file-name" style="margin-top: 10px; font-weight: bold; color: var(--primary);"></div>
|
||||
</div>
|
||||
<button type="submit" class="btn">Unggah & Perbarui</button>
|
||||
</form>
|
||||
|
||||
<div class="asset-list">
|
||||
<h3>File Terdaftar:</h3>
|
||||
<?php foreach ($assets as $asset): ?>
|
||||
<div class="asset-item">
|
||||
<div class="asset-info">
|
||||
<strong><?php echo htmlspecialchars($asset['display_name']); ?></strong>
|
||||
<small>Nama file: <?php echo htmlspecialchars($asset['filename']); ?></small>
|
||||
<small>Terakhir diupdate: <?php echo $asset['updated_at']; ?></small>
|
||||
</div>
|
||||
</div>
|
||||
<audio controls src="assets/audio/<?php echo $asset['filename']; ?>?v=<?php echo time(); ?>"></audio>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<a href="index.php" class="back-link">← Kembali ke Dashboard</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('audio_file').onchange = function() {
|
||||
document.getElementById('file-name').textContent = this.files[0].name;
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
19
bot.log
Normal file
19
bot.log
Normal file
@ -0,0 +1,19 @@
|
||||
Bot logged in as AsepXiaoQin#6954
|
||||
(node:11761) DeprecationWarning: The ready event has been renamed to clientReady to distinguish it from the gateway READY event and will only emit under that name in v15. Please use clientReady instead.
|
||||
(Use `node --trace-deprecation ...` to show where the warning was created)
|
||||
Slash commands registered.
|
||||
Command dijalankan... /testsahur
|
||||
Command dijalankan... /join
|
||||
/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:529
|
||||
throw new Error(`No compatible encryption modes. Available include: ${options.join(", ")}`);
|
||||
^
|
||||
|
||||
Error: No compatible encryption modes. Available include: aead_aes256_gcm_rtpsize, aead_xchacha20_poly1305_rtpsize
|
||||
at chooseEncryptionMode (/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:529:11)
|
||||
at /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:721:21
|
||||
Emitted 'error' event on VoiceConnection instance at:
|
||||
at VoiceConnection.onNetworkingError (/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:1914:10)
|
||||
at Networking.emit (node:events:518:28)
|
||||
at /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:729:32
|
||||
|
||||
Node.js v22.18.0
|
||||
7
data/config.json
Normal file
7
data/config.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"discord_token": "MTQ3MTkwOTE5Mzg4Njg1OTI5NA.GCEdpc.jMIxPFsquVAhp88x3dO-yWUFI7e1u1r8oIZTcw",
|
||||
"guild_id": "1428530728706117632",
|
||||
"voice_channel_id": "1457687430189682781",
|
||||
"alarm_time": "18:55",
|
||||
"last_voice_channel": null
|
||||
}
|
||||
13
db/migrations/001_create_bot_settings.sql
Normal file
13
db/migrations/001_create_bot_settings.sql
Normal file
@ -0,0 +1,13 @@
|
||||
-- migrations/001_create_bot_settings.sql
|
||||
CREATE TABLE IF NOT EXISTS bot_settings (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
setting_key VARCHAR(50) UNIQUE NOT NULL,
|
||||
setting_value TEXT,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO bot_settings (setting_key, setting_value) VALUES
|
||||
('discord_token', ''),
|
||||
('guild_id', ''),
|
||||
('voice_channel_id', ''),
|
||||
('last_voice_channel', '');
|
||||
10
db/migrations/002_create_audio_assets.sql
Normal file
10
db/migrations/002_create_audio_assets.sql
Normal file
@ -0,0 +1,10 @@
|
||||
-- Create audio_assets table
|
||||
CREATE TABLE IF NOT EXISTS audio_assets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
filename VARCHAR(255) NOT NULL UNIQUE,
|
||||
display_name VARCHAR(255) NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Pre-fill with sahur.mp3 if not exists
|
||||
INSERT IGNORE INTO audio_assets (filename, display_name) VALUES ('sahur.mp3', 'Sahur Notification');
|
||||
3
db/migrations/003_add_alarm_settings.sql
Normal file
3
db/migrations/003_add_alarm_settings.sql
Normal file
@ -0,0 +1,3 @@
|
||||
-- migrations/003_add_alarm_settings.sql
|
||||
INSERT IGNORE INTO bot_settings (setting_key, setting_value) VALUES
|
||||
('alarm_time', '');
|
||||
124
index.js
Normal file
124
index.js
Normal file
@ -0,0 +1,124 @@
|
||||
const { Client, GatewayIntentBits, SlashCommandBuilder, Routes } = require('discord.js');
|
||||
const { joinVoiceChannel, createAudioPlayer, createAudioResource, StreamType, getVoiceConnection } = require('@discordjs/voice');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { REST } = require('@discordjs/rest');
|
||||
|
||||
// Load Config
|
||||
const config = JSON.parse(fs.readFileSync('./data/config.json', 'utf8'));
|
||||
const token = config.discord_token;
|
||||
|
||||
const client = new Client({
|
||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates]
|
||||
});
|
||||
|
||||
const player = createAudioPlayer();
|
||||
|
||||
player.on('error', err => {
|
||||
console.log('LOG ERROR AUDIO:', err.message);
|
||||
});
|
||||
|
||||
player.on('stateChange', (old, current) => {
|
||||
console.log('Status Audio Saat Ini:', current.status);
|
||||
});
|
||||
|
||||
client.on('ready', async () => {
|
||||
console.log(`Bot Minimalis Ready: ${client.user.tag}`);
|
||||
const commands = [
|
||||
new SlashCommandBuilder().setName('join').setDescription('Bot join ke Voice Channel'),
|
||||
new SlashCommandBuilder().setName('testsahur').setDescription('Tes putar sahur.mp3')
|
||||
].map(cmd => cmd.toJSON());
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(token);
|
||||
try {
|
||||
await rest.put(Routes.applicationCommands(client.user.id), { body: commands });
|
||||
console.log('Slash Commands registered.');
|
||||
} catch (error) {
|
||||
console.error('Error registering commands:', error);
|
||||
}
|
||||
});
|
||||
|
||||
client.on('interactionCreate', async interaction => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
// Fix untuk /join
|
||||
if (interaction.commandName === 'join') {
|
||||
// Gunakan Defer Reply di awal
|
||||
await interaction.deferReply();
|
||||
|
||||
try {
|
||||
const channel = interaction.member.voice.channel;
|
||||
if (!channel) return interaction.editReply('Masuk ke VC dulu!');
|
||||
|
||||
joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: interaction.guildId,
|
||||
adapterCreator: interaction.guild.voiceAdapterCreator,
|
||||
selfDeaf: false,
|
||||
selfMute: false
|
||||
});
|
||||
|
||||
await interaction.editReply('Berhasil join ke Voice Channel!');
|
||||
} catch (error) {
|
||||
// Anti-Stuck: Tangkap error agar tidak diam saja
|
||||
await interaction.editReply('Error: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix untuk /testsahur
|
||||
if (interaction.commandName === 'testsahur') {
|
||||
// Gunakan Defer Reply di awal
|
||||
await interaction.deferReply();
|
||||
|
||||
try {
|
||||
const channel = interaction.member.voice.channel;
|
||||
if (!channel) return interaction.editReply('Masuk ke VC dulu!');
|
||||
|
||||
const connection = joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: interaction.guildId,
|
||||
adapterCreator: interaction.guild.voiceAdapterCreator,
|
||||
selfDeaf: false,
|
||||
selfMute: false
|
||||
});
|
||||
|
||||
// Direct Path
|
||||
const filePath = './assets/audio/sahur.mp3';
|
||||
|
||||
// Verify File
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return interaction.editReply('Error: File tidak ditemukan di assets/audio!');
|
||||
}
|
||||
|
||||
// Hapus Stream Kompleks & Gunakan Jalur Langsung
|
||||
const resource = createAudioResource('./assets/audio/sahur.mp3', {
|
||||
inputType: StreamType.Arbitrary,
|
||||
inlineVolume: true
|
||||
});
|
||||
|
||||
// Debug Status
|
||||
console.log('Resource Readable:', resource.readable);
|
||||
console.log('Connection Status:', connection.state.status);
|
||||
|
||||
// Kabel Utama (Subscribe)
|
||||
const subscription = connection.subscribe(player);
|
||||
player.play(resource);
|
||||
|
||||
await interaction.editReply('🔊 Sedang memutar sahur.mp3...');
|
||||
} catch (error) {
|
||||
// Anti-Stuck: Tangkap error agar tidak diam saja
|
||||
await interaction.editReply('Error: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Interaction Timeout Fix: Jika belum dibalas atau di-defer
|
||||
if (!interaction.replied && !interaction.deferred) {
|
||||
try {
|
||||
await interaction.reply('Sedang diproses...');
|
||||
} catch (err) {
|
||||
console.error('Fallback reply failed:', err.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
client.login(token);
|
||||
405
index.php
405
index.php
@ -1,150 +1,279 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
@ini_set('display_errors', '1');
|
||||
@error_reporting(E_ALL);
|
||||
@date_default_timezone_set('UTC');
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
function get_setting($key) {
|
||||
$stmt = db()->prepare("SELECT setting_value FROM bot_settings WHERE setting_key = ?");
|
||||
$stmt->execute([$key]);
|
||||
return $stmt->fetchColumn() ?: '';
|
||||
}
|
||||
|
||||
function save_setting($key, $value) {
|
||||
$stmt = db()->prepare("UPDATE bot_settings SET setting_value = ? WHERE setting_key = ?");
|
||||
$stmt->execute([$value, $key]);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$token = $_POST['discord_token'] ?? '';
|
||||
$guild = $_POST['guild_id'] ?? '';
|
||||
$channel = $_POST['voice_channel_id'] ?? '';
|
||||
$alarm = $_POST['alarm_time'] ?? '';
|
||||
|
||||
save_setting('discord_token', $token);
|
||||
save_setting('guild_id', $guild);
|
||||
save_setting('voice_channel_id', $channel);
|
||||
save_setting('alarm_time', $alarm);
|
||||
|
||||
// Also update JSON for the bot
|
||||
$config = [
|
||||
'discord_token' => $token,
|
||||
'guild_id' => $guild,
|
||||
'voice_channel_id' => $channel,
|
||||
'alarm_time' => $alarm,
|
||||
'last_voice_channel' => json_decode(get_setting('last_voice_channel'), true) ?: null
|
||||
];
|
||||
if (!is_dir(__DIR__ . '/data')) mkdir(__DIR__ . '/data', 0775, true);
|
||||
file_put_contents(__DIR__ . '/data/config.json', json_encode($config, JSON_PRETTY_PRINT));
|
||||
|
||||
$message = 'Configuration saved successfully!';
|
||||
}
|
||||
|
||||
$token = get_setting('discord_token');
|
||||
$guildId = get_setting('guild_id');
|
||||
$voiceId = get_setting('voice_channel_id');
|
||||
$alarmTime = get_setting('alarm_time');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>New Style</title>
|
||||
<?php
|
||||
// Read project preview data from environment
|
||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
?>
|
||||
<?php if ($projectDescription): ?>
|
||||
<!-- Meta description -->
|
||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
||||
<!-- Open Graph meta tags -->
|
||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<!-- Twitter meta tags -->
|
||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<?php endif; ?>
|
||||
<?php if ($projectImageUrl): ?>
|
||||
<!-- Open Graph image -->
|
||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<!-- Twitter image -->
|
||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<?php endif; ?>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes bg-pan {
|
||||
0% { background-position: 0% 0%; }
|
||||
100% { background-position: 100% 100%; }
|
||||
}
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.loader {
|
||||
margin: 1.25rem auto 1.25rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.hint {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap; border: 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 1rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
code {
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Discord Alarm Sahur — Dashboard</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-bg: #f8f9fa;
|
||||
--surface-bg: #ffffff;
|
||||
--border-color: #e5e5e5;
|
||||
--text-main: #111111;
|
||||
--text-muted: #666666;
|
||||
--accent: #007aff;
|
||||
}
|
||||
body {
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
background-color: var(--primary-bg);
|
||||
color: var(--text-main);
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
.container { max-width: 600px; }
|
||||
.card {
|
||||
background: var(--surface-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.card-header {
|
||||
background: transparent;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding: 1rem 1.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: var(--text-main);
|
||||
border-color: var(--text-main);
|
||||
border-radius: 4px;
|
||||
padding: 0.5rem 1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #333;
|
||||
border-color: #333;
|
||||
}
|
||||
.form-control {
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 0.6rem;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.1);
|
||||
}
|
||||
.status-dot {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
background-color: #ccc;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.status-online { background-color: #28a745; }
|
||||
.audio-preview {
|
||||
background: #f1f1f1;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
h1 { font-size: 1.5rem; font-weight: 600; margin-bottom: 1.5rem; }
|
||||
.hint { font-size: 0.85rem; color: var(--text-muted); margin-top: 0.25rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<div class="container">
|
||||
<?php
|
||||
$bot_status = 'Offline';
|
||||
$bot_running = false;
|
||||
$pm2_output = [];
|
||||
exec("sudo -u ubuntu /usr/bin/pm2 jlist", $pm2_output);
|
||||
$pm2_data = json_decode(implode('', $pm2_output), true);
|
||||
if ($pm2_data) {
|
||||
foreach ($pm2_data as $proc) {
|
||||
if ($proc['name'] === 'discord-bot') {
|
||||
$bot_status = ucfirst($proc['pm2_env']['status']);
|
||||
$bot_running = ($proc['pm2_env']['status'] === 'online');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<header class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Alarm Sahur Bot</h1>
|
||||
<div class="small text-muted">
|
||||
<span class="status-dot <?= $bot_running ? 'status-online' : '' ?>"></span>
|
||||
Bot: <strong><?= $bot_status ?></strong>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-success py-2 px-3 small border-0 rounded-1 mb-4" role="alert">
|
||||
<?= htmlspecialchars($message) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||
<div class="card-header">Configuration</div>
|
||||
<div class="card-body">
|
||||
<form method="POST">
|
||||
<div class="mb-3">
|
||||
<label class="form-label small fw-medium">Discord Bot Token</label>
|
||||
<input type="password" name="discord_token" class="form-control" value="<?= htmlspecialchars($token) ?>" placeholder="MTAyMzQ1Njc4OTAxMjM0NTY3OA...">
|
||||
<div class="hint">Obtained from Discord Developer Portal.</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label small fw-medium">Guild ID</label>
|
||||
<input type="text" name="guild_id" class="form-control" value="<?= htmlspecialchars($guildId) ?>" placeholder="1234567890...">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label small fw-medium">Voice Channel ID</label>
|
||||
<input type="text" name="voice_channel_id" class="form-control" value="<?= htmlspecialchars($voiceId) ?>" placeholder="9876543210...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small fw-medium">Alarm Time (HH:MM)</label>
|
||||
<input type="time" name="alarm_time" class="form-control" value="<?= htmlspecialchars($alarmTime) ?>">
|
||||
<div class="hint">Bot will automatically join the voice channel and play audio at this time.</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 mt-2">Save Configuration</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">Bot Controls</div>
|
||||
<div class="card-body">
|
||||
<p class="small text-muted mb-3">Use these controls to manage the bot process. If the bot is not responding, try resetting it.</p>
|
||||
<button id="resetBotBtn" class="btn btn-outline-danger w-100 fw-medium">
|
||||
<span id="btnText">Reset Bot Process</span>
|
||||
<span id="btnLoader" class="spinner-border spinner-border-sm d-none" role="status" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div id="resetStatus" class="hint mt-2 text-center d-none"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<span>Audio Asset</span>
|
||||
<a href="audio_assets.php" class="btn btn-sm btn-outline-primary">Manage</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="audio-preview">
|
||||
<span class="small fw-medium">sahur.mp3</span>
|
||||
<audio id="sahurPlayer" src="assets/audio/sahur.mp3?v=<?= time() ?>"></audio>
|
||||
<button class="btn btn-sm btn-outline-dark" onclick="document.getElementById('sahurPlayer').play()">Preview</button>
|
||||
</div>
|
||||
<div class="hint mt-2">File located at <code>assets/audio/sahur.mp3</code>.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">Quick Start</div>
|
||||
<div class="card-body small">
|
||||
<ol class="ps-3 mb-0">
|
||||
<li>Configure the Token and Channel IDs above.</li>
|
||||
<li>Ensure <code>node_modules</code> are installed (run <code>npm install</code>).</li>
|
||||
<li>Start the bot via <code>node index.js</code>.</li>
|
||||
<li>Use <code>/testsahur</code> in your Discord server.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="text-center mt-5">
|
||||
<p class="small text-muted">Flatlogic LAMP Engineer © <?= date('Y') ?></p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document.getElementById('resetBotBtn').addEventListener('click', function() {
|
||||
const btn = this;
|
||||
const btnText = document.getElementById('btnText');
|
||||
const btnLoader = document.getElementById('btnLoader');
|
||||
const statusDiv = document.getElementById('resetStatus');
|
||||
|
||||
if (!confirm('Are you sure you want to restart the bot process?')) return;
|
||||
|
||||
btn.disabled = true;
|
||||
btnText.classList.add('d-none');
|
||||
btnLoader.classList.remove('d-none');
|
||||
statusDiv.classList.add('d-none');
|
||||
|
||||
fetch('api/reset_bot.php', {
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
btn.disabled = false;
|
||||
btnText.classList.remove('d-none');
|
||||
btnLoader.classList.add('d-none');
|
||||
statusDiv.classList.remove('d-none');
|
||||
|
||||
if (data.success) {
|
||||
statusDiv.className = 'hint mt-2 text-center text-success';
|
||||
statusDiv.textContent = data.message + '. Refreshing page...';
|
||||
setTimeout(() => location.reload(), 2000);
|
||||
} else {
|
||||
statusDiv.className = 'hint mt-2 text-center text-danger';
|
||||
statusDiv.textContent = 'Error: ' + (data.error || 'Unknown error');
|
||||
console.error(data.details);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
btn.disabled = false;
|
||||
btnText.classList.remove('d-none');
|
||||
btnLoader.classList.add('d-none');
|
||||
statusDiv.classList.remove('d-none');
|
||||
statusDiv.className = 'hint mt-2 text-center text-danger';
|
||||
statusDiv.textContent = 'Network error occurred.';
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
953
package-lock.json
generated
Normal file
953
package-lock.json
generated
Normal file
@ -0,0 +1,953 @@
|
||||
{
|
||||
"name": "alarm-sahur-bot",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "alarm-sahur-bot",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@discordjs/opus": "^0.10.0",
|
||||
"@discordjs/voice": "^0.19.0",
|
||||
"discord.js": "^14.15.3",
|
||||
"ffmpeg-static": "^5.3.0",
|
||||
"libsodium-wrappers": "^0.7.16",
|
||||
"opusscript": "^0.1.1",
|
||||
"play-dl": "^1.9.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@derhuerst/http-basic": {
|
||||
"version": "8.2.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caseless": "^0.12.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"http-response-object": "^3.0.1",
|
||||
"parse-cache-control": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.13.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.6.2",
|
||||
"@discordjs/util": "^1.2.0",
|
||||
"@sapphire/shapeshift": "^4.0.0",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.4",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "1.5.3",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.6.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.33"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/node-pre-gyp": {
|
||||
"version": "0.4.5",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"make-dir": "^3.1.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"nopt": "^5.0.0",
|
||||
"npmlog": "^5.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11"
|
||||
},
|
||||
"bin": {
|
||||
"node-pre-gyp": "bin/node-pre-gyp"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/opus": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/opus/-/opus-0.10.0.tgz",
|
||||
"integrity": "sha512-HHEnSNrSPmFEyndRdQBJN2YE6egyXS9JUnJWyP6jficK0Y+qKMEZXyYTgmzpjrxXP1exM/hKaNP7BRBUEWkU5w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@discordjs/node-pre-gyp": "^0.4.5",
|
||||
"node-addon-api": "^8.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.6.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.1",
|
||||
"@discordjs/util": "^1.1.1",
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.1",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.33"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/voice": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.19.0.tgz",
|
||||
"integrity": "sha512-UyX6rGEXzVyPzb1yvjHtPfTlnLvB5jX/stAMdiytHhfoydX+98hfympdOwsnTktzr+IRvphxTbdErgYDJkEsvw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/ws": "^8.18.1",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"prism-media": "^1.3.5",
|
||||
"tslib": "^2.8.1",
|
||||
"ws": "^8.18.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/voice/node_modules/opusscript": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz",
|
||||
"integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@discordjs/voice/node_modules/prism-media": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.5.tgz",
|
||||
"integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@discordjs/opus": ">=0.8.0 <1.0.0",
|
||||
"ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0",
|
||||
"node-opus": "^0.3.3",
|
||||
"opusscript": "^0.0.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@discordjs/opus": {
|
||||
"optional": true
|
||||
},
|
||||
"ffmpeg-static": {
|
||||
"optional": true
|
||||
},
|
||||
"node-opus": {
|
||||
"optional": true
|
||||
},
|
||||
"opusscript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.2.3",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.0",
|
||||
"@discordjs/rest": "^2.5.1",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@sapphire/async-queue": "^1.5.2",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.4",
|
||||
"discord-api-types": "^0.38.1",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.1",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.5",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "4.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v16"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
"version": "3.5.3",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.2.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.18.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vladfrangu/async_event_emitter": {
|
||||
"version": "2.4.7",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "2.1.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/are-we-there-yet": {
|
||||
"version": "2.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/caseless": {
|
||||
"version": "0.12.0",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "2.0.0",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"color-support": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.38.39",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.39.tgz",
|
||||
"integrity": "sha512-XRdDQvZvID1XvcFftjSmd4dcmMi/RL/jSy5sduBDAvCGFcNFHThdIQXCEBDZFe52lCNEzuIL0QJoKYAmRmxLUA==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"scripts/actions/documentation"
|
||||
]
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.25.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.13.0",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.6.2",
|
||||
"@discordjs/rest": "^2.6.0",
|
||||
"@discordjs/util": "^1.2.0",
|
||||
"@discordjs/ws": "^1.2.3",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/env-paths": {
|
||||
"version": "2.2.1",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ffmpeg-static": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.3.0.tgz",
|
||||
"integrity": "sha512-H+K6sW6TiIX6VGend0KQwthe+kaceeH/luE8dIZyOP35ik7ahYojDuqlTV1bOrtEwl01sy2HFNGQfi5IDJvotg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@derhuerst/http-basic": "^8.2.0",
|
||||
"env-paths": "^2.2.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"progress": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass/node_modules/minipass": {
|
||||
"version": "3.3.6",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "3.0.2",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"aproba": "^1.0.3 || ^2.0.0",
|
||||
"color-support": "^1.1.2",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wide-align": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/http-response-object": {
|
||||
"version": "3.0.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^10.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/http-response-object/node_modules/@types/node": {
|
||||
"version": "10.17.60",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/libsodium": {
|
||||
"version": "0.7.16",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/libsodium-wrappers": {
|
||||
"version": "0.7.16",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.16.tgz",
|
||||
"integrity": "sha512-Gtr/WBx4dKjvRL1pvfwZqu7gO6AfrQ0u9vFL+kXihtHf6NfkROR8pjYWn98MFDI3jN19Ii1ZUfPR9afGiPyfHg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"libsodium": "^0.7.16"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.23",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.snakecase": {
|
||||
"version": "4.1.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-bytes.js": {
|
||||
"version": "1.13.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "5.0.0",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib": {
|
||||
"version": "2.1.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib/node_modules/minipass": {
|
||||
"version": "3.3.6",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "8.5.0",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18 || ^20 || >= 21"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "5.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"abbrev": "1"
|
||||
},
|
||||
"bin": {
|
||||
"nopt": "bin/nopt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/npmlog": {
|
||||
"version": "5.0.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"are-we-there-yet": "^2.0.0",
|
||||
"console-control-strings": "^1.1.0",
|
||||
"gauge": "^3.0.0",
|
||||
"set-blocking": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/opusscript": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.1.1.tgz",
|
||||
"integrity": "sha512-mL0fZZOUnXdZ78woRXp18lApwpp0lF5tozJOD1Wut0dgrA9WuQTgSels/CSmFleaAZrJi/nci5KOVtbuxeWoQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/parse-cache-control": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/play-audio": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/play-audio/-/play-audio-0.5.2.tgz",
|
||||
"integrity": "sha512-ZAqHUKkQLix2Iga7pPbsf1LpUoBjcpwU93F1l3qBIfxYddQLhxS6GKmS0d3jV8kSVaUbr6NnOEcEMFvuX93SWQ==",
|
||||
"license": "GPL-3.0"
|
||||
},
|
||||
"node_modules/play-dl": {
|
||||
"version": "1.9.7",
|
||||
"resolved": "https://registry.npmjs.org/play-dl/-/play-dl-1.9.7.tgz",
|
||||
"integrity": "sha512-KpgerWxUCY4s9Mhze2qdqPhiqd8Ve6HufpH9mBH3FN+vux55qSh6WJKDabfie8IBHN7lnrAlYcT/UdGax58c2A==",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"play-audio": "^0.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "6.2.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^5.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.4",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.21.3",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.16.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align": {
|
||||
"version": "1.1.5",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.19.0",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
package.json
Normal file
15
package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "alarm-sahur-bot",
|
||||
"version": "1.0.0",
|
||||
"description": "Discord Alarm Sahur Bot",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@discordjs/opus": "^0.10.0",
|
||||
"@discordjs/voice": "^0.19.0",
|
||||
"discord.js": "^14.15.3",
|
||||
"ffmpeg-static": "^5.3.0",
|
||||
"libsodium-wrappers": "^0.7.16",
|
||||
"opusscript": "^0.1.1",
|
||||
"play-dl": "^1.9.7"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user