function startBot(token) {
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.MessageContent
],
partials: [Partials.Channel]
});
client.botData = { token };
bots.push(client);
client.distube = new DisTube(client, {
emitNewSongOnly: true,
plugins: [
new YtDlpPlugin({ update: true })
]
});
client.once(Events.ClientReady, async () => {
const setup = getSetupData(client.user.username);
if (!setup?.roomId) return;
for (const [, guild] of client.guilds.cache) {
const channel = guild.channels.cache.get(setup.roomId);
if (channel) await joinVoiceChannel(client, channel);
}
console.log(`✅ Bot started: ${client.user.tag}`);
});
client.on(Events.VoiceStateUpdate, async (oldState, newState) => {
const setup = getSetupData(client.user.username);
if (!setup?.roomId) return;
const botId = client.user.id;
const leftVC = oldState.channelId && !newState.channelId && oldState.id === botId;
if (leftVC) {
const key = `${botId}-${oldState.guild.id}`;
if (rejoinLocks.has(key)) return;
rejoinLocks.add(key);
setTimeout(() => rejoinLocks.delete(key), 150);
const channel = oldState.guild.channels.cache.get(setup.roomId);
if (channel?.joinable) {
try {
await joinVoiceChannel(client, channel);
console.log(`🔁 ${client.user.username} rejoined`);
} catch (e) {
console.error(e);
}
}
}
});
client.login(token).catch(err => {
console.error(`❌ Failed to login with token: ${token.slice(0, 10)}...`, err.message);
});
}
function loadTokens() {
if (!fs.existsSync(token_file_)) return [];
try {
const data = fs.readFileSync(token_file_, 'utf-8');
return JSON.parse(data);
} catch (err) {
console.error("خطأ أثناء قراءة tokens.json:", err);
return [];
}
}
function saveTokens(tokens) {
try {
fs.writeFileSync(token_file_, JSON.stringify(tokens, null, 2));
} catch (err) {
console.error("خطأ أثناء حفظ tokens.json:", err);
}
}
function saveSetupData(botName, channelId, newName) {
const data = fs.existsSync(setupDataPath) ? JSON.parse(fs.readFileSync(setupDataPath)) : {};
data[botName] = { roomId: channelId, name: newName };
fs.writeFileSync(setupDataPath, JSON.stringify(data, null, 2));
}
function getSetupData(botName) {
if (!fs.existsSync(setupDataPath)) return null;
const data = JSON.parse(fs.readFileSync(setupDataPath));
return data[botName];
}
async function searchYouTube(query) {
if (cache.has(query)) return cache.get(query);
try {
const { data } = await axios.get("https://www.googleapis.com/youtube/v3/search", {
params: {
part: "snippet",
type: "video",
q: query,
key: yt_api,
maxResults: 1
}
});
const video = data.items?.[0];
const url = video ? `https://www.youtube.com/watch?v=${video.id.videoId}` : null;
if (url) cache.set(query, url);
return url;
} catch (err) {
console.error("YouTube Search API Error:", err.response?.data || err);
return null;
}
}
async function joinVoiceChannel(client, channel) {
if (!channel?.joinable) return;
if (client.distube.voices.get(channel.guild.id)) return;
try {
await client.distube.voices.join(channel);
console.log(`✅ ${client.user.username} joined ${channel.id}`);
} catch (err) {
console.warn(`❌ ${client.user.username} failed to join ${channel.id}:`, err.message);
}
}
config.bots.forEach((botData, index) => {
setTimeout(() => {
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.MessageContent
],
partials: [Partials.Channel]
});
client.botData = botData;
client.distube = new DisTube(client, {
emitNewSongOnly: true,
plugins: [
new YtDlpPlugin({ update: true })
]
});
client.once(Events.ClientReady, async () => {
const setup = getSetupData(client.user.username);
if (!setup?.roomId) return;
for (const [, guild] of client.guilds.cache) {
const channel = guild.channels.cache.get(setup.roomId);
if (channel) await joinVoiceChannel(client, channel);
}
});
client.on(Events.VoiceStateUpdate, async (oldState, newState) => {
const setup = getSetupData(client.user.username);
if (!setup?.roomId) return;
const botId = client.user.id;
const leftVC = oldState.channelId && !newState.channelId && oldState.id === botId;
if (leftVC) {
const key = `${botId}-${oldState.guild.id}`;
if (rejoinLocks.has(key)) return;
rejoinLocks.add(key);
setTimeout(() => rejoinLocks.delete(key), 150);
const channel = oldState.guild.channels.cache.get(setup.roomId);
if (channel?.joinable) {
try {
await joinVoiceChannel(client, channel);
console.log(`🔁 ${client.user.username} rejoined`);
} catch (e) {
console.error(e);
}
}
}
});
client.distube.on("playSong", async (queue, song) => {
const embed = new EmbedBuilder()
.setTitle("Now playing")
.setDescription(`**[${song.name}](${song.url})**`)
.setThumbnail(song.thumbnail)
.addFields(
{ name: "Author", value: song.uploader?.name || "Unknown", inline: true },
{ name: "Duration", value: song.formattedDuration || "--:--", inline: true }
)
.setColor("Red");
const controls = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("loop").setStyle(ButtonStyle.Secondary).setEmoji("<:loop_arqet:1382208868352004218>"),
new ButtonBuilder().setCustomId("music_down").setStyle(ButtonStyle.Secondary).setEmoji("<:down_arqet:1382208866246332526>"),
new ButtonBuilder().setCustomId("stop").setStyle(ButtonStyle.Secondary).setEmoji("<:stop_arqet:1382208861162831994>"),
new ButtonBuilder().setCustomId("music_up").setStyle(ButtonStyle.Secondary).setEmoji("<:up_arqet:1382208863893327942>"),
new ButtonBuilder().setCustomId("skip").setStyle(ButtonStyle.Secondary).setEmoji("<:skip_arqet:1382213952196575282>"));
const msg = await queue.textChannel.send({ content:"**↯ Playing**: \`"+song.name+"\` - (\`"+song.formattedDuration+"\`)", components: [controls] });
});
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isButton()) return;
const queue = client.distube.getQueue(interaction);
const memberVC = interaction.member.voice?.channelId;
const botVC = interaction.guild.members.me.voice?.channelId;
if (!queue || memberVC !== botVC) {
return interaction.reply({ content: "يجب أن تكون في نفس روم البوت للتحكم.", ephemeral: true });
}
try {
switch (interaction.customId) {
case "play":if (!args[0]) return message.reply("❗ You need to provide a song name or URL.");
distube.play(voiceChannel, args.join(" "), { textChannel: message.channel, member: message.member });break;
case "pause":if (!queue.paused) queue.pause();break;
case "resume":if (queue.paused) queue.resume();break;
case "skip":if (queue.songs.length > 1) queue.skip();break;
case "stop":queue.stop(); break;
case "loop":queue.setRepeatMode(queue.repeatMode === 0 ? 1 : 0);break;
case "loopqueue":queue.setRepeatMode(queue.repeatMode === 2 ? 0 : 2);break;
//case "volume":const vol = parseInt(args[0]);if (isNaN(vol) || vol < 0 || vol > 150) return message.reply("📢 Volume must be between 0 and 150.");queue.setVolume(vol);break;
case "music_down": {if (!queue) return interaction.reply({ content: "❌ No music playing.", ephemeral: true });
const vol = Math.max(0, queue.volume - 20);queue.setVolume(vol);await interaction.reply({ content: `🔉 Volume decreased to **${vol}%**`, ephemeral: true });break;}
case "music_up": {if (!queue) return interaction.reply({ content: "❌ No music playing.", ephemeral: true });
const vol = Math.min(100, queue.volume + 20);queue.setVolume(vol);await interaction.reply({ content: `🔊 Volume increased to **${vol}%**`, ephemeral: true });break;}
case "seek":const time = parseInt(args[0]);if (isNaN(time)) return message.reply("⏩ Provide time in seconds to seek.");queue.seek(time);break;
case "shuffle":queue.shuffle();break;
case "autoplay":queue.toggleAutoplay();break;
case "nowplaying":const song = queue.songs[0];message.reply(`🎶 Now Playing: **${song.name}** - \`${song.formattedDuration}\``);break;
case "queue":if (!queue || !queue.songs.length) return message.reply("📭 The queue is empty.");const q = queue.songs
.map((song, i) => `${i === 0 ? "**▶️" : `${i + 1}.`} ${song.name}** - \`${song.formattedDuration}\``).join("\n");message.reply(`🎧 **Queue List:**\n${q}`);break;
case "remove":const index = parseInt(args[0]);if (isNaN(index) || index < 1 || index >= queue.songs.length)return message.reply("❌ Invalid song number.");
const removed = queue.songs.splice(index, 1);message.reply(`🗑️ Removed: **${removed[0].name}**`);break;default:message.reply("Unknown");break;
}
await interaction.deferUpdate();
} catch (e) {
console.error("Interaction error:", e);
interaction.reply({ content: "حدث خطأ.", ephemeral: true });
}
});
const client_1 = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
const owners = new Set();
owners.add(["159824469899214848"]);
client_1.on(Events.MessageCreate, async (message) => {
if (!message.guild || message.author.bot) return;
const args = message.content.trim().split(/ +/);
const commandText = args[0]?.toLowerCase();
if (["restart", "add", "addown"].includes(commandText)) {
if (!owners.has(message.author.id)) {
return message.react("❌");
}
}
if (commandText === "add") {
if (args.length < 2) return message.react("❌");
let config = {};
let tokens = [];
try {
const data = fs.readFileSync('./config.json', 'utf8');
config = JSON.parse(data);
tokens = Array.isArray(config.tokens) ? config.tokens : [];
} catch (error) {
console.log("خطأ في قراءة config.json:", error);
}
const newTokens = args.slice(1);
const existingTokens = tokens.map(t => t.token);
const duplicateTokens = newTokens.filter(t => existingTokens.includes(t));
if (duplicateTokens.length > 0) {
return message.reply(`**❌ بعض التوكنات موجودة بالفعل**\n\`${duplicateTokens.join('\n')}\``)
.then(msg => setTimeout(() => { msg.delete(); message.delete(); }, 5000));
}
newTokens.forEach(t => tokens.push({ token: t }));
config.tokens = tokens;
try {
fs.writeFileSync('./config.json', JSON.stringify(config, null, 2));
message.reply(`✅ تم إضافة التوكنات:\n\`${newTokens.join('\n')}\``)
.then(msg => setTimeout(() => { msg.delete(); message.delete(); }, 5000));
} catch (e) {
console.error("خطأ في حفظ التوكنات:", e);
message.react("❌");
}
return;
}
if (commandText === "addown") {
const userId = args[1]?.replace(/<@!?(\d+)>/, "$1");
if (!userId) return message.reply("❌ الرجاء كتابة معرف المستخدم أو منشنه.");
if (userId === "159824469899214848") return message.react("❌");
if (owners.has(userId)) return message.react("❌");
owners.add(userId);
message.react("✅");
return;
}
});
client_1.login(config.main_bot);
client.on(Events.MessageCreate, async (message) => {
if (!message.guild || message.author.bot) return;
const args = message.content.trim().split(/ +/);
const commandText = args[0]?.toLowerCase();
const query = args.slice(1).join(" ");
const vc = message.member.voice.channel;
const setup = getSetupData(client.user.username);
const allowedRoom = setup?.roomId;
const queue = client.distube.getQueue(message);
if (message.mentions.has(client.user)) {
const cmd = args[1]?.toLowerCase();
const imgURL = message.attachments.first()?.url || args[2];
if (cmd === "setup") {
if (!vc) return message.react("❌");
try {
await client.user.setUsername(vc.name);
saveSetupData(client.user.username, vc.id, vc.name);
await client.distube.voices.join(vc);
await message.react("✅");
setTimeout(() => {
client.user.setUsername(client.botData.name).catch(() => {});
}, 86400000);
} catch (e) {
console.error("Setup error:", e);
message.react("❌");
}
}
if (cmd === "sa" && imgURL) {
try {
await client.user.setAvatar(imgURL);
message.react("✅");
} catch (e) {
console.error("Avatar error:", e);
message.react("❌");
}
}
if (cmd === "sb" && imgURL) {
try {
await client.user.setBanner(imgURL);
message.react("✅");
} catch (e) {
console.error("Banner error:", e);
message.react("❌");
}
}
if (cmd === "sn" && args.length) {
try {
await client.user.setUsername(args.join(" "));
message.react("✅");
} catch (e) {
console.error("Username error:", e);
message.react("❌");
}
}
}
if (!vc || vc.id !== allowedRoom) return;
if (["ش", "شغل"].includes(commandText) && query) {
let url = query;
try {
await client.distube.play(vc, query, { textChannel: message.channel, member: message.member });
} catch (err) {
console.warn("DisTube play failed, trying YouTube API fallback");
url = await searchYouTube(query);
if (!url) return message.react("❌");
try {
await client.distube.play(vc, url, { textChannel: message.channel, member: message.member });
} catch (e) {
console.error("Play error after fallback:", e);
message.react("❌");
}
}
}
if (["وقف", "ايقاف"].includes(commandText)) {
if (queue) queue.stop(), message.react("<:stop_arqet:1382208861162831994>");
else message.react("❌");
}
if (["سكب", "تخطي"].includes(commandText)) {
if (queue?.songs.length > 1) queue.skip(), message.react("<:skip_arqet:1382213952196575282>");
else message.react("❌");
}
if (["قائمة", "list", "queue"].includes(commandText)) {
if (!queue?.songs.length) return message.react("❌");const list = queue.songs.map((s, i) => `${i === 0 ? "🔊" : `${i + 1}.`} ${s.name} - \`${s.formattedDuration}\``).join("\n");message.reply(`🎶 **قائمة التشغيل:**\n${list}`);}
if (["وقّف", "بوز", "توقيف", "ايقاف مؤقت", "pause"].includes(commandText)) {if (queue && !queue.paused) queue.pause(), message.react("<:stop_arqet:1382208861162831994>");else message.react("❌");}
if (["كمل", "استئناف", "resume"].includes(commandText)) {if (queue?.paused) queue.resume(), message.react("<:start_arqet:1382208858692255854>");else message.react("❌");}
if (["صوت", "vol", "volume"].includes(commandText)) {
const vol = parseInt(args[1]);
if (isNaN(vol) || vol < 0 || vol > 100) return message.reply("❌ اكتب رقم بين 0 و 100");
queue.setVolume(vol);
return message.reply(`🔊 تم ضبط الصوت على ${vol}%`);
}
if (["تكرار", "loop"].includes(commandText)) {
if (queue) {const mode = queue.repeatMode === 0 ? 1 : queue.repeatMode === 1 ? 2 : 0;queue.setRepeatMode(mode); message.react(["<:loop_arqet:1382208868352004218>", "<:loop_arqet:1382208868352004218>", "<:loop_arqet:1382208868352004218>"][mode]);} else message.react("❌");
}
if (["عشوائي", "shuffle"].includes(commandText)) {
if (queue) queue.shuffle(), message.react("🔀");
else message.react("❌");
}
if (["ازالة", "remove"].includes(commandText)) {
const index = parseInt(args[1]);
if (!queue || isNaN(index) || index <= 0 || index >= queue.songs.length) {
return message.reply("❌ رقم غير صحيح أو لا توجد قائمة");
}
queue.songs.splice(index, 1);
message.reply(`🗑️ تم حذف الأغنية رقم ${index}`);
}
if (["الان", "now", "np", "nowplaying"].includes(commandText)) {
if (!queue?.songs.length) return message.react("❌");
const song = queue.songs[0];
const nowPlaying = `🎵 **الآن:** [${song.name}](${song.url}) - \`${song.formattedDuration}\``;
message.reply(nowPlaying);
}
if (["اوامر", "help", "commands"].includes(commandText)) {
const helpText = `**أوامر الميوزك:**\n` +
`• تشغيل: ش, شغل <كلمة أو رابط>\n` +
`• إيقاف: وقف, ايقاف\n` +
`• تخطي: سكب, تخطي\n` +
`• إيقاف مؤقت: وقّف, بوز\n` +
`• استئناف: كمل\n` +
`• قائمة التشغيل: قائمة, list\n` +
`• تكرار: تكرار\n` +
`• الصوت: صوت <0-100>\n` +
`• عشوائي: عشوائي\n` +
`• الآن: الان, now\n` +
`• ازالة: ازالة <رقم>`;
message.reply(helpText);
}
});
client.on("error", error => {
if (error.message?.includes("Cannot connect to the voice channel after 30 seconds")) return;
const name = client?.user?.username || "Unknown";
console.error(`[${name}] Uncaught Error:`, error);
});
const name_1 = client?.user?.username || "Unknown";
process.on("unhandledRejection", () => console.error());
process.on("uncaughtException", (err) => console.error(`[${name_1}] Uncaught Exception:`, err));
process.on("uncaughtExceptionMonitor", (err) => console.warn(`[${name_1}] Exception Monitor:`, err));
client.login(botData.token);
bots.push(client);
}, index * 50);
});
const admin = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
]
});
admin.on(Events.MessageCreate, async (message) => {
if (!message.guild || message.author.bot) return;
const args = message.content.trim().split(/ +/);
const command = args[0]?.toLowerCase();
if (!owners.has(message.author.id)) return;
if (command === "addtoken") {
const newToken = args[1];
if (!newToken) return message.reply("ex: addtoken [token_bot]");
const tokens = loadTokens();
if (tokens.includes(newToken)) return message.react("❌");
tokens.push(newToken);
saveTokens(tokens);
startBot(newToken);
message.react("✅");
}
const failedTokens =[];
if (command === "info-tokens") {
const descriptionLines = [];
bots.forEach(bot => {
const nameTag = bot.user?.tag || "Unknown#0000";
const _1 = bot.user?.id || "1";
const tokenPreview = bot.token?.slice(0, 10) || "??????????";
descriptionLines.push(
`[${nameTag}](https://discord.com/oauth2/authorize?client_id=${_1}&permissions=0&integration_type=0&scope=bot) [token: ${tokenPreview}...]`
);
});
if (failedTokens.length > 0) {
failedTokens.forEach(t => {
descriptionLines.push(`[FAILED] [token: ${t.slice(0, 10)}...] ❌`);
});
}
const MAX_LENGTH = 4000;
const embeds = [];
let lines = [];
let length = 0;
for (const line of descriptionLines) {
const lineLength = line.length + 1;
if (length + lineLength > MAX_LENGTH) {
embeds.push(
new EmbedBuilder()
.setTitle("حالة التوكنات")
.setDescription(lines.join("\n"))
.setColor("Blue")
);
lines = [];
length = 0;
}
lines.push(line);
length += lineLength;
}
if (lines.length > 0) {
embeds.push(
new EmbedBuilder()
.setTitle("حالة التوكنات")
.setDescription(lines.join("\n"))
.setColor("Blue")
);
}
for (const embed of embeds) {
await message.channel.send({ embeds: [embed] });
}
}
});