forked from syntaxbullet/AuroraBot-discord
refactor: rename bot client, environment variables, and project name from Kyoko to Aurora.
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
DB_USER=kyoko
|
||||
DB_PASSWORD=kyoko
|
||||
DB_NAME=kyoko
|
||||
DB_USER=aurora
|
||||
DB_PASSWORD=aurora
|
||||
DB_NAME=aurora
|
||||
DB_PORT=5432
|
||||
DB_HOST=db
|
||||
DISCORD_BOT_TOKEN=your-discord-bot-token
|
||||
DISCORD_CLIENT_ID=your-discord-client-id
|
||||
DISCORD_GUILD_ID=your-discord-guild-id
|
||||
DATABASE_URL=postgres://kyoko:kyoko@db:5432/kyoko
|
||||
DATABASE_URL=postgres://aurora:aurora@db:5432/aurora
|
||||
|
||||
VPS_USER=your-vps-user
|
||||
VPS_HOST=your-vps-ip
|
||||
|
||||
43
README.md
43
README.md
@@ -1,42 +1 @@
|
||||
# Kyoko - Discord Rpg
|
||||
|
||||
A Discord bot built with [Bun](https://bun.sh), [Discord.js](https://discord.js.org/), and [Drizzle ORM](https://orm.drizzle.team/).
|
||||
|
||||
## Architecture
|
||||
|
||||
This project uses a modular architecture:
|
||||
|
||||
- **`src/index.ts`**: Entry point. initializes the client.
|
||||
- **`src/lib/KyokoClient.ts`**: Custom Discord Client wrapper handling command loading and events.
|
||||
- **`src/lib/env.ts`**: **Centralized Environment Configuration**. Validates environment variables using `zod` at startup.
|
||||
- **`src/lib/DrizzleClient.ts`**: Database client instance.
|
||||
- **`src/commands/`**: Command files.
|
||||
- **`src/db/`**: Database schema and migrations.
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Install Dependencies**:
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
2. **Environment Variables**:
|
||||
Copy `.env.example` to `.env` (create one if it doesn't exist) and fill in the required values:
|
||||
```env
|
||||
DISCORD_BOT_TOKEN=your_token_here
|
||||
DISCORD_CLIENT_ID=your_client_id
|
||||
DISCORD_GUILD_ID=your_guild_id_optional
|
||||
DATABASE_URL=postgres://user:pass@localhost:5432/db_name
|
||||
```
|
||||
*Note: The app will fail to start if `DISCORD_BOT_TOKEN` or `DATABASE_URL` are missing or invalid.*
|
||||
|
||||
3. **Run Development**:
|
||||
```bash
|
||||
bun run dev
|
||||
```
|
||||
|
||||
4. **Database Migrations**:
|
||||
```bash
|
||||
bun run db:push # Apply schema changes
|
||||
bun run generate # Generate migrations
|
||||
```
|
||||
# Aurora
|
||||
@@ -13,7 +13,7 @@ services:
|
||||
- ./src/db/log:/var/log/postgresql
|
||||
app:
|
||||
container_name: aurora_app
|
||||
image: kyoko-app
|
||||
image: aurora-app
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
@@ -39,7 +39,7 @@ services:
|
||||
|
||||
studio:
|
||||
container_name: aurora_studio
|
||||
image: kyoko-app
|
||||
image: aurora-app
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createCommand } from "@/lib/utils";
|
||||
import { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, MessageFlags } from "discord.js";
|
||||
import { configManager } from "@/lib/configManager";
|
||||
import { config, reloadConfig } from "@/lib/config";
|
||||
import { KyokoClient } from "@/lib/BotClient"; // Import directly from lib, avoiding circular dep with index
|
||||
import { AuroraClient } from "@/lib/BotClient";
|
||||
|
||||
export const features = createCommand({
|
||||
data: new SlashCommandBuilder()
|
||||
@@ -31,7 +31,7 @@ export const features = createCommand({
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
|
||||
if (subcommand === "list") {
|
||||
const activeCommands = KyokoClient.commands;
|
||||
const activeCommands = AuroraClient.commands;
|
||||
const categories = new Map<string, string[]>();
|
||||
|
||||
// Group active commands
|
||||
@@ -87,8 +87,8 @@ export const features = createCommand({
|
||||
// Reload config from disk (which was updated by configManager)
|
||||
reloadConfig();
|
||||
|
||||
await KyokoClient.loadCommands(true);
|
||||
await KyokoClient.deployCommands();
|
||||
await AuroraClient.loadCommands(true);
|
||||
await AuroraClient.deployCommands();
|
||||
|
||||
await interaction.editReply({ content: `✅ Command **${commandName}** has been ${enabled ? "enabled" : "disabled"}. Commands reloaded!` });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createCommand } from "@lib/utils";
|
||||
import { KyokoClient } from "@/lib/BotClient";
|
||||
import { AuroraClient } from "@/lib/BotClient";
|
||||
import { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, MessageFlags } from "discord.js";
|
||||
import { createErrorEmbed, createSuccessEmbed, createWarningEmbed } from "@lib/embeds";
|
||||
|
||||
@@ -13,14 +13,14 @@ export const refresh = createCommand({
|
||||
|
||||
try {
|
||||
const start = Date.now();
|
||||
await KyokoClient.loadCommands(true);
|
||||
await AuroraClient.loadCommands(true);
|
||||
const duration = Date.now() - start;
|
||||
|
||||
// Deploy commands
|
||||
await KyokoClient.deployCommands();
|
||||
await AuroraClient.deployCommands();
|
||||
|
||||
const embed = createSuccessEmbed(
|
||||
`Successfully reloaded ${KyokoClient.commands.size} commands in ${duration}ms.`,
|
||||
`Successfully reloaded ${AuroraClient.commands.size} commands in ${duration}ms.`,
|
||||
"System Refreshed"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Events, MessageFlags } from "discord.js";
|
||||
import { KyokoClient } from "@/lib/BotClient";
|
||||
import { AuroraClient } from "@/lib/BotClient";
|
||||
import { userService } from "@/modules/user/user.service";
|
||||
import { createErrorEmbed } from "@lib/embeds";
|
||||
import type { Event } from "@lib/types";
|
||||
@@ -32,7 +32,7 @@ const event: Event<Events.InteractionCreate> = {
|
||||
}
|
||||
|
||||
if (interaction.isAutocomplete()) {
|
||||
const command = KyokoClient.commands.get(interaction.commandName);
|
||||
const command = AuroraClient.commands.get(interaction.commandName);
|
||||
if (!command || !command.autocomplete) return;
|
||||
try {
|
||||
await command.autocomplete(interaction);
|
||||
@@ -44,7 +44,7 @@ const event: Event<Events.InteractionCreate> = {
|
||||
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
const command = KyokoClient.commands.get(interaction.commandName);
|
||||
const command = AuroraClient.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||
|
||||
10
src/index.ts
10
src/index.ts
@@ -1,14 +1,14 @@
|
||||
import { KyokoClient } from "@/lib/BotClient";
|
||||
import { AuroraClient } from "@/lib/BotClient";
|
||||
import { env } from "@lib/env";
|
||||
|
||||
// Load commands & events
|
||||
await KyokoClient.loadCommands();
|
||||
await KyokoClient.loadEvents();
|
||||
await KyokoClient.deployCommands();
|
||||
await AuroraClient.loadCommands();
|
||||
await AuroraClient.loadEvents();
|
||||
await AuroraClient.deployCommands();
|
||||
|
||||
|
||||
// login with the token from .env
|
||||
if (!env.DISCORD_BOT_TOKEN) {
|
||||
throw new Error("❌ DISCORD_BOT_TOKEN is not set in environment variables.");
|
||||
}
|
||||
KyokoClient.login(env.DISCORD_BOT_TOKEN);
|
||||
AuroraClient.login(env.DISCORD_BOT_TOKEN);
|
||||
@@ -185,4 +185,4 @@ class Client extends DiscordClient {
|
||||
}
|
||||
}
|
||||
|
||||
export const KyokoClient = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers] });
|
||||
export const AuroraClient = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers] });
|
||||
@@ -1,6 +1,6 @@
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { KyokoClient } from '@/lib/BotClient';
|
||||
import { AuroraClient } from '@/lib/BotClient';
|
||||
|
||||
const configPath = join(process.cwd(), 'src', 'config', 'config.json');
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { userTimers } from "@/db/schema";
|
||||
import { eq, and, lt } from "drizzle-orm";
|
||||
import { DrizzleClient } from "@/lib/DrizzleClient";
|
||||
import { KyokoClient } from "@/lib/BotClient";
|
||||
import { AuroraClient } from "@/lib/BotClient";
|
||||
import { env } from "@/lib/env";
|
||||
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ export const schedulerService = {
|
||||
|
||||
if (guildId) {
|
||||
// We try to fetch, if bot is not in guild or lacks perms, it will catch
|
||||
const guild = await KyokoClient.guilds.fetch(guildId);
|
||||
const guild = await AuroraClient.guilds.fetch(guildId);
|
||||
const member = await guild.members.fetch(userIdStr);
|
||||
await member.roles.remove(roleId);
|
||||
console.log(`👋 Removed temporary role ${roleId} from ${member.user.tag}`);
|
||||
|
||||
Reference in New Issue
Block a user