# 🚀 Discord Bot Library

A powerful, feature-rich **Discord bot framework** built with TypeScript. It provides a complete toolkit for modern bot development, making it easy to build, scale, and maintain production-ready bots.

## ✨ Key Features

- 🔧 **TypeScript First** – Full type safety, IntelliSense, and modern development practices.
- 🗃️ **VerseDB Integration** – Lightweight database system with support for JSON, YAML, and MongoDB.
- 📁 **Automatic Loading** – Seamless auto-registration of events and commands.
- 🔒 **Built-in Encryption** – AES-secured storage for sensitive data.
- 👀 **Hot Reloading** – File watcher for rapid development.
- 🛡️ **Crash Protection** – Automatic error handling and reporting.
- 🎨 **Advanced Logging** – Color-coded logs with timestamps and categories.
- 📦 **Flexible Package Manager Support** – Works with both Yarn and NPM.
- 📊 **Bot Analytics** – Integrated statistics and activity tracking.

## 📦 Installation

```bash
# With Yarn (recommended)

# 🆕 Project Initialization
yarn init                    # Initialize a new project
yarn add rashi-discord-bot-lib discord.js
yarn add -D typescript @types/node

# 📦 Package Management
yarn install                 # Install dependencies
yarn add package-name        # Add dependency
yarn add -D package-name     # Add dev dependency
yarn remove package-name     # Remove dependency
yarn upgrade                 # Update all packages

# 🔄 Development Workflow
yarn dev                     # 🔥 Run with hot reload
yarn build                   # 🏗️ Compile TypeScript
yarn start                   # ▶️ Run compiled code
yarn pack                    # 📦 Package library
```


### Development Scripts

Add these scripts to your `package.json`:

```json
{
  "scripts": {
    "dev": "tsx watch index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "pack": "npm pack"
  }
}
```

### Environment Setup

Create a `.env` file in your project root:

```env
BOT_TOKEN=your_discord_bot_token_here
MONGO_URI=mongodb://localhost:27017/your_database
CRASH_WEBHOOK=https://discord.com/api/webhooks/your_webhook_url
```

## 🚀 Getting Started

### Basic Bot Setup

Create your main `index.ts` file:

```ts
import 'dotenv/config';
import { BotStarter, type BotStarterOptions } from 'rashi-discord-bot-lib';
import { Client, GatewayIntentBits } from 'discord.js';
import path from 'path';
import fs from 'fs';

// --- Ensure environment ---
const token = process.env.BOT_TOKEN;
if (!token) {
  console.error('❌ Missing BOT_TOKEN in .env');
  process.exit(1);
}

// --- Prepare project folders ---
const root = process.cwd();
const dataDir = path.resolve(root, 'data');
const eventsDir = path.resolve(root, 'events');
const slashDir = path.resolve(root, 'commands', 'slash');
const prefixDir = path.resolve(root, 'commands', 'prefix');

for (const dir of [dataDir, eventsDir, slashDir, prefixDir]) {
  fs.mkdirSync(dir, { recursive: true });
}

// --- Create Client ---
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

const starter = new BotStarter();

// --- Configure Options ---
const options: BotStarterOptions = {
  bot: {
    token,
    logs: { terminal: true },
    Database: {
      verse: { adapterType: 'json', path: dataDir },
      mongo: { mongoURI: process.env.MONGO_URI!, dbName: 'bot' },
    },
  },
  events: {
    path: eventsDir,
    recursive: true,
  },
  commands: {
    slashPath: slashDir,
    prefixPath: prefixDir,
    prefix: '!',
  },
  // anticrash: { enable: true, webhookURL: process.env.CRASH_WEBHOOK!, mention: '<@123>' },
};

async function startBot() {
  try {
    const res = await starter.start(client, options);

    // Expose databases for easy access
    (client as any).db = res.db;
    (client as any).mongo = res.mongodb;

    // Example: Save startup timestamp
    await res.db.set('bot.startedAt', new Date().toISOString());
    console.log('✅ Bot started.');

    // Graceful shutdown
    const shutdown = async () => {
      console.log('🛑 Shutting down...');
      await starter.shutdown();
      process.exit(0);
    };
    process.on('SIGINT', shutdown);
    process.on('SIGTERM', shutdown);
  } catch (err) {
    console.error('❌ Failed to start bot:', err);
    process.exit(1);
  }
}

startBot();
```


## 📂 Project Structure

```
your-bot/
├── data/              # Database files (auto-generated)
├── events/            # Event handlers
│   ├── ready.ts
│   └── messageCreate.ts
├── commands/
│   ├── slash/         # Slash commands
│   │   ├── ping.ts
│   │   └── user.ts
│   └── prefix/        # Prefix commands
│       ├── help.ts
│       └── stats.ts
├── .env              # Environment variables
├── index.ts          # Main bot file
├── package.json      # Dependencies and scripts
└── tsconfig.json     # TypeScript configuration
```

## 🎯 Creating Commands

### Slash Commands

Create a slash command in `commands/slash/ping.ts`:

```typescript
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js';

export default {
  data: new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Replies with Pong!'),
  
  async execute(interaction: ChatInputCommandInteraction) {
    const ping = Date.now() - interaction.createdTimestamp;
    await interaction.reply(`🏓 Pong! Latency: ${ping}ms`);
  },
};
```

Advanced slash command with options (`commands/slash/user.ts`):

```typescript
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js';

export default {
  data: new SlashCommandBuilder()
    .setName('user')
    .setDescription('Get user information')
    .addUserOption(option =>
      option.setName('target')
        .setDescription('The user to get info about')
        .setRequired(true)),
  
  async execute(interaction: ChatInputCommandInteraction) {
    const user = interaction.options.getUser('target');
    const member = interaction.guild?.members.cache.get(user!.id);
    
    await interaction.reply({
      content: `👤 **${user!.tag}**\nJoined: ${member?.joinedAt?.toDateString()}`,
      ephemeral: true
    });
  },
};
```

### Prefix Commands

Create a prefix command in `commands/prefix/help.ts`:

```typescript
import { Message, EmbedBuilder } from 'discord.js';

export default {
  name: 'help',
  description: 'Display help information',
  aliases: ['h', 'commands'],
  usage: '[command]',
  
  async execute(message: Message, args: string[]) {
    const embed = new EmbedBuilder()
      .setTitle('📋 Bot Commands')
      .setDescription('Here are my available commands:')
      .addFields(
        { name: '!help', value: 'Show this help message', inline: true },
        { name: '!ping', value: 'Check bot latency', inline: true },
        { name: '!stats', value: 'Show bot statistics', inline: true }
      )
      .setColor(0x00AE86)
      .setTimestamp();

    await message.reply({ embeds: [embed] });
  },
};
```

## 📡 Event Handling

### Ready Event

Create `events/ready.ts`:

```typescript
import { Client } from 'discord.js';

export default {
  name: 'ready',
  once: true,
  execute(client: Client) {
    console.log(`🟢 ${client.user?.tag} is now online!`);
    console.log(`📊 Serving ${client.guilds.cache.size} guilds`);
    
    // Set bot activity
    client.user?.setActivity('with Discord.js', { type: 'PLAYING' });
  },
};
```




## 🗄️ Database Usage

### VerseDB (JSON/YAML)

```typescript
// In your commands or events
const client = interaction.client; // or message.client

// Set data
await client.db.set('user.123456789.coins', 100);
await client.db.set('guild.987654321.settings', { 
  prefix: '!', 
  welcomeChannel: '123456789',
  moderationLogs: true 
});

// Get data with default values
const coins = await client.db.get('user.123456789.coins') || 0;
const settings = await client.db.get('guild.987654321.settings') || {};

// Increment values
const currentCoins = await client.db.get('user.123456789.coins') || 0;
await client.db.set('user.123456789.coins', currentCoins + 50);

// Check if data exists
const hasProfile = await client.db.has('user.123456789.profile');

// Delete data
await client.db.delete('user.123456789.tempData');

// Get all data (be careful with large datasets)
const allData = await client.db.all();

// Advanced: Working with objects
const userData = await client.db.get('user.123456789') || {};
userData.lastSeen = new Date().toISOString();
userData.messageCount = (userData.messageCount || 0) + 1;
await client.db.set('user.123456789', userData);
```

### MongoDB (if configured)

```typescript
// Access MongoDB collections
const users = client.mongo.db.collection('users');
const guilds = client.mongo.db.collection('guilds');

// Create user profile
await users.insertOne({
  userId: '123456789',
  username: 'JohnDoe',
  coins: 100,
  joinedAt: new Date(),
  stats: {
    messagesCount: 0,
    commandsUsed: 0
  }
});

// Find user
const user = await users.findOne({ userId: '123456789' });

// Update user data
await users.updateOne(
  { userId: '123456789' },
  { 
    $inc: { coins: 50, 'stats.commandsUsed': 1 },
    $set: { lastActive: new Date() }
  }
);

// Find multiple users
const topUsers = await users.find({})
  .sort({ coins: -1 })
  .limit(10)
  .toArray();

// Aggregation example
const userStats = await users.aggregate([
  { $group: { _id: null, totalCoins: { $sum: '$coins' } } }
]).toArray();
```


## 🚨 Error Handling & Anti-crash

### Automatic Error Recovery

```typescript
const options: BotStarterOptions = {
  // ... other options
  anticrash: {
    enable: true,
    webhookURL: process.env.CRASH_WEBHOOK,
    mention: '<@YOUR_USER_ID>',
    logErrors: true
  }
};
```


## 📖 Documentation

- [Events System](docs/events.md) – Learn how to create and manage event listeners.
- [Command Handling](docs/commands.md) – Full guide on slash & prefix command setup.
- [Database Management](docs/database.md) – Using VerseDB and MongoDB integrations.
- [Crash Protection](docs/anticrash.md) – Handling unexpected runtime errors.

## 🛠️ Development Tools

- **Hot Reloading** – Automatically refresh commands/events on save.
- **Type Checking** – Strong TypeScript definitions throughout the library.
- **Logging System** – Debug, info, warning, and error levels with colors.
- **Extensible API** – Easily integrate third-party services or extend with custom modules.


## 🆘 Support & Community

- 🐛 **Issues**: [GitHub Issues](https://github.com/your-username/rashi-discord-bot-lib/issues)
- 💬 **Discord**: Join our community server
- 📧 **Email**: support@your-domain.com
- 📖 **Documentation**: Full docs coming soon



## 🎯 Roadmap

- [ ] 🌐 Web dashboard for bot management
- [ ] 🔌 Plugin system for extensions
- [ ] 🔐 Advanced permission system
- [ ] 🌍 Multi-language support
- [ ] 📊 Built-in analytics dashboard
- [ ] 🔄 Database migration tools
- [ ] 📱 Mobile companion app
- [ ] 🤖 AI-powered command suggestions

## 🤝 Contributing

Contributions are welcome! Please fork the repo, create a feature branch, and submit a PR. Make sure to follow TypeScript coding conventions and include tests where possible.

## 📜 License

MIT License © 2025 – Built with ❤️ for the Discord developer community.

