This commit is contained in:
Dragon Fire
2021-05-18 19:56:45 -04:00
parent 78ff824f1a
commit a334819db4
11 changed files with 248 additions and 232 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ config.json
command-leaderboard.json
command-last-run.json
blacklist.json
cleverbot.json
patreon.json
# Tensorflow Models
tf_models/
+20 -28
View File
@@ -121,16 +121,16 @@ client.on('ready', async () => {
}
}, 1.8e+6);
// Import Cleverbot users
// Import forced patrons
try {
const results = client.importCleverbotAllowed();
const results = client.patreon.importForced();
if (results) {
client.logger.info('[CLEVERBOT] cleverbot.json successfully loaded.');
client.logger.info('[CLEVERBOT] patreon.json successfully loaded.');
} else {
client.logger.error('[CLEVERBOT] cleverbot.json is not formatted correctly.');
client.logger.error('[CLEVERBOT] patreon.json is not formatted correctly.');
}
} catch (err) {
client.logger.error(`[CLEVERBOT] Could not parse cleverbot.json:\n${err.stack}`);
client.logger.error(`[CLEVERBOT] Could not parse patreon.json:\n${err.stack}`);
}
// Import blacklist
@@ -213,37 +213,29 @@ client.on('ready', async () => {
// Import Patrons
try {
await client.fetchPatrons();
for (const patron of client.patrons) {
if (client.allowedUsers.includes(patron)) continue;
client.allowedUsers.push(patron);
}
await client.patreon.fetchPatrons();
setInterval(() => {
client.fetchPatrons().then(() => {
for (const patron of client.patrons) {
if (client.allowedUsers.includes(patron)) continue;
client.allowedUsers.push(patron);
}
client.logger.info('[PATREON] Updated patron list.');
}).catch(err => client.logger.error(`[PATREON] Failed to update patron list:\n${err.stack}`));
client.patreon.fetchPatrons()
.then(() => client.logger.info('[PATREON] Updated patron list.'))
.catch(err => client.logger.error(`[PATREON] Failed to update patron list:\n${err.stack}`));
}, 3.6e+6);
client.logger.info(`[PATREON] Fetched ${client.patrons.length} patrons.`);
client.logger.info('[PATREON] Fetched patrons.');
} catch (err) {
client.logger.error(`[PATREON] Failed to fetch patrons:\n${err.stack}`);
}
// Post bot list stats
await client.postTopGGStats();
await client.postBotsGGStats();
await client.postDiscordBotListStats();
await client.postCarbonStats();
await client.postBlistStats();
await client.botList.postTopGGStats();
await client.botList.postBotsGGStats();
await client.botList.postDiscordBotListStats();
await client.botList.postCarbonStats();
await client.botList.postBlistStats();
setInterval(() => {
client.postTopGGStats();
client.postBotsGGStats();
client.postDiscordBotListStats();
client.postCarbonStats();
client.postBlistStats();
client.botList.postTopGGStats();
client.botList.postBotsGGStats();
client.botList.postDiscordBotListStats();
client.botList.postCarbonStats();
client.botList.postBlistStats();
}, 1.8e+6);
});
+1 -1
View File
@@ -13,7 +13,7 @@ module.exports = class CleverbotEndCommand extends Command {
}
run(msg) {
if (!this.client.isOwner(msg.author) && !this.client.allowedUsers.includes(msg.author.id)) {
if (!this.client.isOwner(msg.author) && !this.client.patreon.isPatron(msg.author.id)) {
return msg.say(stripIndents`
You are not currently allowed to use Cleverbot.
Please visit ${this.client.options.invite} for more information.
+1 -1
View File
@@ -22,7 +22,7 @@ module.exports = class CleverbotCommand extends Command {
}
run(msg) {
if (!this.client.isOwner(msg.author) && !this.client.allowedUsers.includes(msg.author.id)) {
if (!this.client.isOwner(msg.author) && !this.client.patreon.isPatron(msg.author.id)) {
return msg.say(stripIndents`
You are not currently allowed to use Cleverbot.
Please visit ${this.client.options.invite} for more information.
-30
View File
@@ -1,30 +0,0 @@
const Command = require('../../structures/Command');
module.exports = class AllowCleverbotCommand extends Command {
constructor(client) {
super(client, {
name: 'allow-cleverbot',
aliases: ['allow-clevs'],
group: 'util',
memberName: 'allow-cleverbot',
description: 'Allows a user to use Cleverbot.',
details: 'Only the bot owner(s) may use this command.',
ownerOnly: true,
guarded: true,
args: [
{
key: 'target',
prompt: 'Who do you want to allow? Use the ID.',
type: 'string'
}
]
});
}
run(msg, { target }) {
if (this.client.allowedUsers.includes(target)) return msg.say(`🧠 \`${target}\` is already allowed.`);
this.client.allowedUsers.push(target);
this.client.exportCleverbotAllowed();
return msg.say(`🧠 Allowed \`${target}\` to use Cleverbot.`);
}
};
-31
View File
@@ -1,31 +0,0 @@
const Command = require('../../structures/Command');
const { removeFromArray } = require('../../util/Util');
module.exports = class DisallowCleverbotCommand extends Command {
constructor(client) {
super(client, {
name: 'disallow-cleverbot',
aliases: ['disallow-clevs'],
group: 'util',
memberName: 'disallow-cleverbot',
description: 'Disallows a user from using Cleverbot.',
details: 'Only the bot owner(s) may use this command.',
ownerOnly: true,
guarded: true,
args: [
{
key: 'target',
prompt: 'Who do you want to disallow? Use the ID.',
type: 'string'
}
]
});
}
run(msg, { target }) {
if (!this.client.allowedUsers.includes(target)) return msg.say(`🧠 \`${target}\` is not allowed.`);
removeFromArray(this.client.allowedUsers, target);
this.client.exportCleverbotAllowed();
return msg.say(`🧠 Disallowed \`${target}\` from using Cleverbot.`);
}
};
+29
View File
@@ -0,0 +1,29 @@
const Command = require('../../structures/Command');
module.exports = class ForcePatronCommand extends Command {
constructor(client) {
super(client, {
name: 'force-patron',
group: 'util',
memberName: 'force-patron',
description: 'Allows a user to use patron-only commands.',
details: 'Only the bot owner(s) may use this command.',
ownerOnly: true,
guarded: true,
args: [
{
key: 'target',
prompt: 'Who do you want to allow? Use the ID.',
type: 'string'
}
]
});
}
run(msg, { target }) {
if (this.client.patreon.isPatron(target)) return msg.say(`💸 \`${target}\` is already a patron.`);
this.client.patreon.forced.push(target);
this.client.patreon.exportForced();
return msg.say(`💸 Allowed \`${target}\` to use patron-only commands.`);
}
};
+30
View File
@@ -0,0 +1,30 @@
const Command = require('../../structures/Command');
const { removeFromArray } = require('../../util/Util');
module.exports = class UnforcePatronCommand extends Command {
constructor(client) {
super(client, {
name: 'unforce-patron',
group: 'util',
memberName: 'unforce-patron',
description: 'Disallows a user from using patron-only commands.',
details: 'Only the bot owner(s) may use this command.',
ownerOnly: true,
guarded: true,
args: [
{
key: 'target',
prompt: 'Who do you want to disallow? Use the ID.',
type: 'string'
}
]
});
}
run(msg, { target }) {
if (!this.client.patreon.isPatron(target)) return msg.say(`💸 \`${target}\` is not a patron.`);
removeFromArray(this.client.patreon.forced, target);
this.client.patreon.exportForced();
return msg.say(`💸 Disallowed \`${target}\` from using patron-only commands.`);
}
};
+96
View File
@@ -0,0 +1,96 @@
const request = require('node-superfetch');
const {
TOP_GG_TOKEN,
BOTS_GG_TOKEN,
DISCORDBOTLIST_TOKEN,
CARBON_TOKEN,
BLIST_TOKEN
} = process.env;
module.exports = class BotList {
constructor(client) {
Object.defineProperty(this, 'client', { value: client });
}
async postTopGGStats() {
if (!TOP_GG_TOKEN) return null;
try {
const { body } = await request
.post(`https://top.gg/api/bots/${this.client.user.id}/stats`)
.set({ Authorization: TOP_GG_TOKEN })
.send({ server_count: this.client.guilds.cache.size });
this.client.logger.info('[TOP.GG] Posted stats.');
return body;
} catch (err) {
this.client.logger.error(`[TOP.GG] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postBotsGGStats() {
if (!BOTS_GG_TOKEN) return null;
try {
const { body } = await request
.post(`https://discord.bots.gg/api/v1/bots/${this.client.user.id}/stats`)
.set({ Authorization: BOTS_GG_TOKEN })
.send({ guildCount: this.client.guilds.cache.size });
this.client.logger.info('[BOTS.GG] Posted stats.');
return body;
} catch (err) {
this.client.logger.error(`[BOTS.GG] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postDiscordBotListStats() {
if (!DISCORDBOTLIST_TOKEN) return null;
try {
const { body } = await request
.post(`https://discordbotlist.com/api/v1/bots/${this.client.user.id}/stats`)
.set({ Authorization: DISCORDBOTLIST_TOKEN })
.send({
guilds: this.client.guilds.cache.size,
users: this.client.users.cache.size,
voice_connections: this.client.dispatchers.size
});
this.client.logger.info('[DISCORDBOTLIST] Posted stats.');
return body;
} catch (err) {
this.client.logger.error(`[DISCORDBOTLIST] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postCarbonStats() {
if (!CARBON_TOKEN) return null;
try {
const { body } = await request
.post('https://www.carbonitex.net/discord/data/botdata.php')
.send({
key: CARBON_TOKEN,
servercount: this.client.guilds.cache.size,
botid: this.client.user.id
});
this.client.logger.info('[CARBON] Posted stats.');
return body;
} catch (err) {
this.client.logger.error(`[CARBON] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postBlistStats() {
if (!BLIST_TOKEN) return null;
try {
const { body } = await request
.patch(`https://blist.xyz/api/v2/bot/${this.client.user.id}/stats/`)
.set({ Authorization: BLIST_TOKEN })
.send({ server_count: this.client.guilds.cache.size });
this.client.logger.info('[BLIST] Posted stats.');
return body;
} catch (err) {
this.client.logger.error(`[BLIST] Failed to post stats:\n${err.stack}`);
return err;
}
}
};
+5 -140
View File
@@ -11,6 +11,8 @@ const url = require('url');
const path = require('path');
const Redis = require('./Redis');
const Font = require('./Font');
const BotList = require('./BotList');
const Patreon = require('./Patreon');
const PhoneManager = require('./phone/PhoneManager');
const TimerManager = require('./remind/TimerManager');
const PokemonStore = require('./pokemon/PokemonStore');
@@ -21,14 +23,7 @@ const {
XIAO_WEBHOOK_TOKEN,
REPORT_CHANNEL_ID,
JOIN_LEAVE_CHANNEL_ID,
COMMAND_CHANNEL_ID,
PATREON_ACCESS_TOKEN,
PATREON_CAMPAIGN_ID,
TOP_GG_TOKEN,
BOTS_GG_TOKEN,
DISCORDBOTLIST_TOKEN,
CARBON_TOKEN,
BLIST_TOKEN
COMMAND_CHANNEL_ID
} = process.env;
module.exports = class XiaoClient extends CommandoClient {
@@ -46,13 +41,14 @@ module.exports = class XiaoClient extends CommandoClient {
this.redis = Redis ? Redis.db : null;
this.webhook = new WebhookClient(XIAO_WEBHOOK_ID, XIAO_WEBHOOK_TOKEN, { disableMentions: 'everyone' });
this.timers = new TimerManager(this);
this.botList = new BotList(this);
this.patreon = new Patreon();
this.blacklist = { guild: [], user: [] };
this.patrons = null;
this.pokemon = new PokemonStore();
this.games = new Collection();
this.dispatchers = new Map();
this.cleverbots = new Map();
this.allowedUsers = [];
this.phone = new PhoneManager(this);
this.activities = activities;
this.leaveMessages = leaveMsgs;
@@ -77,111 +73,6 @@ module.exports = class XiaoClient extends CommandoClient {
moment.tz.link('America/New_York|Dragon');
}
async fetchPatrons() {
if (!PATREON_ACCESS_TOKEN || !PATREON_CAMPAIGN_ID) return null;
const { text } = await request
.get(`https://www.patreon.com/api/oauth2/v2/campaigns/${PATREON_CAMPAIGN_ID}/members`)
.set({ Authorization: `Bearer ${PATREON_ACCESS_TOKEN}` })
.query({
include: 'currently_entitled_tiers,user',
'fields[user]': 'social_connections',
'fields[member]': 'patron_status'
});
const body = JSON.parse(text);
const patrons = [];
for (const patron of body.data) {
if (patron.attributes.patron_status !== 'active_patron') continue;
const socials = body.included.find(user => user.id === patron.relationships.user.data.id)
?.attributes?.social_connections;
if (!socials || !socials.discord || !socials.discord.user_id) continue;
patrons.push(socials.discord.user_id);
}
this.patrons = patrons;
return patrons;
}
async postTopGGStats() {
if (!TOP_GG_TOKEN) return null;
try {
const { body } = await request
.post(`https://top.gg/api/bots/${this.user.id}/stats`)
.set({ Authorization: TOP_GG_TOKEN })
.send({ server_count: this.guilds.cache.size });
this.logger.info('[TOP.GG] Posted stats.');
return body;
} catch (err) {
this.logger.error(`[TOP.GG] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postBotsGGStats() {
if (!BOTS_GG_TOKEN) return null;
try {
const { body } = await request
.post(`https://discord.bots.gg/api/v1/bots/${this.user.id}/stats`)
.set({ Authorization: BOTS_GG_TOKEN })
.send({ guildCount: this.guilds.cache.size });
this.logger.info('[BOTS.GG] Posted stats.');
return body;
} catch (err) {
this.logger.error(`[BOTS.GG] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postDiscordBotListStats() {
if (!DISCORDBOTLIST_TOKEN) return null;
try {
const { body } = await request
.post(`https://discordbotlist.com/api/v1/bots/${this.user.id}/stats`)
.set({ Authorization: DISCORDBOTLIST_TOKEN })
.send({
guilds: this.guilds.cache.size,
users: this.users.cache.size,
voice_connections: this.dispatchers.size
});
this.logger.info('[DISCORDBOTLIST] Posted stats.');
return body;
} catch (err) {
this.logger.error(`[DISCORDBOTLIST] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postCarbonStats() {
if (!CARBON_TOKEN) return null;
try {
const { body } = await request
.post('https://www.carbonitex.net/discord/data/botdata.php')
.send({
key: CARBON_TOKEN,
servercount: this.guilds.cache.size,
botid: this.user.id
});
this.logger.info('[CARBON] Posted stats.');
return body;
} catch (err) {
this.logger.error(`[CARBON] Failed to post stats:\n${err.stack}`);
return err;
}
}
async postBlistStats() {
if (!BLIST_TOKEN) return null;
try {
const { body } = await request
.patch(`https://blist.xyz/api/v2/bot/${this.user.id}/stats/`)
.set({ Authorization: BLIST_TOKEN })
.send({ server_count: this.guilds.cache.size });
this.logger.info('[BLIST] Posted stats.');
return body;
} catch (err) {
this.logger.error(`[BLIST] Failed to post stats:\n${err.stack}`);
return err;
}
}
importBlacklist() {
const read = fs.readFileSync(path.join(__dirname, '..', 'blacklist.json'), { encoding: 'utf8' });
const file = JSON.parse(read);
@@ -221,32 +112,6 @@ module.exports = class XiaoClient extends CommandoClient {
return buf;
}
importCleverbotAllowed() {
const read = fs.readFileSync(path.join(__dirname, '..', 'cleverbot.json'), { encoding: 'utf8' });
const file = JSON.parse(read);
if (!Array.isArray(file)) return null;
for (const id of file) {
if (typeof id !== 'string') continue;
if (this.allowedUsers.includes(id)) continue;
this.allowedUsers.push(id);
}
return file;
}
exportCleverbotAllowed() {
let text = '[\n ';
if (this.allowedUsers.length) {
for (const id of this.allowedUsers) {
text += `"${id}",\n `;
}
text = text.slice(0, -3);
}
text += '\n]\n';
const buf = Buffer.from(text);
fs.writeFileSync(path.join(__dirname, '..', 'cleverbot.json'), buf, { encoding: 'utf8' });
return buf;
}
importCommandLeaderboard(add = false) {
const read = fs.readFileSync(path.join(__dirname, '..', 'command-leaderboard.json'), {
encoding: 'utf8'
+65
View File
@@ -0,0 +1,65 @@
const request = require('node-superfetch');
const fs = require('fs');
const { PATREON_ACCESS_TOKEN, PATREON_CAMPAIGN_ID } = process.env;
module.exports = class Patreon {
constructor(accessToken, campaignID) {
this.patrons = [];
this.forced = [];
this.accessToken = accessToken || PATREON_ACCESS_TOKEN;
this.campignID = campaignID || PATREON_CAMPAIGN_ID;
}
isPatron(id) {
return this.patrons.includes(id) || this.forced.includes(id);
}
async fetchPatrons() {
if (!this.accessToken || !this.campignID) return null;
const { text } = await request
.get(`https://www.patreon.com/api/oauth2/v2/campaigns/${PATREON_CAMPAIGN_ID}/members`)
.set({ Authorization: `Bearer ${PATREON_ACCESS_TOKEN}` })
.query({
include: 'currently_entitled_tiers,user',
'fields[user]': 'social_connections',
'fields[member]': 'patron_status'
});
const body = JSON.parse(text);
const patrons = [];
for (const patron of body.data) {
if (patron.attributes.patron_status !== 'active_patron') continue;
const socials = body.included.find(user => user.id === patron.relationships.user.data.id)
?.attributes?.social_connections;
if (!socials || !socials.discord || !socials.discord.user_id) continue;
patrons.push(socials.discord.user_id);
}
this.patrons = patrons;
return this.patrons;
}
importForced() {
const read = fs.readFileSync(path.join(__dirname, '..', 'patreon.json'), { encoding: 'utf8' });
const file = JSON.parse(read);
if (!Array.isArray(file)) return null;
for (const id of file) {
if (typeof id !== 'string') continue;
if (this.forced.includes(id)) continue;
this.forced.push(id);
}
return file;
}
exportForced() {
let text = '[\n ';
if (this.forced.length) {
for (const id of this.forced) {
text += `"${id}",\n `;
}
text = text.slice(0, -3);
}
text += '\n]\n';
const buf = Buffer.from(text);
fs.writeFileSync(path.join(__dirname, '..', 'patreon.json'), buf, { encoding: 'utf8' });
return buf;
}
};