├── .gitignore ├── LICENSE ├── README.md ├── package.json ├── src ├── commands │ ├── eval.js │ ├── help.js │ ├── me.js │ ├── role.js │ ├── top.js │ └── user.js ├── configs │ ├── config.json │ └── settings.json ├── events │ ├── commandHandler.js │ ├── deleteStats.js │ ├── messageStats.js │ └── voiceStats.js ├── handlers │ ├── commandHandler.js │ ├── eventHandler.js │ └── mongoHandler.js └── schemas │ ├── messageGuild.js │ ├── messageGuildChannel.js │ ├── messageUser.js │ ├── messageUserChannel.js │ ├── voiceGuild.js │ ├── voiceGuildChannel.js │ ├── voiceJoinedAt.js │ ├── voiceUser.js │ ├── voiceUserChannel.js │ └── voiceUserParent.js └── theark.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Theark 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Discord Stat Bot 2 | # Komutlar 3 | * `me`: Komutu kullanan kişinin istatistiklerini gösterir. 4 | * `top`: Sunucunun toplam istatistiklerini gösterir. 5 | * `role`: Belirttiğiniz rolün toplam istatistiklerini gösterir. 6 | * `user`: Belirttiğiniz kişinin istatistiklerini gösterir. 7 | 8 | # Kurulum 9 | * İlk olarak bilgisayarına [Node JS](https://nodejs.org/en/) indir. 10 | * Daha sonra bir [MongoDB](http://mongodb.com) hesabı oluştur ve connection linki al. 11 | * Eğer bunu yapmayı bilmiyorsan [buraya](https://medium.com/@thearkxd/node-js-projeleri-için-mongodb-atlas-connection-linki-alma-5d955bbe5ae6) tıklayarak medium.com üzerinde yazdığım yazıyı inceleyebilirsin. 12 | * Bu projeyi zip halinde indir. 13 | * Herhangi bir klasöre zipi çıkart. 14 | * Daha sonra src klasörünün içindeki configs klasörünün içine gir `settings.json` ve `config.json` dosyalarının içindeki bilgileri doldur. 15 | * Sonra klasörün içerisinde bir `powershell` ya da `cmd` penceresi aç. 16 | * ```npm install``` yazarak tüm modülleri kur. 17 | * Kurulum bittikten sonra ```npm start``` yaz ve botu başlat. 18 | 19 | Tada 🎉. Artık invite botun hazır. Dilediğin gibi kullanabilirsin. 20 | 21 | # İletişim 22 | * [Discord Sunucum](https://discord.gg/UEPcFtytcc) 23 | * [Discord Profilim](https://discord.com/users/350976460313329665) 24 | * Herhangi bir hata bulmanız durumunda ya da yardım isteyeceğiniz zaman buralardan bana ulaşabilirsiniz. 25 | 26 | ### NOT: Botta MIT lisansı bulunmaktadır. Bu botun dosyalarının benden habersiz paylaşılması/satılması durumunda gerekli işlemler yapılacaktır! 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "theark.js", 6 | "scripts": { 7 | "start": "node theark.js" 8 | }, 9 | "dependencies": { 10 | "cron": "^1.8.2", 11 | "discord.js": "^12.5.1", 12 | "moment": "^2.29.1", 13 | "moment-duration-format": "^2.3.2", 14 | "mongoose": "^5.11.14" 15 | }, 16 | "license": "MIT", 17 | "devDependencies": { 18 | "eslint": "^7.17.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/commands/eval.js: -------------------------------------------------------------------------------- 1 | const Discord = require("discord.js"); 2 | const conf = require("../configs/config.json"); 3 | const settings = require("../configs/settings.json"); 4 | 5 | module.exports = { 6 | conf: { 7 | aliases: [], 8 | name: "eval", 9 | owner: true, 10 | }, 11 | 12 | run: async (client, message, args) => { 13 | if (!args[0]) return; 14 | let code = args.join(" "); 15 | 16 | try { 17 | var result = clean(await eval(code)); 18 | if (result.includes(client.token)) 19 | return message.channel.send("Kancık seni .d"); 20 | message.channel.send(result, { 21 | code: "js", 22 | split: true, 23 | }); 24 | } catch (err) { 25 | message.channel.send(err, { code: "js", split: true }); 26 | } 27 | }, 28 | }; 29 | 30 | function clean(text) { 31 | if (typeof text !== "string") 32 | text = require("util").inspect(text, { depth: 0 }); 33 | text = text 34 | .replace(/`/g, "`" + String.fromCharCode(8203)) 35 | .replace(/@/g, "@" + String.fromCharCode(8203)); 36 | return text; 37 | } 38 | -------------------------------------------------------------------------------- /src/commands/help.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | conf: { 3 | aliases: ["help", "y", "h"], 4 | name: "yardım", 5 | }, 6 | 7 | run: async (client, message, args, embed, prefix) => { 8 | let list = client.commands 9 | .filter((x) => x.conf.help) 10 | .sort((a, b) => b.conf.help - a.conf.help) 11 | .map((x) => `\`${prefix}${x.conf.help}\``) 12 | .join("\n"); 13 | 14 | message.channel.send(embed.setDescription(list)); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/commands/me.js: -------------------------------------------------------------------------------- 1 | const moment = require("moment"); 2 | require("moment-duration-format"); 3 | const conf = require("../configs/config.json"); 4 | const messageUserChannel = require("../schemas/messageUserChannel"); 5 | const voiceUserChannel = require("../schemas/voiceUserChannel"); 6 | const messageUser = require("../schemas/messageUser"); 7 | const voiceUser = require("../schemas/voiceUser"); 8 | const voiceUserParent = require("../schemas/voiceUserParent"); 9 | 10 | module.exports = { 11 | conf: { 12 | aliases: [], 13 | name: 'me', 14 | help: "me" 15 | }, 16 | 17 | run: async (client, message, args, embed) => { 18 | const category = async (parentsArray) => { 19 | const data = await voiceUserParent.find({ guildID: message.guild.id, userID: message.author.id }); 20 | const voiceUserParentData = data.filter((x) => parentsArray.includes(x.parentID)); 21 | let voiceStat = 0; 22 | for (var i = 0; i <= voiceUserParentData.length; i++) { 23 | voiceStat += voiceUserParentData[i] ? voiceUserParentData[i].parentData : 0; 24 | } 25 | return moment.duration(voiceStat).format("H [saat], m [dakika]"); 26 | }; 27 | 28 | const Active1 = await messageUserChannel.find({ guildID: message.guild.id, userID: message.author.id }).sort({ channelData: -1 }); 29 | const Active2 = await voiceUserChannel.find({ guildID: message.guild.id, userID: message.author.id }).sort({ channelData: -1 }); 30 | const voiceLength = Active2 ? Active2.length : 0; 31 | let voiceTop; 32 | let messageTop; 33 | Active1.length > 0 ? messageTop = Active1.splice(0, 5).map(x => `<#${x.channelID}>: \`${Number(x.channelData).toLocaleString()} mesaj\``).join("\n") : messageTop = "Veri bulunmuyor." 34 | Active2.length > 0 ? voiceTop = Active2.splice(0, 5).map(x => `<#${x.channelID}>: \`${moment.duration(x.channelData).format("H [saat], m [dakika]")}\``).join("\n") : voiceTop = "Veri bulunmuyor." 35 | 36 | const messageData = await messageUser.findOne({ guildID: message.guild.id, userID: message.author.id }); 37 | const voiceData = await voiceUser.findOne({ guildID: message.guild.id, userID: message.author.id }); 38 | 39 | const messageDaily = messageData ? messageData.dailyStat : 0; 40 | const messageWeekly = messageData ? messageData.weeklyStat : 0; 41 | 42 | const voiceDaily = moment.duration(voiceData ? voiceData.dailyStat : 0).format("H [saat], m [dakika]"); 43 | const voiceWeekly = moment.duration(voiceData ? voiceData.weeklyStat : 0).format("H [saat], m [dakika]"); 44 | 45 | const filteredParents = message.guild.channels.cache.filter((x) => 46 | x.type === "category" && 47 | !conf.publicParents.includes(x.id) && 48 | !conf.registerParents.includes(x.id) && 49 | !conf.solvingParents.includes(x.id) && 50 | !conf.privateParents.includes(x.id) && 51 | !conf.aloneParents.includes(x.id) && 52 | !conf.funParents.includes(x.id) 53 | ); 54 | 55 | embed.setThumbnail(message.author.avatarURL({ dynamic: true, size: 2048 })) 56 | embed.setDescription(` 57 | ${message.author.toString()} üyesinin sunucu verileri 58 | **───────────────** 59 | **➥ Ses Bilgileri:** 60 | • Toplam: \`${moment.duration(voiceData ? voiceData.topStat : 0).format("H [saat], m [dakika]")}\` 61 | • Public Odalar: \`${await category(conf.publicParents)}\` 62 | • Kayıt Odaları: \`${await category(conf.registerParents)}\` 63 | • Sorun Çözme & Terapi: \`${await category(conf.solvingParents)}\` 64 | • Private Odalar: \`${await category(conf.privateParents)}\` 65 | • Alone Odalar: \`${await category(conf.aloneParents)}\` 66 | • Oyun & Eğlence Odaları: \`${await category(conf.funParents)}\` 67 | • Diğer: \`${await category(filteredParents.map(x => x.id))}\` 68 | **───────────────** 69 | **➥ Sesli Kanal Bilgileri: (\`Toplam ${voiceLength} kanal\`)** 70 | ${voiceTop} 71 | **───────────────** 72 | **➥ Mesaj Bilgileri: (\`Toplam ${messageData ? messageData.topStat : 0} mesaj\`)** 73 | ${messageTop} 74 | **───────────────** 75 | `) 76 | embed.addField("➥ Günlük Verileri:", ` 77 | Mesaj: \`${Number(messageDaily).toLocaleString()} mesaj\` 78 | Ses: \`${voiceDaily}\` 79 | `, true); 80 | embed.addField("➥ Haftalık Verileri:", ` 81 | Mesaj: \`${Number(messageWeekly).toLocaleString()} mesaj\` 82 | Ses: \`${voiceWeekly}\` 83 | `, true); 84 | message.channel.send(embed); 85 | } 86 | }; -------------------------------------------------------------------------------- /src/commands/role.js: -------------------------------------------------------------------------------- 1 | const moment = require("moment"); 2 | require("moment-duration-format"); 3 | const messageUser = require("../schemas/messageUser"); 4 | const voiceUser = require("../schemas/voiceUser"); 5 | 6 | module.exports = { 7 | conf: { 8 | aliases: ["rol"], 9 | name: "role", 10 | help: "role" 11 | }, 12 | 13 | run: async (client, message, args, embed) => { 14 | const role = message.mentions.roles.first() || message.guild.roles.cache.get(args[0]); 15 | if (!role) return message.channel.send(embed.setDescription("Bir rol belirtmelisin!")); 16 | else if (role.members.size === 0) return message.channel.send(embed.setDescription("Bu rol kimsede bulunmuyor!")); 17 | 18 | const messageData = async (type) => { 19 | let data = await messageUser.find({ guildID: message.guild.id }).sort({ topStat: -1 }); 20 | data = data.filter(x => message.guild.members.cache.has(x.userID) && message.guild.members.cache.get(x.userID).roles.cache.has(role.id)); 21 | return data.length > 0 ? data.splice(0, 5).map((x, index) => `\`${index + 1}.\` <@${x.userID}> : \`${Number(x[type]).toLocaleString()} mesaj\``).join(`\n`) : "Veri bulunmuyor!"; 22 | }; 23 | 24 | const voiceData = async (type) => { 25 | let data = await voiceUser.find({ guildID: message.guild.id }).sort({ topStat: -1 }); 26 | data = data.filter(x => message.guild.members.cache.has(x.userID) && message.guild.members.cache.get(x.userID).roles.cache.has(role.id)); 27 | return data.length > 0 ? data.splice(0, 5).map((x, index) => `\`${index + 1}.\` <@${x.userID}> : \`${moment.duration(x[type]).format("H [saat], m [dakika]")}\``).join(`\n`) : "Veri bulunmuyor!"; 28 | }; 29 | 30 | embed.setAuthor(message.guild.name, message.guild.iconURL({ dynamic: true, size: 2048 })) 31 | embed.setThumbnail(message.guild.iconURL({ dynamic: true, size: 2048 })) 32 | message.channel.send(embed.setDescription(` 33 | ${role.toString()} rolüne sahip üyelerin verileri 34 | **───────────────** 35 | 36 | **➥ Toplam Ses Bilgileri:** 37 | ${await voiceData("topStat")} 38 | 39 | **➥ Haftalık Ses Bilgileri:** 40 | ${await voiceData("weeklyStat")} 41 | 42 | **➥ Günlük Ses Bilgileri:** 43 | ${await voiceData("dailyStat")} 44 | 45 | **───────────────** 46 | 47 | **➥ Toplam Mesaj Bilgileri:** 48 | ${await messageData("topStat")} 49 | 50 | **➥ Haftalık Mesaj Bilgileri:** 51 | ${await messageData("weeklyStat")} 52 | 53 | **➥ Günlük Mesaj Bilgileri:** 54 | ${await messageData("dailyStat")} 55 | `)); 56 | } 57 | }; -------------------------------------------------------------------------------- /src/commands/top.js: -------------------------------------------------------------------------------- 1 | const moment = require("moment"); 2 | require("moment-duration-format"); 3 | const messageGuild = require("../schemas/messageGuild"); 4 | const messageGuildChannel = require("../schemas/messageGuildChannel"); 5 | const voiceGuild = require("../schemas/voiceGuild"); 6 | const voiceGuildChannel = require("../schemas/voiceGuildChannel"); 7 | const messageUser = require("../schemas/messageUser"); 8 | const voiceUser = require("../schemas/voiceUser"); 9 | 10 | module.exports = { 11 | conf: { 12 | aliases: [], 13 | name: "top", 14 | help: "top" 15 | }, 16 | 17 | run: async (client, message, args, embed) => { 18 | const messageChannelData = await messageGuildChannel.find({ guildID: message.guild.id }).sort({ channelData: -1 }); 19 | const voiceChannelData = await voiceGuildChannel.find({ guildID: message.guild.id }).sort({ channelData: -1 }); 20 | const messageUsersData = await messageUser.find({ guildID: message.guild.id }).sort({ topStat: -1 }); 21 | const voiceUsersData = await voiceUser.find({ guildID: message.guild.id }).sort({ topStat: -1 }); 22 | const messageGuildData = await messageGuild.findOne({ guildID: message.guild.id }); 23 | const voiceGuildData = await voiceGuild.findOne({ guildID: message.guild.id }); 24 | 25 | const messageChannels = messageChannelData.splice(0, 5).map((x, index) => `\`${index+1}.\` <#${x.channelID}>: \`${Number(x.channelData).toLocaleString()} mesaj\``).join(`\n`); 26 | const voiceChannels = voiceChannelData.splice(0, 5).map((x, index) => `\`${index+1}.\` <#${x.channelID}>: \`${moment.duration(x.channelData).format("H [saat], m [dakika]")}\``).join(`\n`); 27 | const messageUsers = messageUsersData.splice(0, 5).map((x, index) => `\`${index+1}.\` <@${x.userID}>: \`${Number(x.topStat).toLocaleString()} mesaj\``).join(`\n`); 28 | const voiceUsers = voiceUsersData.splice(0, 5).map((x, index) => `\`${index+1}.\` <@${x.userID}>: \`${moment.duration(x.topStat).format("H [saat], m [dakika]")}\``).join(`\n`); 29 | 30 | embed.setAuthor(message.guild.name, message.guild.iconURL({ dynamic: true, size: 2048 })) 31 | embed.setThumbnail(message.guild.iconURL({ dynamic: true, size: 2048 })) 32 | message.channel.send(embed.setDescription(` 33 | ${message.guild.name} sunucusunun toplam verileri 34 | **───────────────** 35 | 36 | **➥ Ses Bilgileri: (\`Toplam ${moment.duration(voiceGuildData ? voiceGuildData.topStat : 0).format("H [saat], m [dakika]")}\`)** 37 | ${voiceUsers.length > 0 ? voiceUsers : "Veri Bulunmuyor."} 38 | 39 | **➥ Ses Kanal Bilgileri:** 40 | ${voiceChannels.length > 0 ? voiceChannels : "Veri Bulunmuyor."} 41 | 42 | **───────────────** 43 | 44 | **➥ Mesaj Bilgileri: (\`Toplam ${Number(messageGuildData ? messageGuildData.topStat : 0).toLocaleString()} mesaj\`)** 45 | ${messageUsers.length > 0 ? messageUsers : "Veri Bulunmuyor."} 46 | 47 | **➥ Mesaj Kanal Bilgileri:** 48 | ${messageChannels.length > 0 ? messageChannels : "Veri Bulunmuyor."} 49 | `)) 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/commands/user.js: -------------------------------------------------------------------------------- 1 | const moment = require("moment"); 2 | require("moment-duration-format"); 3 | const conf = require("../configs/config.json"); 4 | const messageUserChannel = require("../schemas/messageUserChannel"); 5 | const voiceUserChannel = require("../schemas/voiceUserChannel"); 6 | const messageUser = require("../schemas/messageUser"); 7 | const voiceUser = require("../schemas/voiceUser"); 8 | const voiceUserParent = require("../schemas/voiceUserParent"); 9 | 10 | module.exports = { 11 | conf: { 12 | aliases: ["kullanıcı"], 13 | name: 'user', 14 | help: "user [kullanıcı]" 15 | }, 16 | 17 | run: async (client, message, args, embed) => { 18 | const member = message.mentions.members.first() || message.guild.members.cache.get(args[0]); 19 | if (!member) return message.channel.send(embed.setDescription("Bir kullanıcı belirtmelisin!")); 20 | 21 | const category = async (parentsArray) => { 22 | const data = await voiceUserParent.find({ guildID: message.guild.id, userID: member.user.id }); 23 | const voiceUserParentData = data.filter((x) => parentsArray.includes(x.parentID)); 24 | let voiceStat = 0; 25 | for (var i = 0; i <= voiceUserParentData.length; i++) { 26 | voiceStat += voiceUserParentData[i] ? voiceUserParentData[i].parentData : 0; 27 | } 28 | return moment.duration(voiceStat).format("H [saat], m [dakika]"); 29 | }; 30 | 31 | const Active1 = await messageUserChannel.find({ guildID: message.guild.id, userID: member.user.id }).sort({ channelData: -1 }); 32 | const Active2 = await voiceUserChannel.find({ guildID: message.guild.id, userID: member.user.id }).sort({ channelData: -1 }); 33 | const voiceLength = Active2 ? Active2.length : 0; 34 | let voiceTop; 35 | let messageTop; 36 | Active1.length > 0 ? messageTop = Active1.splice(0, 5).map(x => `<#${x.channelID}>: \`${Number(x.channelData).toLocaleString()} mesaj\``).join("\n") : messageTop = "Veri bulunmuyor." 37 | Active2.length > 0 ? voiceTop = Active2.splice(0, 5).map(x => `<#${x.channelID}>: \`${moment.duration(x.channelData).format("H [saat], m [dakika]")}\``).join("\n") : voiceTop = "Veri bulunmuyor." 38 | 39 | const messageData = await messageUser.findOne({ guildID: message.guild.id, userID: member.user.id }); 40 | const voiceData = await voiceUser.findOne({ guildID: message.guild.id, userID: member.user.id }); 41 | 42 | const messageDaily = messageData ? messageData.dailyStat : 0; 43 | const messageWeekly = messageData ? messageData.weeklyStat : 0; 44 | 45 | const voiceDaily = moment.duration(voiceData ? voiceData.dailyStat : 0).format("H [saat], m [dakika]"); 46 | const voiceWeekly = moment.duration(voiceData ? voiceData.weeklyStat : 0).format("H [saat], m [dakika]"); 47 | 48 | const topses = voiceData ? voiceData.topStat : 0 49 | const topmesaj = messageData ? messageData.topStat : 0 50 | 51 | const filteredParents = message.guild.channels.cache.filter((x) => 52 | x.type === "category" && 53 | !conf.publicParents.includes(x.id) && 54 | !conf.registerParents.includes(x.id) && 55 | !conf.solvingParents.includes(x.id) && 56 | !conf.privateParents.includes(x.id) && 57 | !conf.aloneParents.includes(x.id) && 58 | !conf.funParents.includes(x.id) 59 | ); 60 | 61 | embed.setAuthor(member.user.username, member.user.avatarURL({ dynamic: true, size: 2048 })) 62 | embed.setThumbnail(member.user.avatarURL({ dynamic: true, size: 2048 })) 63 | embed.setDescription(` 64 | ${member.toString()} üyesinin sunucu verileri 65 | **───────────────** 66 | **➥ Ses Bilgileri:** 67 | • Toplam: \`${moment.duration(topses).format("H [saat], m [dakika]")}\` 68 | • Public Odalar: \`${await category(conf.publicParents)}\` 69 | • Kayıt Odaları: \`${await category(conf.registerParents)}\` 70 | • Sorun Çözme & Terapi: \`${await category(conf.solvingParents)}\` 71 | • Private Odalar: \`${await category(conf.privateParents)}\` 72 | • Alone Odalar: \`${await category(conf.aloneParents)}\` 73 | • Oyun & Eğlence Odaları: \`${await category(conf.funParents)}\` 74 | • Diğer: \`${await category(filteredParents.map(x => x.id))}\` 75 | **───────────────** 76 | **➥ Kanal Bilgileri: (\`Toplam ${voiceLength} kanal\`)** 77 | ${voiceTop} 78 | **───────────────** 79 | **➥ Mesaj Bilgileri: (\`Toplam ${topmesaj} mesaj\`)** 80 | ${messageTop} 81 | **───────────────** 82 | `) 83 | embed.addField("➥ Günlük Verileri:", ` 84 | Mesaj: \`${Number(messageDaily).toLocaleString()} mesaj\` 85 | Ses: \`${voiceDaily}\` 86 | `, true) 87 | embed.addField("➥ Haftalık Verileri:", ` 88 | Mesaj: \`${Number(messageWeekly).toLocaleString()} mesaj\` 89 | Ses: \`${voiceWeekly}\` 90 | `, true) 91 | message.channel.send(embed) 92 | } 93 | }; -------------------------------------------------------------------------------- /src/configs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "publicParents": [], 3 | "registerParents": [], 4 | "solvingParents": [], 5 | "privateParents": [], 6 | "aloneParents": [], 7 | "funParents": [] 8 | } 9 | -------------------------------------------------------------------------------- /src/configs/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "", 3 | "prefix": [], 4 | "mongoUrl": "", 5 | "owners": [] 6 | } 7 | -------------------------------------------------------------------------------- /src/events/commandHandler.js: -------------------------------------------------------------------------------- 1 | const settings = require("../configs/settings.json"); 2 | const { MessageEmbed } = require("discord.js"); 3 | const client = global.client; 4 | let sended = false; 5 | 6 | setInterval(() => { 7 | client.cooldown.forEach((x, index) => { 8 | if (Date.now() - x.lastUsage > x.cooldown) client.cooldown.delete(index); 9 | }); 10 | }, 5000); 11 | 12 | module.exports = async (message) => { 13 | let prefix = settings.prefix.find((x) => message.content.toLowerCase().startsWith(x)); 14 | if (message.author.bot || !message.guild || !prefix) return; 15 | let args = message.content.substring(prefix.length).trim().split(" "); 16 | let commandName = args[0].toLowerCase(); 17 | 18 | const embed = new MessageEmbed().setColor(message.member.displayHexColor).setAuthor(message.member.displayName, message.author.avatarURL({ dynamic: true, size: 2048 })); 19 | 20 | args = args.splice(1); 21 | let cmd = client.commands.has(commandName) ? client.commands.get(commandName) : client.commands.get(client.aliases.get(commandName)); 22 | 23 | if (cmd) { 24 | if (cmd.conf.owner && !settings.owners.includes(message.author.id)) return; 25 | const cooldown = cmd.conf.cooldown || 3000; 26 | const cd = client.cooldown.get(message.author.id); 27 | if (cd) { 28 | const diff = Date.now() - cd.lastUsage; 29 | if (diff < cooldown) 30 | if (!sended) { 31 | sended = true; 32 | return message.channel.send(embed.setDescription(`Bu komutu tekrar kullanabilmek için **${Number(((cooldown - diff) / 1000).toFixed(2))}** daha beklemelisin!`)).then((x) => x.delete({ timeout: cooldown - diff })); 33 | } 34 | } else client.cooldown.set(message.author.id, { cooldown: cooldown, lastUsage: Date.now() }); 35 | cmd.run(client, message, args, embed, prefix); 36 | } 37 | }; 38 | 39 | module.exports.conf = { 40 | name: "message", 41 | }; 42 | -------------------------------------------------------------------------------- /src/events/deleteStats.js: -------------------------------------------------------------------------------- 1 | const { CronJob } = require("cron"); 2 | const client = global.client; 3 | const messageGuild = require("../schemas/messageGuild"); 4 | const voiceGuild = require("../schemas/voiceGuild"); 5 | const messageUser = require("../schemas/messageUser"); 6 | const voiceUser = require("../schemas/voiceUser"); 7 | 8 | module.exports = () => { 9 | const daily = new CronJob("0 0 * * *", () => { 10 | client.guilds.cache.forEach(async (guild) => { 11 | await messageGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { dailyStat: 0 } }); 12 | await voiceGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { dailyStat: 0 } }); 13 | await messageUser.findOneAndUpdate({ guildID: guild.id }, { $set: { dailyStat: 0 } }); 14 | await voiceUser.findOneAndUpdate({ guildID: guild.id }, { $set: { dailyStat: 0 } }); 15 | }); 16 | }, null, true, "Europe/Istanbul"); 17 | daily.start(); 18 | 19 | const weekly = new CronJob("0 0 * * 0", () => { 20 | client.guilds.cache.forEach(async (guild) => { 21 | await messageGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { weeklyStat: 0 } }); 22 | await voiceGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { weeklyStat: 0 } }); 23 | await messageUser.findOneAndUpdate({ guildID: guild.id }, { $set: { weeklyStat: 0 } }); 24 | await voiceUser.findOneAndUpdate({ guildID: guild.id }, { $set: { weeklyStat: 0 } }); 25 | }); 26 | }, null, true, "Europe/Istanbul"); 27 | weekly.start(); 28 | 29 | const twoWeekly = new CronJob("0 0 1,15 * *", () => { 30 | client.guilds.cache.forEach(async (guild) => { 31 | await messageGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { twoWeeklyStat: 0 } }); 32 | await voiceGuild.findOneAndUpdate({ guildID: guild.id }, { $set: { twoWeeklyStat: 0 } }); 33 | await messageUser.findOneAndUpdate({ guildID: guild.id }, { $set: { twoWeeklyStat: 0 } }); 34 | await voiceUser.findOneAndUpdate({ guildID: guild.id }, { $set: { twoWeeklyStat: 0 } }); 35 | }); 36 | }, null, true, "Europe/Istanbul") 37 | twoWeekly.start(); 38 | }; 39 | 40 | module.exports.conf = { 41 | name: "ready" 42 | }; 43 | -------------------------------------------------------------------------------- /src/events/messageStats.js: -------------------------------------------------------------------------------- 1 | const settings = require("../configs/settings.json"); 2 | const messageUser = require("../schemas/messageUser"); 3 | const messageGuild = require("../schemas/messageGuild"); 4 | const guildChannel = require("../schemas/messageGuildChannel"); 5 | const userChannel = require("../schemas/messageUserChannel"); 6 | 7 | module.exports = async (message) => { 8 | if (message.author.bot || !message.guild || message.content.startsWith(settings.prefix)) return; 9 | await messageUser.findOneAndUpdate({ guildID: message.guild.id, userID: message.author.id }, { $inc: { topStat: 1, dailyStat: 1, weeklyStat: 1, twoWeeklyStat: 1 } }, { upsert: true }); 10 | await messageGuild.findOneAndUpdate({ guildID: message.guild.id }, { $inc: { topStat: 1, dailyStat: 1, weeklyStat: 1, twoWeeklyStat: 1 } }, { upsert: true }); 11 | await guildChannel.findOneAndUpdate({ guildID: message.guild.id, channelID: message.channel.id }, { $inc: { channelData: 1 } }, { upsert: true }); 12 | await userChannel.findOneAndUpdate({ guildID: message.guild.id, userID: message.author.id, channelID: message.channel.id }, { $inc: { channelData: 1 } }, { upsert: true }); 13 | }; 14 | 15 | module.exports.conf = { 16 | name: "message", 17 | }; -------------------------------------------------------------------------------- /src/events/voiceStats.js: -------------------------------------------------------------------------------- 1 | const joinedAt = require("../schemas/voiceJoinedAt"); 2 | const voiceUser = require("../schemas/voiceUser"); 3 | const voiceGuild = require("../schemas/voiceGuild"); 4 | const guildChannel = require("../schemas/voiceGuildChannel"); 5 | const userChannel = require("../schemas/voiceUserChannel"); 6 | const userParent = require("../schemas/voiceUserParent"); 7 | 8 | module.exports = async (oldState, newState) => { 9 | if ((oldState.member && oldState.member.user.bot) || (newState.member && newState.member.user.bot)) return; 10 | 11 | if (!oldState.channelID && newState.channelID) { 12 | await joinedAt.findOneAndUpdate({ userID: newState.id }, { $set: { date: Date.now() } }, { upsert: true }); 13 | } 14 | 15 | const joinedAtData = await joinedAt.findOne({ userID: oldState.id }); 16 | 17 | if (!joinedAtData) { 18 | await joinedAt.findOneAndUpdate({ userID: oldState.id }, { $set: { date: Date.now() } }, { upsert: true }); 19 | } 20 | 21 | const data = Date.now() - joinedAtData.date; 22 | 23 | if (oldState.channelID && !newState.channelID) { 24 | await saveDatas(oldState, oldState.channel, data); 25 | await joinedAt.deleteOne({ userID: oldState.id }); 26 | } else if (oldState.channelID && newState.channelID) { 27 | await saveDatas(oldState, oldState.channel, data); 28 | await joinedAt.findOneAndUpdate({ userID: oldState.id }, { $set: { date: Date.now() } }, { upsert: true }); 29 | } 30 | }; 31 | 32 | async function saveDatas(user, channel, data) { 33 | await voiceUser.findOneAndUpdate({ guildID: user.guild.id, userID: user.id }, { $inc: { topStat: data, dailyStat: data, weeklyStat: data, twoWeeklyStat: data } }, { upsert: true }); 34 | await voiceGuild.findOneAndUpdate({ guildID: user.guild.id }, { $inc: { topStat: data, dailyStat: data, weeklyStat: data, twoWeeklyStat: data } }, { upsert: true }); 35 | await guildChannel.findOneAndUpdate({ guildID: user.guild.id, channelID: channel.id }, { $inc: { channelData: data } }, { upsert: true }); 36 | await userChannel.findOneAndUpdate({ guildID: user.guild.id, userID: user.id, channelID: channel.id }, { $inc: { channelData: data } }, { upsert: true }); 37 | if (channel.parent) await userParent.findOneAndUpdate({ guildID: user.guild.id, userID: user.id, parentID: channel.parentID }, { $inc: { parentData: data } }, { upsert: true }); 38 | } 39 | 40 | module.exports.conf = { 41 | name: "voiceStateUpdate", 42 | }; 43 | -------------------------------------------------------------------------------- /src/handlers/commandHandler.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const client = global.client; 3 | 4 | fs.readdir("./src/commands", (err, files) => { 5 | if (err) console.error(err); 6 | files.forEach((f) => { 7 | let props = require(`../commands/${f}`); 8 | console.log(`[COMMAND] ${props.conf.name} loaded!`); 9 | client.commands.set(props.conf.name, props); 10 | props.conf.aliases.forEach((alias) => { 11 | client.aliases.set(alias, props.conf.name); 12 | }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/handlers/eventHandler.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const client = global.client; 3 | 4 | fs.readdir("./src/events", (err, files) => { 5 | if (err) return console.error(err); 6 | files 7 | .filter((file) => file.endsWith(".js")) 8 | .forEach((file) => { 9 | let prop = require(`../events/${file}`); 10 | if (!prop.conf) return; 11 | client.on(prop.conf.name, prop); 12 | console.log(`[EVENT] ${prop.conf.name} loaded!`); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/handlers/mongoHandler.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const settings = require("../configs/settings.json"); 3 | 4 | mongoose.connect(settings.mongoUrl, { 5 | useUnifiedTopology: true, 6 | useNewUrlParser: true, 7 | useFindAndModify: false, 8 | }); 9 | 10 | mongoose.connection.on("connected", () => { 11 | console.log("Connected to DB"); 12 | }); 13 | mongoose.connection.on("error", () => { 14 | console.error("Connection Error!"); 15 | }); 16 | -------------------------------------------------------------------------------- /src/schemas/messageGuild.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | topStat: { type: Number, default: 0 }, 6 | dailyStat: { type: Number, default: 0 }, 7 | weeklyStat: { type: Number, default: 0 }, 8 | twoWeeklyStat: { type: Number, default: 0 }, 9 | }); 10 | 11 | module.exports = model("messageGuild", schema); 12 | -------------------------------------------------------------------------------- /src/schemas/messageGuildChannel.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | channelID: String, 6 | channelData: { type: Number, default: 0 }, 7 | }); 8 | 9 | module.exports = model("messageGuildChannel", schema); 10 | -------------------------------------------------------------------------------- /src/schemas/messageUser.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | userID: String, 6 | topStat: { type: Number, default: 0 }, 7 | dailyStat: { type: Number, default: 0 }, 8 | weeklyStat: { type: Number, default: 0 }, 9 | twoWeeklyStat: { type: Number, default: 0 }, 10 | }); 11 | 12 | module.exports = model("messageUser", schema); 13 | -------------------------------------------------------------------------------- /src/schemas/messageUserChannel.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | userID: String, 6 | channelID: String, 7 | channelData: { type: Number, default: 0 }, 8 | }); 9 | 10 | module.exports = model("messageUserChannel", schema); 11 | -------------------------------------------------------------------------------- /src/schemas/voiceGuild.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | topStat: { type: Number, default: 0 }, 6 | dailyStat: { type: Number, default: 0 }, 7 | weeklyStat: { type: Number, default: 0 }, 8 | twoWeeklyStat: { type: Number, default: 0 }, 9 | }); 10 | 11 | module.exports = model("voiceGuild", schema); 12 | -------------------------------------------------------------------------------- /src/schemas/voiceGuildChannel.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | channelID: String, 6 | channelData: { type: Number, default: 0 }, 7 | }); 8 | 9 | module.exports = model("voiceGuildChannel", schema); 10 | -------------------------------------------------------------------------------- /src/schemas/voiceJoinedAt.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | userID: String, 5 | date: Number, 6 | }); 7 | 8 | module.exports = model("voiceJoinedAt", schema); 9 | -------------------------------------------------------------------------------- /src/schemas/voiceUser.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | userID: String, 6 | topStat: { type: Number, default: 0 }, 7 | dailyStat: { type: Number, default: 0 }, 8 | weeklyStat: { type: Number, default: 0 }, 9 | twoWeeklyStat: { type: Number, default: 0 }, 10 | }); 11 | 12 | module.exports = model("voiceUser", schema); 13 | -------------------------------------------------------------------------------- /src/schemas/voiceUserChannel.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | userID: String, 6 | channelID: String, 7 | channelData: { type: Number, default: 0 }, 8 | }); 9 | 10 | module.exports = model("voiceUserChannel", schema); 11 | -------------------------------------------------------------------------------- /src/schemas/voiceUserParent.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const schema = Schema({ 4 | guildID: String, 5 | userID: String, 6 | parentID: String, 7 | parentData: { type: Number, default: 0 }, 8 | }); 9 | 10 | module.exports = model("voiceUserParent", schema); 11 | -------------------------------------------------------------------------------- /theark.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection } = require("discord.js"); 2 | const client = (global.client = new Client({ fetchAllMembers: true })); 3 | const settings = require("./src/configs/settings.json"); 4 | client.commands = new Collection(); 5 | client.aliases = new Collection(); 6 | client.cooldown = new Map(); 7 | require("./src/handlers/commandHandler"); 8 | require("./src/handlers/eventHandler"); 9 | require("./src/handlers/mongoHandler"); 10 | 11 | client 12 | .login(settings.token) 13 | .then(() => console.log("[BOT] Bot connected!")) 14 | .catch(() => console.log("[BOT] Bot can't connected!")); 15 | --------------------------------------------------------------------------------