essa.jpeg
This commit is contained in:
@@ -2,5 +2,8 @@
|
||||
"api": {
|
||||
"fallbackPort": 2020,
|
||||
"memberCountGuildId": "447075692664979466"
|
||||
},
|
||||
"dsc": {
|
||||
"slashCmdTestGuildId": "860916258282012692"
|
||||
}
|
||||
}
|
||||
|
||||
9
src/commands/ping.ts
Normal file
9
src/commands/ping.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Command } from '../structures/Command';
|
||||
|
||||
export default new Command({
|
||||
name: 'ping',
|
||||
description: 'pongs back!',
|
||||
run: async ({ interaction }) => {
|
||||
interaction.followUp('pong');
|
||||
},
|
||||
});
|
||||
9
src/commands/pomoc.ts
Normal file
9
src/commands/pomoc.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Command } from '../structures/Command';
|
||||
|
||||
export default new Command({
|
||||
name: 'pomoc',
|
||||
description: 'pokazuje pomocne informacje',
|
||||
run: async ({ interaction }) => {
|
||||
interaction.followUp('tu będzie komenda z pomocami!');
|
||||
},
|
||||
});
|
||||
6
src/events/guildMemberAdd.ts
Normal file
6
src/events/guildMemberAdd.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Event } from '../structures/Event';
|
||||
import { members } from '..';
|
||||
|
||||
export default new Event('guildMemberAdd', () => {
|
||||
members.incrementCurrent();
|
||||
});
|
||||
6
src/events/guildMemberRemove.ts
Normal file
6
src/events/guildMemberRemove.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Event } from '../structures/Event';
|
||||
import { members } from '..';
|
||||
|
||||
export default new Event('guildMemberRemove', () => {
|
||||
members.decrementCurrent();
|
||||
});
|
||||
18
src/events/interactionCreate.ts
Normal file
18
src/events/interactionCreate.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { CommandInteractionOptionResolver } from 'discord.js';
|
||||
import { client } from '..';
|
||||
import { Event } from '../structures/Event';
|
||||
import { BotInteraction } from '../typings/Command';
|
||||
|
||||
export default new Event('interactionCreate', async (interaction) => {
|
||||
if (interaction.isCommand()) {
|
||||
await interaction.deferReply();
|
||||
const command = client.commands.get(interaction.commandName);
|
||||
if (!command)
|
||||
return interaction.followUp("This command doesn't exist. Dork.");
|
||||
command.run({
|
||||
args: interaction.options as CommandInteractionOptionResolver,
|
||||
client,
|
||||
interaction: interaction as BotInteraction,
|
||||
});
|
||||
}
|
||||
});
|
||||
23
src/events/ready.ts
Normal file
23
src/events/ready.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { client, config, members } from '..';
|
||||
import { Event } from '../structures/Event';
|
||||
|
||||
export default new Event('ready', () => {
|
||||
console.log(`BOT: Now logged in as ${client.user?.tag}.`);
|
||||
|
||||
// memberCount reporting - for the API
|
||||
// ---------------------------------------
|
||||
// NOTE: for this to work, bot needs to be
|
||||
// member of Gractwo Main Discord Server
|
||||
members.setCurrent(
|
||||
client.guilds.resolve(config.api.memberCountGuildId)?.memberCount || null
|
||||
);
|
||||
let intervalSeconds = 5;
|
||||
setInterval(() => {
|
||||
if (members.previous != members.current) {
|
||||
console.log(
|
||||
`API/BOT: Gractwo memberCount is ${`now ${members.current}` || 'unset'}`
|
||||
);
|
||||
}
|
||||
members.setPrevious(members.current);
|
||||
}, intervalSeconds * 1000);
|
||||
});
|
||||
48
src/index.ts
48
src/index.ts
@@ -1,50 +1,26 @@
|
||||
import DiscordJS from 'discord.js';
|
||||
// import fs from 'fs';
|
||||
import { BotClient } from './structures/Client';
|
||||
import { MemberCount } from './structures/MemberCount';
|
||||
import express from 'express';
|
||||
import dotenv from 'dotenv';
|
||||
import config from './cfg.json';
|
||||
dotenv.config();
|
||||
require('dotenv').config();
|
||||
|
||||
const client = new BotClient();
|
||||
client.boot();
|
||||
|
||||
const client = new DiscordJS.Client({
|
||||
intents: [
|
||||
DiscordJS.GatewayIntentBits.Guilds,
|
||||
DiscordJS.GatewayIntentBits.GuildMembers,
|
||||
],
|
||||
});
|
||||
const app = express();
|
||||
const port = process.env.PORT || config.api.fallbackPort;
|
||||
let memberCount: number | null, previousCount: number | null;
|
||||
const members = new MemberCount();
|
||||
let port = process.env.PORT || config.api.fallbackPort;
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendStatus(200);
|
||||
});
|
||||
app.get('/members', (req, res) => {
|
||||
res
|
||||
.status(memberCount ? 200 : 500)
|
||||
.send(memberCount ? memberCount.toString() : 'Server Error');
|
||||
.status(members.current ? 200 : 500)
|
||||
.send(members.current ? members.current.toString() : 'Server Error');
|
||||
});
|
||||
|
||||
client.on('guildMemberAdd', () => {
|
||||
if (memberCount) memberCount++;
|
||||
});
|
||||
client.on('guildMemberRemove', () => {
|
||||
if (memberCount) memberCount--;
|
||||
});
|
||||
client.on('ready', () => {
|
||||
console.log(`BOT: Now logged in as ${client.user?.tag}.`);
|
||||
memberCount =
|
||||
client.guilds.resolve(config.api.memberCountGuildId)?.memberCount || null;
|
||||
setInterval(() => {
|
||||
if (previousCount != memberCount) {
|
||||
console.log(
|
||||
`API/BOT: Gractwo memberCount is ${`now ${memberCount}` || 'unset'}.`
|
||||
);
|
||||
}
|
||||
previousCount = memberCount;
|
||||
}, 5 * 1000);
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`API: Now listening on :${port}.`);
|
||||
});
|
||||
client.login(process.env.TOKEN);
|
||||
|
||||
export { client, app, config, members };
|
||||
|
||||
84
src/structures/Client.ts
Normal file
84
src/structures/Client.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import {
|
||||
ApplicationCommandDataResolvable,
|
||||
Client,
|
||||
ClientEvents,
|
||||
Collection,
|
||||
GatewayIntentBits,
|
||||
} from 'discord.js';
|
||||
import { CommandType } from '../typings/Command';
|
||||
import glob from 'glob';
|
||||
import { promisify } from 'util';
|
||||
import { RegisterCommandsOptions } from '../typings/Client';
|
||||
import { Event } from './Event';
|
||||
import config from '../cfg.json';
|
||||
|
||||
// makes file search lib a promise
|
||||
const globPromise = promisify(glob);
|
||||
|
||||
class BotClient extends Client {
|
||||
commands: Collection<string, CommandType> = new Collection();
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
intents: 32767, // all intents!
|
||||
});
|
||||
}
|
||||
|
||||
boot() {
|
||||
this.registerModules();
|
||||
this.login(
|
||||
// if prod, use main bot token
|
||||
process.env.ENVIRONMENT == 'prod'
|
||||
? process.env.TOKEN
|
||||
: process.env.DEVTOKEN
|
||||
);
|
||||
}
|
||||
|
||||
async importFile(filePath: string) {
|
||||
return (await import(filePath))?.default;
|
||||
}
|
||||
|
||||
async registerCommands({ commands, guildId }: RegisterCommandsOptions) {
|
||||
if (guildId) {
|
||||
// register in guild
|
||||
this.guilds.cache.get(guildId)?.commands.set(commands);
|
||||
} else {
|
||||
// register globally
|
||||
this.application?.commands.set(commands);
|
||||
}
|
||||
}
|
||||
|
||||
async registerModules() {
|
||||
const slashCommands: ApplicationCommandDataResolvable[] = [];
|
||||
const commandFiles = await globPromise(
|
||||
`${__dirname}/../commands/*{.ts,.,js}`
|
||||
);
|
||||
commandFiles.forEach(async (filePath) => {
|
||||
const command: CommandType = await this.importFile(filePath);
|
||||
if (!command.name) return;
|
||||
this.commands.set(command.name, command);
|
||||
slashCommands.push(command);
|
||||
});
|
||||
|
||||
this.on('ready', () => {
|
||||
this.registerCommands({
|
||||
commands: slashCommands,
|
||||
guildId: config.dsc.slashCmdTestGuildId,
|
||||
});
|
||||
// if prod, register global commands
|
||||
if (process.env.ENVIRONMENT == 'prod') {
|
||||
this.registerCommands({
|
||||
commands: slashCommands,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const eventFiles = await globPromise(`${__dirname}/../events/*{.ts,.js}`);
|
||||
eventFiles.forEach(async (filePath) => {
|
||||
const event: Event<keyof ClientEvents> = await this.importFile(filePath);
|
||||
this.on(event.event, event.run);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { BotClient };
|
||||
9
src/structures/Command.ts
Normal file
9
src/structures/Command.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { CommandType } from '../typings/Command';
|
||||
|
||||
class Command {
|
||||
constructor(commandOptions: CommandType) {
|
||||
Object.assign(this, commandOptions);
|
||||
}
|
||||
}
|
||||
|
||||
export { Command };
|
||||
10
src/structures/Event.ts
Normal file
10
src/structures/Event.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ClientEvents } from 'discord.js';
|
||||
|
||||
class Event<Key extends keyof ClientEvents> {
|
||||
constructor(
|
||||
public event: Key,
|
||||
public run: (...args: ClientEvents[Key]) => any
|
||||
) {}
|
||||
}
|
||||
|
||||
export { Event };
|
||||
22
src/structures/MemberCount.ts
Normal file
22
src/structures/MemberCount.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
class MemberCount {
|
||||
current: number | null = null;
|
||||
previous: number | null = null;
|
||||
// "previous" is only used for reporting checks
|
||||
// inside the ready.ts event
|
||||
|
||||
incrementCurrent() {
|
||||
if (this.current) this.current++;
|
||||
}
|
||||
decrementCurrent() {
|
||||
if (this.current) this.current--;
|
||||
}
|
||||
setCurrent(input: number | null) {
|
||||
this.current = input;
|
||||
}
|
||||
|
||||
setPrevious(input: number | null) {
|
||||
this.previous = input;
|
||||
}
|
||||
}
|
||||
|
||||
export { MemberCount };
|
||||
7
src/typings/Client.ts
Normal file
7
src/typings/Client.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ApplicationCommandDataResolvable } from 'discord.js';
|
||||
|
||||
interface RegisterCommandsOptions {
|
||||
guildId?: string;
|
||||
commands: ApplicationCommandDataResolvable[];
|
||||
}
|
||||
export { RegisterCommandsOptions };
|
||||
27
src/typings/Command.ts
Normal file
27
src/typings/Command.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import {
|
||||
ChatInputApplicationCommandData,
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
GuildMember,
|
||||
PermissionResolvable,
|
||||
} from 'discord.js';
|
||||
import { BotClient } from '../structures/Client';
|
||||
|
||||
interface BotInteraction extends CommandInteraction {
|
||||
member: GuildMember;
|
||||
}
|
||||
|
||||
interface RunOptions {
|
||||
client: BotClient;
|
||||
interaction: BotInteraction;
|
||||
args: CommandInteractionOptionResolver;
|
||||
}
|
||||
|
||||
type RunFunction = (options: RunOptions) => any;
|
||||
|
||||
type CommandType = {
|
||||
userPermissions?: PermissionResolvable[];
|
||||
run: RunFunction;
|
||||
} & ChatInputApplicationCommandData;
|
||||
|
||||
export { CommandType, BotInteraction };
|
||||
Reference in New Issue
Block a user