Untitled

 avatar
unknown
javascript
2 years ago
19 kB
13
Indexable
const Discord = require('discord.js');
const fs = require('fs');
const axios = require('axios');

const { Manager } = require("erela.js");
const Spotify = require("erela.js-spotify");
const Facebook = require("erela.js-facebook");
const Deezer = require("erela.js-deezer");
const AppleMusic = require("erela.js-apple");

// Discord client
const client = new Discord.Client({
    allowedMentions: {
        parse: [
            'users',
            'roles'
        ],
        repliedUser: true
    },
    autoReconnect: true,
    disabledEvents: [
        "TYPING_START"
    ],
    partials: [
        Discord.Partials.Channel,
        Discord.Partials.GuildMember,
        Discord.Partials.Message,
        Discord.Partials.Reaction,
        Discord.Partials.User,
        Discord.Partials.GuildScheduledEvent
    ],
    intents: [
        Discord.GatewayIntentBits.Guilds,
        Discord.GatewayIntentBits.GuildMembers,
        Discord.GatewayIntentBits.GuildBans,
        Discord.GatewayIntentBits.GuildEmojisAndStickers,
        Discord.GatewayIntentBits.GuildIntegrations,
        Discord.GatewayIntentBits.GuildWebhooks,
        Discord.GatewayIntentBits.GuildInvites,
        Discord.GatewayIntentBits.GuildVoiceStates,
        Discord.GatewayIntentBits.GuildMessages,
        Discord.GatewayIntentBits.GuildMessageReactions,
        Discord.GatewayIntentBits.GuildMessageTyping,
        Discord.GatewayIntentBits.DirectMessages,
        Discord.GatewayIntentBits.DirectMessageReactions,
        Discord.GatewayIntentBits.DirectMessageTyping,
        Discord.GatewayIntentBits.GuildScheduledEvents,
        Discord.GatewayIntentBits.MessageContent
    ],
    restTimeOffset: 0
});


const clientID = process.env.SPOTIFY_CLIENT_ID;
const clientSecret = process.env.SPOTIFY_CLIENT_SECRET;
if (clientID && clientSecret) {
    // Lavalink client
    client.player = new Manager({
        plugins: [
            new AppleMusic(),
            new Deezer(),
            new Facebook(),
            new Spotify({
                clientID,
                clientSecret,
            })
        ],
        nodes: [
            {
                host: 'lava.link',
                port: 80,
                password: 'youshallnotpass',
                secure: false
            },
            {
                host: process.env.LAVALINK_HOST,
                port: parseInt(process.env.LAVALINK_PORT),
                password: process.env.LAVALINK_PASSWORD,
                secure: Boolean(process.env.LAVALINK_SECURE)
            },
        ],
        send(id, payload) {
            const guild = client.guilds.cache.get(id);
            if (guild) guild.shard.send(payload);
        },
    })

} else {
    // Lavalink client
    client.player = new Manager({
        plugins: [
            new AppleMusic(),
            new Deezer(),
            new Facebook(),
            new Spotify({
                clientID,
                clientSecret,
            })
        ],
        nodes: [
            {
                host: 'lava.link',
                port: 80,
                password: 'youshallnotpass',
                secure: false
            },
            {
                host: process.env.LAVALINK_HOST,
                port: parseInt(process.env.LAVALINK_PORT),
                password: process.env.LAVALINK_PASSWORD,
                secure: Boolean(process.env.LAVALINK_SECURE)
            },
        ],
        send(id, payload) {
            const guild = client.guilds.cache.get(id);
            if (guild) guild.shard.send(payload);
        }
    })
}
const events = fs.readdirSync(`./src/events/music`).filter(files => files.endsWith('.js'));

for (const file of events) {
    const event = require(`./events/music/${file}`);
    client.player.on(file.split(".")[0], event.bind(null, client)).setMaxListeners(0);
};

// Connect to database
require("./database/connect")();

// Client settings
client.config = require('./config/bot');
client.changelogs = require('./config/changelogs');
client.emotes = require("./config/emojis.json");
client.webhooks = require("./config/webhooks.json");
const webHooksArray = ['startLogs', 'shardLogs', 'errorLogs', 'dmLogs', 'voiceLogs', 'serverLogs', 'serverLogs2', 'commandLogs', 'consoleLogs', 'warnLogs', 'voiceErrorLogs', 'creditLogs', 'evalLogs', 'interactionLogs'];
// Check if .env webhook_id and webhook_token are set
if (process.env.WEBHOOK_ID && process.env.WEBHOOK_TOKEN) {
    for (const webhookName of webHooksArray) {
        client.webhooks[webhookName].id = process.env.WEBHOOK_ID;
        client.webhooks[webhookName].token = process.env.WEBHOOK_TOKEN;
    }
}

client.commands = new Discord.Collection();
client.playerManager = new Map();
client.triviaManager = new Map();
client.queue = new Map();

// Webhooks
const consoleLogs = new Discord.WebhookClient({
    id: client.webhooks.consoleLogs.id,
    token: client.webhooks.consoleLogs.token,
});

const warnLogs = new Discord.WebhookClient({
    id: client.webhooks.warnLogs.id,
    token: client.webhooks.warnLogs.token,
});

// Load handlers
fs.readdirSync('./src/handlers').forEach((dir) => {
    fs.readdirSync(`./src/handlers/${dir}`).forEach((handler) => {
        require(`./handlers/${dir}/${handler}`)(client);
    });
});

client.login(process.env.DISCORD_TOKEN);

process.on('unhandledRejection', error => {
    console.error('Unhandled promise rejection:', error);
    if (error) if (error.length > 950) error = error.slice(0, 950) + '... schau in die Konsole für Details';
    if (error.stack) if (error.stack.length > 950) error.stack = error.stack.slice(0, 950) + '... schau in die Konsole für Details';
    if(!error.stack) return
    const embed = new Discord.EmbedBuilder()
        .setTitle(`🚨・Unhandled promise rejection`)
        .addFields([
            {
                name: "Error",
                value: error ? Discord.codeBlock(error) : "Kein Error",
            },
            {
                name: "Stack error",
                value: error.stack ? Discord.codeBlock(error.stack) : "Kein stack error",
            }
        ])
        .setColor(client.config.colors.normal)
    consoleLogs.send({
        username: 'Felobot',
        embeds: [embed],
    }).catch(() => {
        console.log('Error sending unhandledRejection to webhook')
    })
});

process.on('warning', warn => {
    console.warn("Warnung:", warn);
    const embed = new Discord.EmbedBuilder()
        .setTitle(`🚨・Neue Warnung gefunden`)
        .addFields([
            {
                name: `Warnung`,
                value: `\`\`\`${warn}\`\`\``,
            },
        ])
        .setColor(client.config.colors.normal)
    warnLogs.send({
        username: 'Felobot',
        embeds: [embed],
    }).catch(() => {
        console.log('Fehler beim senden der Warnung zum Webhook!')
        console.log(warn)
    })
});

client.on(Discord.ShardEvents.Error, error => {
    console.log(error)
    if (error) if (error.length > 950) error = error.slice(0, 950) + '... schau in die Konsole für Details';
    if (error.stack) if (error.stack.length > 950) error.stack = error.stack.slice(0, 950) + '... schau in die Konsole für Details';
    if (!error.stack) return
    const embed = new Discord.EmbedBuilder()
        .setTitle(`🚨・A websocket connection encountered an error`)
        .addFields([
            {
                name: `Error`,
                value: `\`\`\`${error}\`\`\``,
            },
            {
                name: `Stack error`,
                value: `\`\`\`${error.stack}\`\`\``,
            }
        ])
        .setColor(client.config.colors.normal)
    consoleLogs.send({
        username: 'Felobot',
        embeds: [embed],
    });
});

//DM-Chat
client.on('messageCreate', async message => {

    if (message.channel.type === Discord.ChannelType.DM) {
        if (message.author.bot) return;

        await message.channel.sendTyping();

        let input = {
            method: 'GET',
            url: "https://google-bard1.p.rapidapi.com/",
            headers: {
                text: message.content,
                lang: 'de',
                psid: 'REDACTED.',
                'X-RapidAPI-Key': 'REDACTED',
                'X-RapidAPI-Host': 'google-bard1.p.rapidapi.com',
            }
        };

        try {
            const output = await axios.request(input);
            const response = output.data.response;

            if (response.length > 2000) {
                const chunks = response.match(/.{1,2000}/g)

                for (let i = 0; i < chunks.length; i++) {
                    await message.author.send(chunks[i]).catch(err => {
                        message.author.send("Ein Fehler mit Felo.AI ist aufgetreten! Bitte versuche es erneut!").catch(err => {});
                    });
                }

            } else {
                await message.author.send(response).catch(err => {
                    message.author.send("Ein Fehler mit Felo.AI ist aufgetreten! Bitte versuche es erneut!").catch(err => {});
                });
            }
        } catch (e) {
            console.log(e);
            message.author.send("Ein Fehler mit Felo.AI ist aufgetreten! Bitte versuche es erneut!").catch(err => {});
        }
    } else {
        return;
    }

});


client.on('messageCreate', async (message) => {
    if (message.author.bot || !message.content.startsWith('.p')) return;

    const args = message.content.slice(3).trim().split(' ');
    const command = args.shift().toLowerCase();

    if (!message.member.voice.channel) {
        return client.errNormal({
            error: `You're not in a voice channel!`,
            type: 'reply'
        }, message);
    }

    const channel = message.member.voice.channel;
    let player = client.player.players.get(message.guild.id);

    if (player && (channel.id !== player?.voiceChannel)) {
        return client.errNormal({
            error: `You are not in the same voice channel!`,
            type: 'reply'
        }, message);
    }

    if (!player) {
        player = client.player.create({
            guild: message.guild.id,
            voiceChannel: channel.id,
            textChannel: message.channel.id,
            selfDeafen: true
        });

        if (!channel.joinable) {
            return client.errNormal({
                error: `That channel isn't joinable`,
                type: 'reply'
            }, message);
        }
        
        player.connect();

        setTimeout(() => {
            if (channel.type == Discord.ChannelType.GuildStageVoice) {
                message.guild.members.me.voice.setSuppressed(false);
            }
        }, 500);
    }

    player = client.player.players.get(message.guild.id);
    if (player.state !== "CONNECTED") player.connect();

    const query = args.join(' ');

    client.simpleEmbed({
        desc: `🔎┆Searching...`,
        type: 'reply'
    }, message);

    const res = await player.search(command);

    if (res.loadType === 'LOAD_FAILED') {
        if (!player.queue.current) player.destroy();
        return client.errNormal({
            error: `Error getting music. Please try again in a few minutes`,
            type: 'reply'
        }, message);
    }

    console.log(res);

    switch (res.loadType) {
        case 'NO_MATCHES': {
            if (!player.queue.current) player.destroy();
            await client.errNormal({
                error: `No music was found`,
                type: 'reply'
            }, message);
            break;
        }

        case 'TRACK_LOADED': {
            const track = res.tracks[0];
            await player.queue.add(track);

            if (!player.playing && !player.paused) {
                player.play();
            } else {
                client.embed({
                    title: `${client.emotes.normal.music}・${track.title}`,
                    url: track.uri,
                    desc: `The song has been added to the queue!`,
                    thumbnail: track.thumbnail,
                    fields: [
                        {
                            name: `👤┆Requested By`,
                            value: `${track.requester}`,
                            inline: true
                        },
                        {
                            name: `${client.emotes.normal.clock}┆Ends at`,
                            value: `<t:${((Date.now() / 1000) + (track.duration / 1000)).toFixed(0)}:f>`,
                            inline: true
                        },
                        {
                            name: `🎬┆Author`,
                            value: `${track.author}`,
                            inline: true
                        }
                    ],
                    type: 'reply'
                }, message);
            }
            break;
        }

        case 'PLAYLIST_LOADED': {
            await player.queue.add(res.tracks);
            if (!player.playing && !player.paused) player.play();
            else {
                // Hier kannst du Code hinzufügen, wenn die Wiedergabe bereits läuft
            }
            break;
        }

        case 'SEARCH_RESULT': {
            let max = 5;
            let collected;
            let filter = (i) => i.user.id === message.author.id;
            if (res.tracks.length < max) max = res.tracks.length;

            let row = new Discord.ActionRowBuilder()
                .addComponents(
                    new Discord.ButtonBuilder()
                        .setEmoji("1️⃣")
                        .setCustomId("1")
                        .setStyle(Discord.ButtonStyle.Secondary),

                    new Discord.ButtonBuilder()
                        .setEmoji("2️⃣")
                        .setCustomId("2")
                        .setStyle(Discord.ButtonStyle.Secondary),

                    new Discord.ButtonBuilder()
                        .setEmoji("3️⃣")
                        .setCustomId("3")
                        .setStyle(Discord.ButtonStyle.Secondary),

                    new Discord.ButtonBuilder()
                        .setEmoji("4️⃣")
                        .setCustomId("4")
                        .setStyle(Discord.ButtonStyle.Secondary),

                    new Discord.ButtonBuilder()
                        .setEmoji("5️⃣")
                        .setCustomId("5")
                        .setStyle(Discord.ButtonStyle.Secondary),
                );

            let row2 = new Discord.ActionRowBuilder()
                .addComponents(
                    new Discord.ButtonBuilder()
                        .setEmoji("🛑")
                        .setLabel("Cancel")
                        .setCustomId("cancel")
                        .setStyle(Discord.ButtonStyle.Danger),
                );

            const results = res.tracks
                .slice(0, max)
                .map((track, index) => `**[#${++index}]**┆${track.title.length >= 45 ? `${track.title.slice(0, 45)}...` : track.title}`)
                .join('\n');

            client.embed({
                title: `🔍・Search Results`,
                desc: results,
                fields: [
                    {
                        name: `❓┆Cancel search?`,
                        value: `Press \`cancel\` to stop the search`,
                        inline: true
                    }
                ],
                components: [row, row2],
                type: 'reply'
            }, message);

            try {
                let i = await message.awaitMessageComponent({ filter, max: 1, time: 30e3, componentType: Discord.ComponentType.Button, errors: ['time'] });
            } catch (e) {
                if (!player.queue.current) player.destroy();
                row.components.forEach((button) => button.setDisabled(true));
                row2.components.forEach((button) => button.setDisabled(true));
                return client.errNormal({
                    error: `You didn't provide a selection`,
                    type: 'reply',
                    components: [row, row2]
                }, message);
            }

            const first = i.customId;
            i.message.delete();
            i.deferUpdate();

            if (first.toLowerCase() === 'cancel') {
                if (!player.queue.current) player.destroy();
                return message.channel.send('Cancelled selection.');
            }

            const index = Number(first) - 1;
            if (index < 0 || index > max - 1) return client.errNormal({
                error: `The number you provided is too small or too big (1-${max})`,
                type: 'reply'
            }, message);

            const track = res.tracks[index];
            player.queue.add(track);

            if (!player.playing && !player.paused) {
                player.play();
            } else {
                client.embed({
                    title: `${client.emotes.normal.music}・${track.title}`,
                    url: track.uri,
                    desc: `The song has been added to the queue!`,
                    thumbnail: track.thumbnail,
                    fields: [
                        {
                            name: `👤┆Requested By`,
                            value: `${track.requester}`,
                            inline: true
                        },
                        {
                            name: `${client.emotes.normal.clock}┆Ends at`,
                            value: `<t:${((Date.now() / 1000) + (track.duration / 1000)).toFixed(0)}:f>`,
                            inline: true
                        },
                        {
                            name: `🎬┆Author`,
                            value: `${track.author}`,
                            inline: true
                        }
                    ],
                    type: 'reply'
                }, message);
            }
        }
    }
});
Editor is loading...