2026-05-13 01:12:11 +07:00
|
|
|
import "./mock-crc";
|
2026-05-13 02:30:09 +07:00
|
|
|
import "libsodium-wrappers";
|
|
|
|
|
import "@snazzah/davey";
|
2026-05-13 15:28:25 +07:00
|
|
|
import { getVoiceConnection } from "@discordjs/voice";
|
2026-05-12 19:38:23 +07:00
|
|
|
import { Client } from "discord.js-selfbot-v13";
|
|
|
|
|
import { config } from "./config";
|
2026-05-13 00:32:27 +07:00
|
|
|
import { discordPlayer } from "./player";
|
2026-05-13 15:28:25 +07:00
|
|
|
import { startRecording } from "./recorder";
|
|
|
|
|
import { startWebserver } from "./webserver";
|
2026-05-13 16:25:01 +07:00
|
|
|
import { createChildLogger } from "./logger";
|
|
|
|
|
import { retryWithBackoff } from "./retry";
|
|
|
|
|
|
|
|
|
|
const logger = createChildLogger("bot");
|
2026-05-12 19:38:23 +07:00
|
|
|
|
|
|
|
|
// Validasi environment variables
|
|
|
|
|
const token = process.env.DISCORD_TOKEN;
|
|
|
|
|
const voiceChannelId = process.env.VOICE_CHANNEL_ID;
|
|
|
|
|
const guildId = process.env.GUILD_ID;
|
|
|
|
|
|
|
|
|
|
if (!token) throw new Error("Missing DISCORD_TOKEN in .env");
|
|
|
|
|
if (!voiceChannelId) throw new Error("Missing VOICE_CHANNEL_ID in .env");
|
|
|
|
|
if (!guildId) throw new Error("Missing GUILD_ID in .env");
|
|
|
|
|
|
2026-05-13 16:25:01 +07:00
|
|
|
// Inisialisasi selfbot client
|
2026-05-12 19:38:23 +07:00
|
|
|
const client = new Client();
|
|
|
|
|
|
|
|
|
|
client.on("ready", async () => {
|
2026-05-13 15:28:25 +07:00
|
|
|
if (config.verbose) {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.info({ user: client.user?.tag }, "Bot logged in");
|
2026-05-13 15:28:25 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ambil guild
|
|
|
|
|
const guild = client.guilds.cache.get(guildId!);
|
|
|
|
|
if (!guild) {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.error({ guildId }, "Guild not found");
|
2026-05-13 15:28:25 +07:00
|
|
|
process.exit(1);
|
|
|
|
|
}
|
2026-05-12 19:38:23 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
// Fetch channels jika belum ada di cache
|
|
|
|
|
const channel =
|
|
|
|
|
guild.channels.cache.get(voiceChannelId!) ??
|
|
|
|
|
(await guild.channels.fetch(voiceChannelId!).catch(() => null));
|
2026-05-12 19:38:23 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
if (!channel || channel.type !== "GUILD_VOICE") {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.error({ voiceChannelId }, "Voice channel not found or wrong type");
|
2026-05-13 15:28:25 +07:00
|
|
|
process.exit(1);
|
|
|
|
|
}
|
2026-05-12 19:38:23 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
if (config.verbose) {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.info(
|
|
|
|
|
{ channelName: channel.name, channelId: channel.id },
|
|
|
|
|
"Joining voice channel",
|
2026-05-13 15:28:25 +07:00
|
|
|
);
|
|
|
|
|
}
|
2026-05-13 16:25:01 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
await startRecording(client, channel as any);
|
2026-05-12 19:38:23 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
// Set up player connection
|
|
|
|
|
const connection = getVoiceConnection(guildId!);
|
|
|
|
|
if (connection) {
|
|
|
|
|
discordPlayer.setConnection(connection);
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.info("Player connected to voice channel");
|
2026-05-13 15:28:25 +07:00
|
|
|
}
|
2026-05-13 00:32:27 +07:00
|
|
|
|
2026-05-13 15:28:25 +07:00
|
|
|
// Start Webserver
|
2026-05-13 16:05:19 +07:00
|
|
|
startWebserver(config.webserverPort);
|
2026-05-12 19:38:23 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
client.on("error", (err) => {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.error({ error: err }, "Client error");
|
2026-05-12 19:38:23 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Graceful shutdown
|
|
|
|
|
process.on("SIGINT", () => {
|
2026-05-13 15:28:25 +07:00
|
|
|
if (config.verbose) {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.info("Shutting down gracefully...");
|
2026-05-13 15:28:25 +07:00
|
|
|
}
|
|
|
|
|
client.destroy();
|
|
|
|
|
process.exit(0);
|
2026-05-12 19:38:23 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
process.on("SIGTERM", () => {
|
2026-05-13 15:28:25 +07:00
|
|
|
if (config.verbose) {
|
2026-05-13 16:25:01 +07:00
|
|
|
logger.info("Terminating...");
|
2026-05-13 15:28:25 +07:00
|
|
|
}
|
|
|
|
|
client.destroy();
|
|
|
|
|
process.exit(0);
|
2026-05-12 19:38:23 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
client.login(token);
|