Added analystics
This commit is contained in:
1 parent
0130b3c9af
commit
bd91cf9697
13 files changed
+253
-24
No files matched your search
+4
-1
@@ -1,3 +1,5 @@
|
||||
const { SlashCommandBuilder, Routes, EmbedBuilder, ActivityType } = require('discord.js');
|
||||
|
||||
const client = require('../index.js').bsl;
|
||||
const servers = require('../models/server');
|
||||
const bots = require('../models/bot');
|
||||
@@ -9,6 +11,8 @@ const ms = require("parse-ms-2");
|
||||
client.on('ready', async () => {
|
||||
const bot = await bots.find({ verified: true });
|
||||
client.user.setPresence({ activities: [{ name: 'botscord.xyz | ' + bot.length + ' bots' }] });
|
||||
client.user.setActivity('botscord.xyz | ' + bot.length + ' bots', { type: ActivityType.Watching });
|
||||
|
||||
console.log(bsl, 'Bot is ready!');
|
||||
// Log server count
|
||||
setTimeout(() => {
|
||||
@@ -16,7 +20,6 @@ client.on('ready', async () => {
|
||||
`${client.guilds.cache.size} servers`);
|
||||
}, 1000);
|
||||
});
|
||||
const { SlashCommandBuilder, Routes, EmbedBuilder } = require('discord.js');
|
||||
const { REST } = require('@discordjs/rest');
|
||||
const commands = [
|
||||
new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'),
|
||||
|
||||
@@ -20,7 +20,7 @@ const client = new Client({
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.GuildMessageReactions,
|
||||
GatewayIntentBits.GuildMessageTyping,
|
||||
GatewayIntentBits.DirectMessages,
|
||||
GatewayIntentBits.DirectMessages
|
||||
|
||||
]
|
||||
});
|
||||
|
||||
@@ -14,6 +14,10 @@ let hm = new mongoose.Schema({
|
||||
users: String,
|
||||
votes: { type: Number, default: 0 },
|
||||
token: String,
|
||||
country: Object,
|
||||
analytics: Object,
|
||||
analytics_visitors: Number,
|
||||
analytics_invites: Number,
|
||||
});
|
||||
|
||||
module.exports = mongoose.model("bots", hm);
|
||||
@@ -36,6 +36,8 @@
|
||||
"express": "^4.18.1",
|
||||
"express-rate-limit": "^6.5.1",
|
||||
"express-session": "^1.17.3",
|
||||
"geoip-lite": "^1.4.6",
|
||||
"ipware": "^2.0.0",
|
||||
"memorystore": "^1.6.7",
|
||||
"mongoose": "^6.5.0",
|
||||
"parse-ms-2": "^1.0.0",
|
||||
|
||||
@@ -79,28 +79,27 @@ client.on('interactionCreate', async interaction => {
|
||||
}
|
||||
});
|
||||
client.on("guildMemberAdd", async (member) => {
|
||||
let guild = client.guilds.cache.get(config.discord.id);
|
||||
console.log(colors.green("Website: "), `${member.user.tag} has joined ${member.guild.name}`);
|
||||
let guild = client.guilds.cache.get(global.config.discord.id);
|
||||
if (member.user.bot) {
|
||||
try {
|
||||
guild.member(member.id).roles.add(config.server.roles.botlist.bot);
|
||||
client.channels.cache.get(config.server.channels.new).send(`${member.user.tag} has joined the server!`);
|
||||
guild.members.cache.get(member.id).roles.add(global.config.discord.roles.bot);
|
||||
client.channels.cache.get(global.config.bot.channels.welcome).send(`${member.user.tag} has joined the server!`);
|
||||
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
guild.member(member.id).roles.add(config.server.roles.botlist.user);
|
||||
client.channels.cache.get(config.server.channels.new).send(`${member.user.tag} has joined the server!`);
|
||||
guild.members.cache.get(member.id).roles.add(global.config.discord.roles.user);
|
||||
client.channels.cache.get(global.config.bot.channels.welcome).send(`${member.user.tag} has joined the server!`);
|
||||
} catch (error) {
|
||||
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
});
|
||||
var cooldown = [];
|
||||
client.on("messageCreate", async (message) => {
|
||||
console.log(cooldown
|
||||
)
|
||||
if (message.author.bot) return;
|
||||
if (message.channel.type === "dm") return;
|
||||
if (cooldown.some(code => code.id === message.author.id)){
|
||||
|
||||
@@ -616,6 +616,9 @@ video {
|
||||
.col-auto {
|
||||
grid-column: auto;
|
||||
}
|
||||
.col-span-4 {
|
||||
grid-column: span 4 / span 4;
|
||||
}
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
@@ -751,6 +754,9 @@ video {
|
||||
.ml-36 {
|
||||
margin-left: 9rem;
|
||||
}
|
||||
.mb-1 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
@@ -819,6 +825,11 @@ video {
|
||||
.h-3 {
|
||||
height: 0.75rem;
|
||||
}
|
||||
.max-h-fit {
|
||||
max-height: -webkit-fit-content;
|
||||
max-height: -moz-fit-content;
|
||||
max-height: fit-content;
|
||||
}
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
@@ -1015,6 +1026,10 @@ video {
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
.columns-4 {
|
||||
-moz-columns: 4;
|
||||
columns: 4;
|
||||
}
|
||||
.grid-flow-col {
|
||||
grid-auto-flow: column;
|
||||
}
|
||||
@@ -1039,6 +1054,9 @@ video {
|
||||
.grid-cols-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
.grid-rows-4 {
|
||||
grid-template-rows: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
.flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
@@ -1093,6 +1111,9 @@ video {
|
||||
.gap-11 {
|
||||
gap: 2.75rem;
|
||||
}
|
||||
.gap-10 {
|
||||
gap: 2.5rem;
|
||||
}
|
||||
.gap-x-0 {
|
||||
-moz-column-gap: 0px;
|
||||
column-gap: 0px;
|
||||
@@ -2161,6 +2182,15 @@ body {
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
|
||||
.lg\:m-4 {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.lg\:mx-14 {
|
||||
margin-left: 3.5rem;
|
||||
margin-right: 3.5rem;
|
||||
}
|
||||
|
||||
.lg\:mt-0 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
@@ -2193,6 +2223,14 @@ body {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.lg\:w-1\/4 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.lg\:w-2\/3 {
|
||||
width: 66.666667%;
|
||||
}
|
||||
|
||||
.lg\:flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
@@ -2204,6 +2242,10 @@ body {
|
||||
.lg\:items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.lg\:p-10 {
|
||||
padding: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
|
||||
@@ -23,17 +23,23 @@ router.get('/callback', passport.authenticate('discord', {
|
||||
keepSessionInfo: true
|
||||
}), function (req, res) {
|
||||
try {
|
||||
request({
|
||||
url: `https://discordapp.com/api/v8/guilds/${config.server.id}/members/${req.user.id}`,
|
||||
var lol = request({
|
||||
url: `https://discord.com/api/v10/guilds/${global.config.discord.id}/members/${req.user.id}`,
|
||||
method: "PUT",
|
||||
json: {
|
||||
access_token: req.user.accessToken
|
||||
},
|
||||
headers: {
|
||||
"Authorization": `Bot ${client.token}`
|
||||
"Authorization": `Bot ${global.bsl.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
}, function (error, response, body){
|
||||
console.log(error)
|
||||
console.log(body)
|
||||
});
|
||||
} catch { };
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
};
|
||||
const embed = new client.embed()
|
||||
.setTitle('User logged in')
|
||||
.setDescription(`${req.user.username}#${req.user.discriminator} logged in\nID: ${req.user.id}`)
|
||||
|
||||
@@ -3,6 +3,9 @@ var express = require('express'),
|
||||
var bots = require('../../../models/bot');
|
||||
var votes = require('../../../models/votes');
|
||||
const client = require('../../index');
|
||||
var getIP = require('ipware')().get_ip;
|
||||
var geoip = require('geoip-lite');
|
||||
|
||||
function makeid(length) {
|
||||
var result = '';
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
@@ -78,6 +81,36 @@ router.get('/:botID', async function (req, res) {
|
||||
req.session.error = "No bot found";
|
||||
return res.redirect('/');
|
||||
}
|
||||
let referresURL = String(req.headers.referer).replace("undefined", "Unkown").split('.').join(',');
|
||||
await bots.updateOne({
|
||||
botID: req.params.botID
|
||||
}, {
|
||||
$inc: {
|
||||
analytics_visitors: 1
|
||||
}
|
||||
})
|
||||
|
||||
var ipInfo = getIP(req);
|
||||
var ip = ipInfo.clientIp;
|
||||
var geo = geoip.lookup(ip);
|
||||
|
||||
if (geo) {
|
||||
let CountryCode = geo.country || "TR"
|
||||
await bots.updateOne({
|
||||
botID: req.params.botID
|
||||
}, {
|
||||
$inc: {
|
||||
[`country.${CountryCode}`]: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
await bots.updateOne({
|
||||
botID: req.params.botID
|
||||
}, {
|
||||
$inc: {
|
||||
[`analytics.${referresURL}`]: 1
|
||||
}
|
||||
})
|
||||
let coowner = new Array()
|
||||
await bot.owners.forEach(async function (a) {
|
||||
try {
|
||||
@@ -131,6 +164,30 @@ router.get('/:botID/settings', async function (req, res) {
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:botID/analytics', async function (req, res) {
|
||||
if (!req.user) {
|
||||
req.session.backURL = req.originalUrl;
|
||||
return res.redirect('/auth');
|
||||
} else {
|
||||
bots.findOne({ id: req.params.botID }, async function (err, bot) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return res.redirect('/');
|
||||
}
|
||||
if (!bot) {
|
||||
req.session.error = "No bot found";
|
||||
return res.redirect('/');
|
||||
}
|
||||
res.render('bot/analytics', {
|
||||
bot: bot,
|
||||
user: req.user,
|
||||
bota: await global.bsl.users.fetch(bot.id)
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:botID/settings', async function (req, res) {
|
||||
if (!req.user) {
|
||||
req.session.backURL = req.originalUrl;
|
||||
|
||||
@@ -131,7 +131,7 @@ router.get('/:server', function (req, res) {
|
||||
res.render('server/index', {
|
||||
user: req.user,
|
||||
server: server,
|
||||
serverr: global.client.guilds.cache.get(server.id)
|
||||
serverr: global.bsl.guilds.cache.get(server.id)
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<%- include('../includes/header.ejs', {title: 'Analytics' + bot.name}) %>
|
||||
<br>
|
||||
<div class="p-10 ">
|
||||
<h2 style="margin-top: -10px;" class="text-white"><i class="fa fa-chart-bar"></i> Analytics</h2>
|
||||
<br>
|
||||
<div class="flex flex-wrap gap-10">
|
||||
<div class="mb-4 w-fit">
|
||||
<div class="bg-dark-200 border-left-primary shadow h-100 py-2">
|
||||
<div class="col-auto">
|
||||
<i class="fa fa-chevron-up fa-2x text-white"></i>
|
||||
</div>
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1 text-white">Votes</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-white"><%= bot.votes || 0 %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 w-fit">
|
||||
<div class="bg-dark-200 border-left-success shadow h-100 py-2">
|
||||
<div class="col-auto">
|
||||
<i class="fa fa-plus fa-2x text-white"></i>
|
||||
</div>
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-success text-uppercase mb-1 text-white">Invites
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-white"><%= bot.analytics_invites || 0 %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" mb-4 w-fit">
|
||||
<div class="card bg-dark-200 border-left-info shadow h-100 py-2">
|
||||
<div class="col-auto">
|
||||
<i class="fa fa-eye fa-2x text-white"></i>
|
||||
</div>
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-info text-uppercase mb-1 text-white">Visitors
|
||||
<!-- small style="opacity: 75%" class="text-white">/week</small -->
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-white"><%= bot.analytics_visitors || 0%></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 w-fit">
|
||||
<div class="bg-dark-200 border-left-warning shadow h-100 py-2">
|
||||
<div class="col-auto">
|
||||
<i class="fa fa-circle status-<%= bota.presence.status %> fa-2x"></i>
|
||||
</div>
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1 text-white">Status</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-white"><%= bota.presence.status.toUpperCase() %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 font-italic">
|
||||
<h3 style="color: #5f79da" class="text-uppercase">Referrers</h3>
|
||||
<p style="color: rgb(126, 126, 126)">The domain names of the sites that most redirect to your bot's page.</p>
|
||||
</div>
|
||||
<table id="analytics_referring" class="table table-hover" style="width:100%; color: #fff">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Referring Url</th>
|
||||
<th>Total referrers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if(bot.analytics) { %>
|
||||
<% Object.keys(bot.analytics).sort((a,b) => bot.analytics[b] - bot.analytics[a]).forEach(b => { %>
|
||||
<tr>
|
||||
<td translate="no"><span style="display: flex; align-items: center;"><%= b.split(",").join(".") %></span></td>
|
||||
<td><span style="display: flex; align-items: center;"><%= bot.analytics[b] %></span></td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-2 font-italic">
|
||||
<h3 style="color: #5f79da" class="text-uppercase">Countries</h3>
|
||||
<p style="color: rgb(126, 126, 126)">These are the countries that enter your bot's page.</p>
|
||||
</div>
|
||||
<table id="analytics_country" class="table table-hover" style="width:100%; color: #fff">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Country</th>
|
||||
<th>Total viewers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%
|
||||
if(bot.country) {
|
||||
Object.keys(bot.country).sort((a,b) => bot.country[b] - bot.country[a]).forEach(b => {
|
||||
%>
|
||||
<tr>
|
||||
<td translate="no"><span style="display: flex; align-items: center;"><img src="https://www.countryflags.io/<%= b %>/flat/32.png"> <%= b %></span></td>
|
||||
<td><span style="display: flex; align-items: center;"><%= bot.country[b] %></span></td>
|
||||
</tr>
|
||||
<%
|
||||
})
|
||||
}
|
||||
%>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1,6 +1,12 @@
|
||||
<%- include("../includes/header.ejs", {title: "Edit " + bot.name}) %>
|
||||
<!-- create form -->
|
||||
<div class="container-sm p-10">
|
||||
<!-- button with redirect to /analystics -->
|
||||
<a href="/bot/<%= bot.id %>/analytics" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
|
||||
<i class="fas fa-chart-bar"></i>
|
||||
<span>Analytics</span>
|
||||
</a>
|
||||
<br><br>
|
||||
<form method="post" action="">
|
||||
<div class="relative z-0 mb-6 w-full group">
|
||||
<textarea type="text" name="bot_description" id="bot_name" class="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer" placeholder=" " required rows="5"><%= bot.long_description %></textarea>
|
||||
|
||||
@@ -29,12 +29,18 @@
|
||||
<meta property="og:description" content="<%= server.description %>
|
||||
|
||||
🟢 <%= global.bsl.guilds.cache.get(server.id).members.cache.filter(a => a.presence?.status).size %> onlineᅠᅠᅠᅠ⚫ <%= global.bsl.guilds.cache.get(server.id).memberCount %> members">
|
||||
<% } %>
|
||||
<meta property="og:title" content="BotsCord.xyz" />
|
||||
<% } else if(typeof bota !="undefined" ) { %>
|
||||
<meta property="og:url" content="http://botscord.xyz/server/<%=bota.id %>" />
|
||||
<meta property="og:image" content="https://cdn.discordapp.com/avatars/<%=bota.id %>/<%=bota.avatar %>.png" />
|
||||
<meta property="og:description" content="<%= bot.description %>">
|
||||
<% }else{ %>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="http://botscord.xyz" />
|
||||
<meta property="og:image" content="http://botscord.xyz/img/logo.png" />
|
||||
<meta property="og:description" content="Botscord is a place where you can promote and vote for your favorite bot/server!" />
|
||||
<% } %>
|
||||
<meta property="og:title" content="BotsCord.xyz" />
|
||||
|
||||
<meta name="theme-color" content="#FF0000">
|
||||
<meta name="author" content="BotsCord">
|
||||
<meta name="robots" content="index, follow">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<%- include('../includes/header.ejs', { title: server.name, server: server}) %>
|
||||
<br><br><br><br>
|
||||
<div class="flex space-x-4 py-2 lg:h-5/6 sm:min-h-min">
|
||||
<div class="p-10 bg-blue-color w-2/3 text-white h-full m-4 mx-14 text-ellipsis">
|
||||
<div class="lg:flex space-x-4 py-2 lg:h-5/6 sm:min-h-min">
|
||||
<div class="p-10 bg-blue-color w-full text-white h-full m-4 lg:mx-14 text-ellipsis lg:w-2/3">
|
||||
<p class="text-white text-clip">
|
||||
<pre style="white-space: pre-wrap;" class="text-clip break-words w-full h-full"><br><%= server.long_description %></pre>
|
||||
<pre style="white-space: pre-wrap;" class="text-clip break-wordsw-full h-full"><br><%= server.long_description %></pre>
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-blue-color w-1/4 p-10 text-white h-full m-4 ">
|
||||
<img class="w-full rounded-full" src="<%= serverr.icon %>" alt="<%= server.name %>" onerror="this.src='/img/logo.png'">
|
||||
<div class="bg-blue-color w-full p-10 text-white h-full lg:w-1/4 lg:m-4">
|
||||
<img class="w-full rounded-full max-w-xs" src="https://cdn.discordapp.com/avatars/<%=server.id %>/<%=serverr.icon %>.png" alt="<%= server.name %>" onerror="this.src='/img/logo.png'">
|
||||
<h1 class="text-3xl">
|
||||
<%= server.name %>
|
||||
</h1>
|
||||
@@ -17,7 +17,7 @@
|
||||
Join</a>
|
||||
<br>
|
||||
<% if(user) { if(serverr.members.cache.get(user.id)) {
|
||||
if(serverr.members.cache.get(user.id).permissions.has('ADMINISTRATOR')) { %>
|
||||
if(serverr.members.cache.get(user.id).permissions.has(global.discord.PermissionsBitField.adminstrator)) { %>
|
||||
<div class="h6 mt-4">
|
||||
<i class="fa user-crown"></i>Owner Options
|
||||
</div>
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
<div class="box-2-p"><i class="mt-1 fa fa-users"></i></div>
|
||||
<p class="box-2">Members: <%= serverr.memberCount.toLocaleString().replace(',', '.' ) %>/ <%= global.bsl.guilds.cache.get(server.id).members.cache.filter(a => a.presence?.status).size %> online
|
||||
<p class="box-2">Members: <%= serverr.memberCount.toLocaleString().replace(',', '.' ) %>/ <%= serverr.members.cache.filter(a => a.presence?.status).size %> online
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
|
||||
Reference in new issue
Block a user