30 |
31 |
35 | <% } %>
--------------------------------------------------------------------------------
/src/commands/media/waifu.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('waifu')
9 | .setDescription('Returns a random waifu pic')
10 | .addStringOption(option =>
11 | option.setName('amount')
12 | .setDescription('Defines how many images the bot should send')
13 | .setRequired(true)
14 | .addChoices(
15 | {
16 | name: 'One',
17 | value: '1',
18 | },
19 | {
20 | name: 'Five',
21 | value: '5',
22 | },
23 | {
24 | name: 'Ten',
25 | value: '10',
26 | },
27 | ))
28 | .setDMPermission(false),
29 |
30 | async execute(interaction) {
31 | const amount = parseInt(interaction.options.getString('amount'));
32 |
33 | async function fetchImage() {
34 | const response = await fetch('https://api.waifu.pics/sfw/waifu');
35 | const data = await response.json();
36 | const img_url = data.url;
37 | return img_url;
38 | }
39 |
40 | const fetches = Array.from(Array(amount), () => fetchImage());
41 | const images = await Promise.all(fetches);
42 | const embeds = [];
43 |
44 | images.forEach((img) => {
45 | const embed = new EmbedBuilder()
46 | .setColor(color)
47 | .setTitle('Random waifu pic?')
48 | .setFooter({ text: 'From waifu.pics' })
49 | .setImage(img);
50 | embeds.push(embed);
51 | });
52 |
53 | await interaction.reply({ embeds: embeds });
54 | },
55 | };
56 |
--------------------------------------------------------------------------------
/src/commands/media/neko.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const { fetchRandom } = require ('nekos-best.js');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('neko')
9 | .setDescription('Returns a random neko')
10 | .addStringOption(option =>
11 | option.setName('amount')
12 | .setDescription('Defines how many images the bot should send')
13 | .setRequired(true)
14 | .addChoices(
15 | {
16 | name: 'One',
17 | value: '1',
18 | },
19 | {
20 | name: 'Five',
21 | value: '5',
22 | },
23 | {
24 | name: 'Ten',
25 | value: '10',
26 | },
27 | ))
28 | .setDMPermission(false),
29 |
30 | async execute(interaction) {
31 | let amount = interaction.options.getString('amount');
32 | amount = parseInt(amount);
33 |
34 | async function fetchImage() {
35 | const response = await fetchRandom('neko');
36 | return response.results[0];
37 | }
38 |
39 | const fetches = Array.from(Array(amount), () => fetchImage());
40 | const nekos = await Promise.all(fetches);
41 | const embeds = [];
42 |
43 | nekos.forEach((neko) => {
44 | const embed = new EmbedBuilder()
45 | .setColor(color)
46 | .setTitle('Meow')
47 | .setDescription(`[${neko.artist_name}](${neko.source_url})`)
48 | .setFooter({ text: 'From nekos.best' })
49 | .setImage(neko.url);
50 | embeds.push(embed);
51 | });
52 |
53 | await interaction.reply({ embeds: embeds });
54 | },
55 | };
56 |
--------------------------------------------------------------------------------
/src/commands/media/dog.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('dog')
9 | .setDescription('Returns a random dog')
10 | .addStringOption(option =>
11 | option.setName('amount')
12 | .setDescription('Defines how many images the bot should send')
13 | .setRequired(true)
14 | .addChoices(
15 | {
16 | name: 'One',
17 | value: '1',
18 | },
19 | {
20 | name: 'Five',
21 | value: '5',
22 | },
23 | {
24 | name: 'Ten',
25 | value: '10',
26 | },
27 | ))
28 | .setDMPermission(false),
29 |
30 | async execute(interaction) {
31 | const amount = parseInt(interaction.options.getString('amount'));
32 |
33 | async function fetchImage() {
34 | const response = await fetch('https://random.dog/woof.json');
35 | const data = await response.json();
36 | const img_url = data.url;
37 | return img_url;
38 | }
39 |
40 | const fetches = Array.from(Array(amount), () => fetchImage());
41 | const images = await Promise.all(fetches);
42 | const embeds = [];
43 |
44 | images.forEach((img) => {
45 | const embed = new EmbedBuilder()
46 | .setColor(color)
47 | .setTitle('Woof!')
48 | .setDescription(`[Link if you can't see the image](${img})`)
49 | .setFooter({ text: 'From random.dog' })
50 | .setImage(img);
51 | embeds.push(embed);
52 | });
53 |
54 | await interaction.reply({ embeds: embeds });
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/src/commands/media/fox.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('fox')
9 | .setDescription('Returns a random fox')
10 | .addStringOption(option =>
11 | option.setName('amount')
12 | .setDescription('Defines how many images the bot should send')
13 | .setRequired(true)
14 | .addChoices(
15 | {
16 | name: 'One',
17 | value: '1',
18 | },
19 | {
20 | name: 'Five',
21 | value: '5',
22 | },
23 | {
24 | name: 'Ten',
25 | value: '10',
26 | },
27 | ))
28 | .setDMPermission(false),
29 |
30 | async execute(interaction) {
31 | const amount = parseInt(interaction.options.getString('amount'));
32 |
33 | async function fetchImage() {
34 | const response = await fetch('https://randomfox.ca/floof/');
35 | const data = await response.json();
36 | const img_url = data.image;
37 | return img_url;
38 | }
39 |
40 | const fetches = Array.from(Array(amount), () => fetchImage());
41 | const images = await Promise.all(fetches);
42 | const embeds = [];
43 |
44 | images.forEach((img) => {
45 | const embed = new EmbedBuilder()
46 | .setColor(color)
47 | .setTitle('Floof!')
48 | .setDescription(`[Link if you can't see the image](${img})`)
49 | .setFooter({ text: 'From randomfox.ca' })
50 | .setImage(img);
51 | embeds.push(embed);
52 | });
53 |
54 | await interaction.reply({ embeds: embeds });
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/src/commands/media/cat.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('cat')
9 | .setDescription('Returns a random cat')
10 | .addStringOption(option =>
11 | option.setName('amount')
12 | .setDescription('Defines how many images the bot should send')
13 | .setRequired(true)
14 | .addChoices(
15 | {
16 | name: 'One',
17 | value: '1',
18 | },
19 | {
20 | name: 'Five',
21 | value: '5',
22 | },
23 | {
24 | name: 'Ten',
25 | value: '10',
26 | },
27 | ))
28 | .setDMPermission(false),
29 |
30 | async execute(interaction) {
31 | const amount = parseInt(interaction.options.getString('amount'));
32 |
33 | async function fetchImage() {
34 | const response = await fetch('https://cataas.com/cat?json=true');
35 | const data = await response.json();
36 | const img_url = `https://cataas.com${data.url}`;
37 | return img_url;
38 | }
39 |
40 | const fetches = Array.from(Array(amount), () => fetchImage());
41 | const images = await Promise.all(fetches);
42 | const embeds = [];
43 |
44 | images.forEach((img) => {
45 | const embed = new EmbedBuilder()
46 | .setColor(color)
47 | .setTitle('Meow!')
48 | .setDescription(`[Link if you can't see the image](${img})`)
49 | .setImage(img)
50 | .setFooter({ text: 'From cataas.com' });
51 | embeds.push(embed);
52 | });
53 |
54 | await interaction.reply({ embeds: embeds });
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/src/commands/boorus/konachan.js:
--------------------------------------------------------------------------------
1 | const { italic, SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('konachan')
9 | .setDescription('search konachan board')
10 | .addStringOption(option => option.setName('tags').setDescription('tags to search for').setRequired(true))
11 | .setDMPermission(false),
12 |
13 | async execute(interaction) {
14 | if (!interaction.channel.nsfw) {
15 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
16 | return;
17 | }
18 |
19 | await interaction.deferReply();
20 | const query = interaction.options.getString('tags');
21 | if (query.split(' ').length > 2) return interaction.editReply({ content: "Max. amount of tags is 2." });
22 |
23 | const response = await fetch(`https://konachan.com/post.json?limit=99&tags=${query}`);
24 | const data = await response.json();
25 | const randomInt = Math.floor(Math.random() * (Object.keys(data).length - 0) + 0);
26 |
27 | if (!data.length) {
28 | await interaction.editReply(`I'm so sorry but I can't find anything with the tag(s) ${italic(query)}`);
29 | return;
30 | }
31 |
32 | const imgUrl = data[randomInt].file_url;
33 | const postId = data[randomInt].id;
34 | const postUrl = `https://konachan.com/post/show/${postId}`;
35 |
36 | const embed = new EmbedBuilder()
37 | .setTitle(`Post URL`)
38 | .setURL(postUrl)
39 | .setDescription(`Board: konachan.com\nQueried Tag(s): ${query}\nRequested by: ${interaction.member}`)
40 | .setColor(color)
41 | .setImage(imgUrl)
42 | .setFooter({ text: "This content is served by an image-search api and Darling is not responsible for any content!" });
43 |
44 | await interaction.editReply({ embeds: [embed] });
45 | },
46 | };
47 |
--------------------------------------------------------------------------------
/src/commands/moderation/clear.js:
--------------------------------------------------------------------------------
1 | const { color } = require('../../data/config.json');
2 | const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder } = require('discord.js');
3 |
4 | module.exports = {
5 | data: new SlashCommandBuilder()
6 | .setName('clear')
7 | .setDescription('deletes a specified amount of messages in a channel')
8 | .addIntegerOption(option =>
9 | option
10 | .setName('amount')
11 | .setDescription('define amount of messages to delete')
12 | .setRequired(true)
13 | .setMinValue(1)
14 | .setMaxValue(100))
15 | .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
16 | .setDMPermission(false),
17 |
18 | async execute(interaction) {
19 | await interaction.deferReply({ ephemeral: true });
20 | if (!interaction.guild.members.me.permissions.has(PermissionFlagsBits.ManageMessages)) {
21 | await interaction.editReply({ content: "I'm sorry, but I'm missing permission to do that!" });
22 | return;
23 | }
24 | if (!interaction.member.permissions.has(PermissionFlagsBits.ManageMessages)) {
25 | await interaction.editReply({ content: "I'm sorry, but you're not allowed to do that!" });
26 | return;
27 | }
28 |
29 | const amount = interaction.options.getInteger('amount');
30 | const messages = await interaction.channel.messages.fetch({ limit: amount });
31 | if (messages.find(msg => Date.now() - msg.createdAt >= 1000 * 60 * 60 * 24 * 14)) {
32 | await interaction.editReply({ content: "I'm sorry, but I can't delete messages which are older than 14 days!" });
33 | return;
34 | }
35 |
36 | await interaction.channel.bulkDelete(messages);
37 | const embed = new EmbedBuilder()
38 | .setTitle(`Deleted ${messages.size} messages! 🧹`)
39 | .setColor(color)
40 | .setThumbnail("https://eckigerluca.com/darling/media/cleaning.gif");
41 | await interaction.editReply({ embeds: [embed] });
42 | await new Promise(resolve => setTimeout(resolve, 6000));
43 | },
44 | };
45 |
--------------------------------------------------------------------------------
/src/commands/boorus/gelbooru.js:
--------------------------------------------------------------------------------
1 | const { italic, SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('gelbooru')
9 | .setDescription('search gelbooru.com board')
10 | .addStringOption(option => option.setName('tags').setDescription('tags to search for').setRequired(true))
11 | .setDMPermission(false),
12 |
13 | async execute(interaction) {
14 | if (!interaction.channel.nsfw) {
15 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
16 | return;
17 | }
18 |
19 | await interaction.deferReply();
20 | const query = interaction.options.getString('tags');
21 | if (query.split(' ').length > 2) return interaction.editReply({ content: "Max. amount of tags is 2." });
22 |
23 | const response = await fetch(`https://gelbooru.com/index.php?page=dapi&s=post&q=index&json=1&tags=${query}`);
24 | const data = await response.json();
25 |
26 | if (!data?.post) {
27 | await interaction.editReply(`I'm so sorry but I can't find anything with the tag(s) ${italic(query)}`);
28 | return;
29 | }
30 |
31 | const randomInt = Math.floor(Math.random() * (Object.keys(data.post).length - 0) + 0);
32 |
33 | const postId = data.post[randomInt].id;
34 |
35 | const postUrl = `https://gelbooru.com/index.php?page=post&s=view&id=${postId}`;
36 | const imgUrl = data.post[randomInt].file_url;
37 |
38 | const embed = new EmbedBuilder()
39 | .setTitle(`Post URL`)
40 | .setURL(postUrl)
41 | .setDescription(`Board: gelbooru.com\nQueried Tag(s): ${query}\nRequested by: ${interaction.member}`)
42 | .setColor(color)
43 | .setImage(imgUrl)
44 | .setFooter({ text: "This content is served by an image-search api and Darling is not responsible for any content!" });
45 |
46 | await interaction.editReply({ embeds: [embed] });
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/src/commands/boorus/lolibooru.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder, italic } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('lolibooru')
9 | .setDescription('search lolibooru.moe board')
10 | .addStringOption(option => option.setName('tags').setDescription('tags to search for').setRequired(true))
11 | .setDMPermission(false),
12 |
13 | async execute(interaction) {
14 | if (!interaction.channel.nsfw) {
15 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
16 | return;
17 | }
18 |
19 | await interaction.deferReply();
20 | const query = interaction.options.getString('tags');
21 | if (query.split(' ').length > 2) return interaction.editReply({ content: "Max. amount of tags is 2." });
22 |
23 | const response = await fetch(`https://lolibooru.moe/post/index.json?page=dapi&s=post&q=index&json=1&limit=99&tags=${query}`);
24 | const data = await response.json();
25 | const randomInt = Math.floor(Math.random() * (Object.keys(data).length - 0) + 0);
26 |
27 | const postId = data[randomInt]?.id;
28 |
29 | if (!postId) {
30 | await interaction.editReply(`I'm so sorry but I can't find anything with the tag(s) ${italic(query)}`);
31 | return;
32 | }
33 |
34 | const postUrl = `https://lolibooru.moe/post/show/${postId}`;
35 | const imgUrl = data[randomInt].file_url;
36 | const imgUrlEdited = imgUrl.replace(/ /g, '%20');
37 |
38 | const embed = new EmbedBuilder()
39 | .setTitle(`Post URL`)
40 | .setURL(postUrl)
41 | .setDescription(`Board: lolibooru.moe\nQueried Tag(s): ${query}\nRequested by: ${interaction.member}`)
42 | .setColor(color)
43 | .setImage(imgUrlEdited)
44 | .setFooter({ text:"This content is served by an image-search api and Darling is not responsible for any content!" });
45 |
46 | await interaction.editReply({ embeds: [embed] });
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/src/commands/nsfw/hentaineko.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-inner-declarations */
2 | const { SlashCommandBuilder } = require('@discordjs/builders');
3 | const { color } = require('../../data/config.json');
4 | const { EmbedBuilder } = require('discord.js');
5 | const fetch = require('node-fetch');
6 |
7 | module.exports = {
8 | data: new SlashCommandBuilder()
9 | .setName('hentaineko')
10 | .setDescription('Returns a random hentai neko pic')
11 | .addStringOption(option =>
12 | option.setName('amount')
13 | .setDescription('Defines how many images the bot should send')
14 | .setRequired(true)
15 | .addChoices(
16 | {
17 | name: 'One',
18 | value: '1',
19 | },
20 | {
21 | name: 'Five',
22 | value: '5',
23 | },
24 | {
25 | name: 'Ten',
26 | value: '10',
27 | },
28 | ))
29 | .setDMPermission(false),
30 |
31 | async execute(interaction) {
32 | if (!interaction.channel.nsfw) {
33 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
34 | return;
35 | }
36 | const amount = parseInt(interaction.options.getString('amount'));
37 |
38 | async function fetchImage() {
39 | const response = await fetch('https://api.waifu.pics/nsfw/neko');
40 | const data = await response.json();
41 | const img_url = data.url;
42 | return img_url;
43 | }
44 |
45 | const fetches = Array.from(Array(amount), () => fetchImage());
46 | const images = await Promise.all(fetches);
47 | const embeds = [];
48 |
49 | images.forEach((img) => {
50 | const embed = new EmbedBuilder()
51 | .setColor(color)
52 | .setTitle('Random hentai neko pic?')
53 | .setFooter({ text: 'From waifu.pics' })
54 | .setImage(img);
55 | embeds.push(embed);
56 | });
57 |
58 | await interaction.reply({ embeds: embeds });
59 | },
60 | };
61 |
--------------------------------------------------------------------------------
/src/commands/nsfw/hentaiblowjob.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-inner-declarations */
2 | const { SlashCommandBuilder } = require('@discordjs/builders');
3 | const { color } = require('../../data/config.json');
4 | const { EmbedBuilder } = require('discord.js');
5 | const fetch = require('node-fetch');
6 |
7 | module.exports = {
8 | data: new SlashCommandBuilder()
9 | .setName('hentaiblowjob')
10 | .setDescription('Returns a random hentai blowjob gif')
11 | .addStringOption(option =>
12 | option.setName('amount')
13 | .setDescription('Defines how many gifs the bot should send')
14 | .setRequired(true)
15 | .addChoices(
16 | {
17 | name: 'One',
18 | value: '1',
19 | },
20 | {
21 | name: 'Five',
22 | value: '5',
23 | },
24 | {
25 | name: 'Ten',
26 | value: '10',
27 | },
28 | ))
29 | .setDMPermission(false),
30 |
31 | async execute(interaction) {
32 | if (!interaction.channel.nsfw) {
33 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
34 | return;
35 | }
36 | const amount = parseInt(interaction.options.getString('amount'));
37 |
38 | async function fetchImage() {
39 | const response = await fetch('https://api.waifu.pics/nsfw/blowjob');
40 | const data = await response.json();
41 | const img_url = data.url;
42 | return img_url;
43 | }
44 |
45 | const fetches = Array.from(Array(amount), () => fetchImage());
46 | const images = await Promise.all(fetches);
47 | const embeds = [];
48 |
49 | images.forEach((img) => {
50 | const embed = new EmbedBuilder()
51 | .setColor(color)
52 | .setTitle('Random hentai blowjob')
53 | .setFooter({ text: 'From waifu.pics' })
54 | .setImage(img);
55 | embeds.push(embed);
56 | });
57 |
58 | await interaction.reply({ embeds: embeds });
59 | },
60 | };
61 |
--------------------------------------------------------------------------------
/src/commands/nsfw/hentaiwaifu.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-inner-declarations */
2 | const { SlashCommandBuilder } = require('@discordjs/builders');
3 | const { color } = require('../../data/config.json');
4 | const { EmbedBuilder } = require('discord.js');
5 | const fetch = require('node-fetch');
6 |
7 | module.exports = {
8 | data: new SlashCommandBuilder()
9 | .setName('hentaiwaifu')
10 | .setDescription('Returns a random hentai waifu pic')
11 | .addStringOption(option =>
12 | option.setName('amount')
13 | .setDescription('Defines how many images the bot should send')
14 | .setRequired(true)
15 | .addChoices(
16 | {
17 | name: 'One',
18 | value: '1',
19 | },
20 | {
21 | name: 'Five',
22 | value: '5',
23 | },
24 | {
25 | name: 'Ten',
26 | value: '10',
27 | },
28 | ))
29 | .setDMPermission(false),
30 |
31 | async execute(interaction) {
32 | if (!interaction.channel.nsfw) {
33 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
34 | return;
35 | }
36 | const amount = parseInt(interaction.options.getString('amount'));
37 |
38 | async function fetchImage() {
39 | const response = await fetch('https://api.waifu.pics/nsfw/waifu');
40 | const data = await response.json();
41 | const img_url = data.url;
42 | return img_url;
43 | }
44 |
45 | const fetches = Array.from(Array(amount), () => fetchImage());
46 | const images = await Promise.all(fetches);
47 | const embeds = [];
48 |
49 | images.forEach((img) => {
50 | const embed = new EmbedBuilder()
51 | .setColor(color)
52 | .setTitle('Random hentai waifu pic?')
53 | .setFooter({ text: 'From waifu.pics' })
54 | .setImage(img);
55 | embeds.push(embed);
56 | });
57 |
58 | await interaction.reply({ embeds: embeds });
59 | },
60 | };
61 |
--------------------------------------------------------------------------------
/src/events/interaction-create.js:
--------------------------------------------------------------------------------
1 | const logger = require("silly-logger");
2 |
3 | module.exports = {
4 | name: 'interactionCreate',
5 | once: false,
6 | async execute(interaction) {
7 | if (!interaction.isCommand()) return;
8 |
9 | const command = interaction.client.commands.get(interaction.commandName);
10 |
11 | if (!command) return;
12 |
13 | if (!interaction.guild) return await interaction.reply({ content: "No.", ephemeral: true });
14 |
15 | if (interaction.commandData == undefined) {
16 | interaction.commandData = {
17 | name: interaction.commandName,
18 | options: [interaction.options],
19 | };
20 | }
21 |
22 | try {
23 | await command.execute(interaction);
24 | }
25 | catch (error) {
26 | logger.error(error);
27 | try {
28 | try {
29 | await interaction.reply({ content: `There was an error while executing this command!\nJoin the Support Server and send us the error message:\n \`\`\`js\n ${JSON.stringify(interaction.commandData, null, 4)} \`\`\` \`\`\`js\n${error}\`\`\` \n https://discord.com/invite/tpUr7d3 `, embeds: [], ephemeral: true });
30 | }
31 | catch {
32 | await interaction.editReply({ content: `There was an error while executing this command!\nJoin the Support Server and send us the error message:\n \`\`\`js\n ${JSON.stringify(interaction.commandData, null, 4)} \`\`\` \`\`\`js\n${error}\`\`\` \n https://discord.com/invite/tpUr7d3 `, embeds: [], ephemeral: true });
33 | }
34 | }
35 | // eslint-disable-next-line no-inline-comments
36 | catch (err) {
37 | logger.error(err);
38 | try {
39 | await interaction.reply({ content: `There was an error while executing this command, but there was another error sending the error message!\n Please contact us and include the following information: \`command name, options, time of execution\` \n https://discord.com/invite/tpUr7d3 `, embeds: [], ephemeral: true });
40 | }
41 | catch {
42 | await interaction.editReply({ content: `There was an error while executing this command, but there was another error sending the error message!\n Please contact us and include the following information: \`command name, options, time of execution\` \n https://discord.com/invite/tpUr7d3 `, embeds: [], ephemeral: true });
43 | }
44 | }
45 | }
46 | },
47 | };
48 |
--------------------------------------------------------------------------------
/src/commands/boorus/safebooru.js:
--------------------------------------------------------------------------------
1 | const { italic, SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 | const fetch = require('node-fetch');
5 |
6 | module.exports = {
7 | data: new SlashCommandBuilder()
8 | .setName('safebooru')
9 | .setDescription('search safebooru.org board')
10 | .addStringOption(option => option.setName('tags').setDescription('tags to search for').setRequired(true))
11 | .setDMPermission(false),
12 |
13 | async execute(interaction) {
14 | if (!interaction.channel.nsfw) {
15 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
16 | return;
17 | }
18 |
19 | await interaction.deferReply();
20 | const query = interaction.options.getString('tags');
21 | if (query.split(' ').length > 2) return interaction.editReply({ content: "Max. amount of tags is 2." });
22 |
23 | const response = await fetch(`https://safebooru.org/index.php?page=dapi&s=post&q=index&json=1&tags=${query}`);
24 | let data;
25 |
26 | try {
27 | data = await response.json();
28 | } catch {
29 | await interaction.editReply(`I'm so sorry but I can't find anything with the tag(s) ${italic(query)}`);
30 | return;
31 | }
32 |
33 | const randomInt = Math.floor(Math.random() * (Object.keys(data).length - 0) + 0);
34 |
35 | const postImgName = data[randomInt].image;
36 | const postDirectory = data[randomInt].directory;
37 | const postId = data[randomInt].id;
38 |
39 | const postUrl = `https://safebooru.org/index.php?page=post&s=view&id=${postId}`;
40 | const imgUrl = `https://safebooru.org/images/${postDirectory}/${postImgName}`;
41 |
42 | const embed = new EmbedBuilder()
43 | .setTitle(`Post URL`)
44 | .setURL(postUrl)
45 | .setDescription(`Board: safebooru.org\nQueried Tag(s): ${query}\nRequested by: ${interaction.member}`)
46 | .setColor(color)
47 | .setImage(imgUrl)
48 | .setFooter({ text: "This content is served by an image-search api and Darling is not responsible for any content!" });
49 |
50 | await interaction.editReply({ embeds: [embed] });
51 | },
52 | };
53 |
--------------------------------------------------------------------------------
/src/commands/other/whois.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 |
5 | module.exports = {
6 | data: new SlashCommandBuilder()
7 | .setName('whois')
8 | .setDescription('returns information about you or')
9 | .addUserOption(option =>
10 | option.setName('user')
11 | .setDescription('Tag a user to get information about them'))
12 | .setDMPermission(false),
13 |
14 | async execute(interaction) {
15 | let user = interaction.options.getUser('user');
16 | if (user === null) {
17 | user = interaction.user;
18 | }
19 |
20 | async function getMemberJoinDate() {
21 | const member = await interaction.guild.members.fetch(user.id);
22 | const date = Math.round(member.joinedTimestamp / 1000);
23 | return date;
24 | }
25 | const joinDate = await getMemberJoinDate();
26 |
27 | let roles = '';
28 | async function getMemberRoles() {
29 | const member = await interaction.guild.members.fetch(user.id);
30 | const rolesArray = member._roles;
31 | rolesArray.forEach(role => roles += `<@&${role}> `);
32 | return roles;
33 | }
34 | const memberRoles = await getMemberRoles();
35 |
36 | const avatar = user.displayAvatarURL({ size: 1024, extension: 'png', forceStatic: false });
37 | const embed = new EmbedBuilder()
38 | .setDescription(`<@${user.id}>`)
39 | .setAuthor({ name: String(user.username), iconURL: avatar })
40 | .setThumbnail(avatar)
41 | .setFooter({ text: `User ID: ${user.id}` })
42 | .setColor(color)
43 | .addFields(
44 | { name: 'Joined:', value: `\n`, inline: true },
45 | { name: 'Registered:', value: `\n`, inline: true },
46 | { name: 'Roles:', value: '\u200b' + memberRoles, inline: false },
47 | );
48 | await interaction.reply({ embeds: [embed] });
49 | },
50 | };
51 |
--------------------------------------------------------------------------------
/src/website/views/header.ejs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/commands/other/botinfo.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require('@discordjs/builders');
2 | const { color } = require('../../data/config.json');
3 | const { EmbedBuilder } = require('discord.js');
4 |
5 | module.exports = {
6 | data: new SlashCommandBuilder()
7 | .setName('botinfo')
8 | .setDescription('Shows some information about the bot')
9 | .setDMPermission(false),
10 |
11 | async execute(interaction) {
12 | const servers = interaction.client.guilds.cache.size;
13 | const eckigerluca = await interaction.client.users.fetch('173374602389618688');
14 | const eckigerluca_avatar = eckigerluca.displayAvatarURL({ size: 1024, extension: 'png', forceStatic: false });
15 | const embed = new EmbedBuilder()
16 | .setTitle('Hey!')
17 | .setColor(color)
18 | .setDescription('This page here is just existing to share some information about the bot, so read it if you have time for it lol')
19 | .setThumbnail(interaction.client.user.displayAvatarURL({ size: 1024, extension: 'png', forceStatic: false }))
20 | .addFields(
21 | // { name: 'How it started...', value: "I actually decided to code my own bot because I felt like 'Ugh pay2win I dont like that' sooooo I decided to do it free then. Yes, this bot is completely free, but I have to pay to maintain it tho lol\nThe first few lines of code of `Darling.` were written in Python with discord.py, but sadly this library isn't maintained anymore so I had to switch to `Discord.js` which is obv written in JavaScript. Uh yeah, a date.. it was the 12th August 2020 when I started this project. How time has passed\nEnough bs, time for important information!", inline: false },
22 | { name: "Profile Picture", value: `__Artist:__\n[ShiChi](https://www.pixiv.net/en/users/36083362)\n__Artwork:__\n[スカジ](https://www.pixiv.net/en/artworks/85612659)`, inline: true },
23 | { name: "Servers", value: `${servers}`, inline: true },
24 | { name: "Code", value: "https://github.com/eckigerluca/darling", inline: true },
25 | { name: "Support", value: "The **Bot Support** is on my [Server](https://eckigerluca.com/discord).\nBut you can also support **me** on [Patreon](https://patreon.com/eckigerluca) or [Ko-Fi](https://ko-fi.com/eckigerluca)", inline: false },
26 | )
27 | .setFooter({ text: `Bot by ${eckigerluca.username}`, iconURL: eckigerluca_avatar })
28 | .setAuthor({ name: "EckigerLuca", iconURL: eckigerluca_avatar, url: "https://github.com/EckigerLuca/" });
29 | await interaction.reply({ embeds: [embed] });
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Darling.
2 |
3 |
4 |
5 |
6 |
7 | ### This is the code of my bot
8 | So I'd prefer if You would just add it to your server with [this](https://eckigerluca.com/darling/invite) link.
9 |
10 | ### But if You want to host it by yourself,
11 | rename the `config.json.public` to `config.json` (found under `src/data`) and edit the values. The Bot **needs** the `SERVER MEMBERS INTENT`, so make sure to enable it!
12 |
13 | Make sure that you have a mongo-db database avaiable for bot! The name of the database needs to be `darling`. On first start, the bot will create the needed collection on it's own. [Install MongoDB](https://www.mongodb.com/docs/v6.0/administration/install-community/) (Currently using v6.0)
14 |
15 | New with Version 2.0 is a Web Dashboard, which can't be disabled!
16 | Set it up by renaming the `settings.json.public` (found under `src/website`) to `settings.json` and changing the values in the as needed. Client ID and Secret are found at the OAuth2 Section of your Application. You also need to add your Domain and Callback URL to the Redirects.
17 |
18 | After that, use `npm i` to install all needed packages. When done, register the slash commands by using `npm run deploy` in your console.
19 |
20 | You can then start the bot with `npm start` or `node .`
21 |
22 | If the bot is online, invite it to the server You want to use it on and check if the Dashboard works. (Check the image for permissions).
23 |
24 | 
25 | If the Bot won't start, check the console for any errors and if there are one's, create an Issue (or try to fix them by yourself).
26 |
27 | ## Top.gg
28 | This bot uses Top.gg. If you don't want to use it, leave the variable `topGG` in the `config.json` as it is, but if you want to use it change the bool to `true` and PLEASE DO NOT forget to add your token in the file!
29 |
30 | ## Contact:
31 | * [E-Mail](mailto:contact@darling-bot.xyz)
32 | * Discord: `EckigerLuca#0001`
33 | * Support [Server](https://eckigerluca.com/discord)
34 |
35 | ##
36 |
37 |
--------------------------------------------------------------------------------
/src/commands/boorus/rule34.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-inner-declarations */
2 | const { italic, SlashCommandBuilder } = require('@discordjs/builders');
3 | const { color } = require('../../data/config.json');
4 | const { EmbedBuilder } = require('discord.js');
5 | const fetch = require('node-fetch');
6 |
7 | module.exports = {
8 | data: new SlashCommandBuilder()
9 | .setName('rule34')
10 | .setDescription('search rule34.xxx board')
11 | .addStringOption(option => option.setName('tags').setDescription('tags to search for').setRequired(true))
12 | .setDMPermission(false),
13 |
14 | async execute(interaction) {
15 | if (interaction.channel.nsfw) {
16 | await interaction.deferReply();
17 | const query = interaction.options.getString('tags');
18 | if (query.split(' ').length > 2) return interaction.editReply({ content: "Max. amount of tags is 2." });
19 |
20 | async function getBooru() {
21 | const response = await fetch(`https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&tags=${query}`);
22 | let data;
23 | try {
24 | data = await response.json();
25 | const randomInt = Math.floor(Math.random() * (Object.keys(data).length - 0) + 0);
26 |
27 | const postId = data[randomInt].id;
28 |
29 | const postUrl = `https://rule34.xxx/index.php?page=post&s=view&id=${postId}`;
30 | const imgUrl = data[randomInt].file_url;
31 |
32 | const result = {
33 | "postUrl": postUrl,
34 | "imgUrl": imgUrl,
35 | };
36 | return result;
37 | } catch {
38 | return;
39 | }
40 | }
41 | let booruResult;
42 |
43 | do {
44 | booruResult = await getBooru();
45 | if (!booruResult) {
46 | interaction.editReply(`I'm so sorry but I can't find anything with the tag(s) ${italic(query)}`);
47 | return;
48 | }
49 | } while (booruResult.imgUrl.includes('mp4'));
50 |
51 | const embed = new EmbedBuilder()
52 | .setTitle(`Post URL`)
53 | .setURL(booruResult.postUrl)
54 | .setDescription(`Board: rule34.xxx\nQueried Tag(s): ${query}\nRequested by: ${interaction.member}`)
55 | .setColor(color)
56 | .setImage(booruResult.imgUrl)
57 | .setFooter({ text: "This content is served by an image-search api and Darling is not responsible for any content!" });
58 |
59 | await interaction.editReply({ embeds: [embed] });
60 | }
61 | else {
62 | await interaction.reply({ content: 'Please go to a channel that is marked as NSFW!', ephemeral: true });
63 | }
64 | },
65 | };
66 |
--------------------------------------------------------------------------------
/src/commands/moderation/kick.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
2 |
3 | module.exports = {
4 | data: new SlashCommandBuilder()
5 | .setName('kick')
6 | .setDescription('kick a member')
7 | .addUserOption(option => option.setName('user').setDescription('Select a user to kick').setRequired(true))
8 | .addStringOption(option => option.setName('reason').setDescription('Define a reason').setRequired(false))
9 | .setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
10 | .setDMPermission(false),
11 |
12 | async execute(interaction) {
13 | const user = interaction.options.getUser('user');
14 | const reason = interaction.options.getString('reason') || "No reason provided.";
15 | const member = await interaction.guild.members.fetch(user.id);
16 | const messageAuthor = await interaction.guild.members.fetch(interaction.member.id);
17 | const authorIsServerOwner = messageAuthor.id === interaction.guild.ownerId;
18 | const clientMember = interaction.guild.members.me;
19 |
20 | if (!clientMember.permissions.has(PermissionFlagsBits.KickMembers)) {
21 | await interaction.reply({ content: "I am missing permission to do that!", ephemeral: true });
22 | return;
23 | }
24 | else if (!messageAuthor.permissions.has(PermissionFlagsBits.KickMembers)) {
25 | await interaction.reply({ content: "You're not allowed to do that!", ephemeral: true });
26 | return;
27 | }
28 |
29 | if (clientMember === member) {
30 | await interaction.reply({ content: "I can't kick myself silly!", ephemeral: true });
31 | return;
32 | }
33 | else if (member.id === interaction.guild.ownerId) {
34 | await interaction.reply({ content: "You can't kick the server owner silly!", ephemeral: true });
35 | return;
36 | }
37 |
38 | if (member.roles.highest.position >= clientMember.roles.highest.position) {
39 | await interaction.reply({ content: "I can't kick that member because their role is higher than mine!", ephemeral: true });
40 | return;
41 | }
42 | else if (member.roles.highest.position >= messageAuthor.roles.highest.position && !authorIsServerOwner) {
43 | await interaction.reply({ content: "You can't kick that member because their role is higher than yours!", ephemeral: true });
44 | return;
45 | }
46 |
47 | try {
48 | await member.send(`You have been kicked from **${interaction.guild.name}**\nReason: ${reason}`);
49 | }
50 | catch {
51 | console.log("Could not dm kicked member");
52 | }
53 |
54 | await member.kick(reason);
55 | interaction.reply({ content: `Kicked ${member.username} successfully!\nReason: ${reason}` });
56 | },
57 | };
58 |
--------------------------------------------------------------------------------
/src/commands/moderation/ban.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
2 |
3 | module.exports = {
4 | data: new SlashCommandBuilder()
5 | .setName('ban')
6 | .setDescription('ban a member')
7 | .addUserOption(option => option.setName('user').setDescription('Select a user to ban').setRequired(true))
8 | .addStringOption(option => option.setName('reason').setDescription('Define a reason').setRequired(false))
9 | .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
10 | .setDMPermission(false),
11 |
12 | async execute(interaction) {
13 | const user = interaction.options.getUser('user');
14 | const reason = interaction.options.getString('reason') || "No reason provided.";
15 | const member = await interaction.guild.members.fetch(user.id);
16 | const messageAuthor = await interaction.guild.members.fetch(interaction.member.id);
17 | const authorIsServerOwner = messageAuthor.id === interaction.guild.ownerId;
18 | const clientMember = interaction.guild.members.me;
19 |
20 | if (!clientMember.permissions.has(PermissionFlagsBits.BanMembers)) {
21 | await interaction.reply({ content: "I am missing permission to do that!", ephemeral: true });
22 | return;
23 | }
24 | else if (!messageAuthor.permissions.has(PermissionFlagsBits.BanMembers)) {
25 | await interaction.reply({ content: "You're not allowed to do that!", ephemeral: true });
26 | return;
27 | }
28 |
29 | if (clientMember === member) {
30 | await interaction.reply({ content: "I can't ban myself silly!", ephemeral: true });
31 | return;
32 | }
33 | else if (member.id === interaction.guild.ownerId) {
34 | await interaction.reply({ content: "You can't ban the server owner silly!", ephemeral: true });
35 | return;
36 | }
37 |
38 | if (member.roles.highest.position >= clientMember.roles.highest.position) {
39 | await interaction.reply({ content: "I can't ban that member becuse their role is higher than mine!", ephemeral: true });
40 | return;
41 | }
42 | else if (member.roles.highest.position >= messageAuthor.roles.highest.position && !authorIsServerOwner) {
43 | await interaction.reply({ content: "You can't ban that member because their role is higher than yours!", ephemeral: true });
44 | return;
45 | }
46 |
47 | try {
48 | await member.send(`You have been banned from **${interaction.guild.name}**\nReason: ${reason}`);
49 | }
50 | catch {
51 | console.log("Could not dm member after banning!");
52 | }
53 |
54 | await member.ban({ reason: reason });
55 | interaction.reply({ content: `Banned ${member.user.username} successfully!\nReason: ${reason}` });
56 | },
57 | };
58 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const { Client, Collection, GatewayIntentBits } = require('discord.js');
3 | const { token, mongodbUri } = require('./data/config.json');
4 | const { MongoClient } = require('mongodb');
5 | const logger = require('silly-logger');
6 |
7 | logger.enableLogFiles(true);
8 | logger.logFolderPath('./src/logs');
9 |
10 | const { topGG } = require('./data/config.json');
11 |
12 | const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers] });
13 | client.commands = new Collection();
14 |
15 | const dbClient = new MongoClient(String(mongodbUri));
16 | (async function dbSetup() {
17 | await dbClient.connect();
18 | client.dbClient = dbClient;
19 | logger.success("Connected to database server!");
20 |
21 | try {
22 | const databases = (await dbClient.db().admin().listDatabases()).databases;
23 | let found = false;
24 | databases.forEach((database) => {
25 | if (database.name === "darling") found = true;
26 | });
27 | if (!found) {
28 | throw new Error("Database not existing!");
29 | }
30 | }
31 | catch (err) {
32 | logger.error("Database not existing! Please create a mongodb database called 'darling' and restart the bot!");
33 | process.exit(1);
34 | }
35 |
36 | const requiredCollections = ['servers', 'users', 'welcome'];
37 | const collections = await dbClient.db("darling").listCollections().toArray();
38 | const collectionsOnServer = [];
39 | const notFound = [];
40 |
41 | collections.forEach((collection) => {
42 | collectionsOnServer.push(collection.name);
43 | });
44 |
45 | requiredCollections.forEach((collection) => {
46 | if (!collectionsOnServer.includes(collection)) notFound.push(collection);
47 | });
48 |
49 | if (notFound.length > 0) {
50 | logger.error(`Missing collections: ${notFound.join(', ')}`);
51 | logger.info("Creating missing collections...");
52 | notFound.forEach(async (collection) => {
53 | dbClient.db("darling").createCollection(collection);
54 | logger.info(`Created collection ${collection}!`);
55 | });
56 | }
57 | logger.success("Database setup complete!\n");
58 |
59 | } ());
60 |
61 | if (topGG) {
62 | const { discordBotListToken } = require('./data/config.json');
63 | const { AutoPoster } = require('topgg-autoposter');
64 | const ap = AutoPoster(`${String(discordBotListToken)}`, client);
65 |
66 | ap.on('posted', (stats) => {
67 | logger.success(`Posted stats to Top.gg | ${stats.serverCount} servers`);
68 | });
69 |
70 | ap.on('error', (err) => {
71 | logger.error(err);
72 | });
73 | }
74 |
75 | const folders = fs.readdirSync('./src/commands');
76 |
77 | for (const folder of folders) {
78 | const files = fs.readdirSync(`./src/commands/${folder}`);
79 | for (const file of files) {
80 | const command = require(`./commands/${folder}/${file}`);
81 | client.commands.set(command.data.name, command);
82 | }
83 | }
84 |
85 | const eventFiles = fs.readdirSync('./src/events').filter(file => file.endsWith('.js'));
86 | for (const file of eventFiles) {
87 | const event = require(`./events/${file}`);
88 | if (event.once) {
89 | client.once(event.name, (...args) => event.execute(...args));
90 | }
91 | else {
92 | client.on(event.name, (...args) => event.execute(...args));
93 | }
94 | }
95 |
96 | client.login(token);
97 |
--------------------------------------------------------------------------------
/src/events/guild-member-add.js:
--------------------------------------------------------------------------------
1 | const { EmbedBuilder } = require('discord.js');
2 | const { MongoClient } = require('mongodb');
3 | const logger = require('silly-logger');
4 | const { mongodbUri } = require('../data/config.json');
5 |
6 | const dbClient = new MongoClient(String(mongodbUri));
7 |
8 | module.exports = {
9 | name: 'guildMemberAdd',
10 | once: false,
11 | async execute(member) {
12 | if (member.user.bot) return;
13 | const guildId = member.guild.id;
14 | const filter = {
15 | _id: guildId,
16 | };
17 | try {
18 | await dbClient.connect();
19 | const db = dbClient.db("darling");
20 | const collection = db.collection("welcome");
21 | const result = await collection.findOne(filter);
22 | const eckigerluca = await member.client.users.fetch('173374602389618688');
23 | const eckigerluca_avatar = eckigerluca.displayAvatarURL({ size: 1024, extension: 'png', forceStatic: false });
24 | if (result) {
25 | if (result.enabled == true) {
26 | const memberMention = `<@${member.user.id}>`;
27 | const memberName = member.displayName;
28 | const memberNumber = member.guild.memberCount;
29 | const serverName = member.guild.name;
30 |
31 | result.headline = result.headline.replaceAll("${memberName}", memberName);
32 | result.headline = result.headline.replaceAll("${memberNumber}", memberNumber);
33 | result.headline = result.headline.replaceAll("${serverName}", serverName);
34 |
35 | result.message = result.message.replaceAll("${memberMention}", memberMention);
36 | result.message = result.message.replaceAll("${memberName}", memberName);
37 | result.message = result.message.replaceAll("${memberNumber}", memberNumber);
38 | result.message = result.message.replaceAll("${serverName}", serverName);
39 |
40 | result.dm[1] = result.dm[1].replaceAll("${memberMention}", memberMention);
41 | result.dm[1] = result.dm[1].replaceAll("${memberName}", memberName);
42 | result.dm[1] = result.dm[1].replaceAll("${memberNumber}", memberNumber);
43 | result.dm[1] = result.dm[1].replaceAll("${serverName}", serverName);
44 |
45 | const embed = new EmbedBuilder()
46 | .setTitle(result.headline)
47 | .setDescription(result.message)
48 | .setFooter({ text: `Bot by ${eckigerluca.username}`, iconURL: eckigerluca_avatar })
49 | .setTimestamp()
50 | .setColor(result.color);
51 |
52 | if (result.thumbnail == true) {
53 | embed.setThumbnail(member.displayAvatarURL({ size: 512, extension: 'png', forceStatic: false }));
54 | }
55 | if (result.image[0] == true) {
56 | embed.setImage(result.image[1]);
57 | }
58 |
59 | if (result.role[0] == true) {
60 | try {
61 | const role = await member.guild.roles.fetch(result.role[1]);
62 | await member.roles.add(role);
63 | } catch (err) {
64 | logger.error(err);
65 | }
66 | }
67 |
68 | try {
69 | const channel = await member.guild.channels.fetch(result.channelId);
70 |
71 | if (channel) await channel.send({ content: memberMention, embeds: [embed] });
72 | } catch (err) {
73 | logger.error(err);
74 | }
75 |
76 | if (result.dm[0] == true) {
77 | const dmChannel = await member.user.createDM();
78 | await dmChannel.send({ content: result.dm[1] });
79 | }
80 | }
81 | }
82 | }
83 | catch (err) {
84 | logger.error(err);
85 | }
86 | },
87 | };
88 |
--------------------------------------------------------------------------------
/src/events/birthday-checker.js:
--------------------------------------------------------------------------------
1 | const logger = require('silly-logger');
2 | const { scheduleJob, RecurrenceRule } = require('node-schedule');
3 | const { EmbedBuilder } = require('discord.js');
4 | const { color } = require('../data/config.json');
5 |
6 | const rule = new RecurrenceRule();
7 | rule.tz = 'Etc/UTC';
8 | // run at 12:00 UTC
9 | rule.hour = 12;
10 | rule.minute = 0;
11 |
12 | module.exports = {
13 | name: 'ready',
14 | once: true,
15 | async execute(client) {
16 | logger.success("Birthday checker started!");
17 | const eckigerluca = await client.users.fetch('173374602389618688');
18 | const eckigerluca_avatar = eckigerluca.displayAvatarURL({ size: 1024, extension: 'png', forceStatic: false });
19 |
20 | scheduleJob(rule, async () => {
21 | logger.info("Checking birthdays...");
22 | const now = new Date();
23 | const db = client.dbClient.db("darling");
24 | const userCollection = db.collection("users");
25 |
26 | let day = now.getUTCDate();
27 | if (day < 10) day = `0${day}`;
28 | let month = now.getUTCMonth() + 1;
29 | if (month < 10) month = `0${month}`;
30 |
31 | const query = { birthday: { $eq: `${day}/${month}` } };
32 |
33 | const results = await userCollection.find(query).toArray();
34 |
35 | results.forEach(async (result) => {
36 | const updateDoc = {
37 | $inc: {
38 | money: 10000,
39 | },
40 | };
41 | if (result.money !== "∞") await userCollection.updateOne({ _id: result._id }, updateDoc);
42 | const user = await client.users.fetch(result._id);
43 |
44 | const embed = new EmbedBuilder()
45 | .setTitle(`Happy birthday!`)
46 | .setDescription(`Woah! It's your birthday today. Happy birthday!\nHave a wonderful day, get many presents and eat a lot of cake!\nFrom me, you will receive 10.000 ${String.fromCodePoint(0x1FA99)}!`)
47 | .setTimestamp()
48 | .setThumbnail(user.displayAvatarURL({ forceStatic: false, format: 'png', size: 1024 }))
49 | .setColor(color);
50 | user.send({ embeds: [embed] });
51 |
52 | const serverCollection = db.collection("servers");
53 | const filter = { "birthday.enabled": true };
54 | const servers = await serverCollection.find(filter).toArray();
55 | servers.forEach(async (server) => {
56 | const guild = await client.guilds.fetch(server._id);
57 | const channel = guild.channels.cache.get(server.birthday.channel);
58 | if (!channel) return;
59 |
60 | let rawMessage = `Hey, it's ${user}'s birthday today!\nMake sure to gratulate them!`;
61 | let birthdayEmbedDescription;
62 | if (server.birthday.customMessage.enabled) rawMessage = server.birthday.customMessage.message;
63 | birthdayEmbedDescription = rawMessage.replaceAll("${memberMention}", user);
64 | birthdayEmbedDescription = birthdayEmbedDescription.replaceAll("${memberName}", user.username);
65 |
66 | const birthdayEmbed = new EmbedBuilder()
67 | .setTitle(`Happy birthday, ${user.username}!`)
68 | .setDescription(birthdayEmbedDescription)
69 | .setThumbnail(user.displayAvatarURL({ forceStatic: false, format: 'jpg', size: 1024 }))
70 | .setFooter({ text: `Bot by ${eckigerluca.username}`, iconURL: eckigerluca_avatar })
71 | .setColor(color);
72 |
73 | channel.send({ content: `${user}`, embeds: [birthdayEmbed] });
74 | });
75 | });
76 |
77 | logger.success(`Checked birthdays! ${results.length} birthdays today.`);
78 | });
79 | },
80 | };
81 |
--------------------------------------------------------------------------------
/src/website/views/terms-of-service.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Darling. | Terms of Service
16 |
17 |
25 |
26 |
27 |
28 | <%- await include('header.ejs'); %>
29 |
30 |
31 |
32 |
Terms of Service
33 |
34 |
By inviting Darling. to your Discord Server or logging into our website (https://darling-bot.xyz) you agree that you have read, understood and accepted these terms. You are also responsible for informing the members in your Discord Server about these terms. If you do not agree with any of these terms, you are prohibited from using or adding any version of Darling. to your server.
35 |
36 |
Disclaimer
37 |
38 | You are strictly prohibited from using Darling. against the Terms of Service of Discord or for illegal purposes. We are doing our best to prevent these activities, while trying to provide the best user experience as possible. If you find people or communities using Darling. against the ToS of Discord or even for illegal activities, please send us an E-Mail to contact@darling-bot.xyz
39 |
40 |
41 |
Proprietary Rights
42 |
43 | We (Darling. or more specifically <%- legalName %>) own and retain all rights for public available data. We grant you the permission to use this available data for your own needs, but strictly disallow any commercial use. You therefore shall not sell, license or otherwise commercialize the data except if the permission was expressly granted to you.
44 |
45 |
46 |
Availability
47 |
48 |
Darling. is provided as-is. There are no guarantees that it will be available in the future, and its purpose or availability may be changed at any time.
49 |
User related data may be deleted at any time.
50 |
User related data is non-transferable between Discord Accounts.
51 |
Access to all or specific features of Darling. may be revoked, for all or a specific user, at any time.
67 | From here, you can manage some of the bot's features.
68 |
69 | Click on the name of the function to manage them. You can enable/disable them here too!
70 |
106 | Make your Discord Server better with Darling. | Fast, modern and constantly updated
107 |
108 | Invite me!
109 | Support Server
110 |
111 | or
112 |
113 | Bot Dashboard
114 |
115 | Scroll down for features or click here
116 |
211 | Fun commands to keep your community entertained.
212 |
213 | Use the fully customizable welcome messages to greet new members warmly.
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
External Images
223 |
224 | Use one of the many Image-APIs to interact with your members, for example by waving or hugging them.
225 |
226 | There are also meme or anime ( ͡° ͜ʖ ͡°) commands, try them out!
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
With the BEST Web Dashboard
238 |
This is the developers opinion and shouldn't be taken too serious.