# API Integration

### ✨ Features

* **Event-driven architecture** — React to Discord and bot events
* **Backward compatibility** — Legacy addons still work
* **Priority system** — Control execution order of handlers
* **Error isolation** — One addon's error won't crash others
* **Rich context** — Access client, config, and language data
* **Async support** — Full `Promise` / `async-await` support

***

### 🚀 Quick Start

#### Example: HelloWorld Addon

A simple addon that responds to messages, welcomes new members, and reacts to tickets being created:

{% code expandable="true" %}

```javascript
module.exports = {
    // Only 'name' is required!
    name: 'HelloWorld',
    
    // Everything else is optional (but recommended for clarity)
    // version: '1.0.0'
    // description: '...'
    // author: 'Your Name'
    
    events: {
        // Respond to messages
        'discord:messageCreate': async (eventData, context) => {
            const { message } = eventData;
            if (message.author.bot) return;
            
            if (message.content.toLowerCase() === '!hello') {
                await message.channel.send(`Hello ${message.author.username}! 👋`);
            }
        },
        
        // Welcome new members
        'discord:guildMemberAdd': async (eventData, context) => {
            const { member } = eventData;
            console.log(`New member joined: ${member.user.username}`);
            
            const channel = member.guild.channels.cache.find(
                ch => ch.name === 'welcome' || ch.name === 'general'
            );
            if (channel) {
                await channel.send(`Welcome ${member.user.username}! 🎉`);
            }
        },
        
        // React to tickets being created
        'ticket:created': async (eventData, context) => {
            const { ticket, user } = eventData;
            console.log(`Ticket #${ticket.ticketId} was created by ${user.username}`);
        }
    }
};
```

{% endcode %}

#### ✅ With this addon

* Type `!hello` → Bot replies with a greeting
* New members join → Welcome message in **#welcome** or **#general**
* Ticket is created → Logged in console

***

### 📡 Event Reference

#### Discord Events

Listen to Discord.js events with the `discord:` prefix:

| Event                       | What It Does                | Key Data                 |
| --------------------------- | --------------------------- | ------------------------ |
| `discord:messageCreate`     | New message sent            | `message`                |
| `discord:messageUpdate`     | Message edited              | `message`, `oldMessage`  |
| `discord:messageDelete`     | Message deleted             | `message`                |
| `discord:guildMemberAdd`    | User joins server           | `member`                 |
| `discord:guildMemberRemove` | User leaves server          | `member`                 |
| `discord:guildMemberUpdate` | User roles/nickname changed | `oldMember`, `newMember` |
| `discord:voiceStateUpdate`  | Voice channel changes       | `oldState`, `newState`   |
| `discord:channelCreate`     | Channel created             | `channel`                |
| `discord:channelDelete`     | Channel deleted             | `channel`                |
| `discord:roleCreate`        | Role created                | `role`                   |
| `discord:roleDelete`        | Role deleted                | `role`                   |
| `discord:guildBanAdd`       | User banned                 | `ban`                    |
| `discord:guildBanRemove`    | User unbanned               | `ban`                    |
| `discord:interactionCreate` | Slash command/button used   | `interaction`            |
| `discord:ready`             | Bot started                 | `client`                 |

#### Bot Business Logic Events

**Ticket Events**

| Event              | What It Does                 | Key Data                                           |
| ------------------ | ---------------------------- | -------------------------------------------------- |
| `ticket:created`   | New ticket opened            | `ticket`, `user`, `ticketType`, `questions`        |
| `ticket:closed`    | Ticket closed/resolved       | `ticket`, `closedBy`, `closeReason`, `isAutoAlert` |
| `ticket:deleted`   | Ticket channel deleted       | `ticket`, `deletedBy`, `channelName`               |
| `ticket:claimed`   | Staff member claims ticket   | `ticket`, `claimer`                                |
| `ticket:unclaimed` | Staff member unclaims ticket | `ticket`, `previousClaimer`                        |
| `ticket:reviewed`  | User reviews service         | `ticket`, `rating`, `feedback`, `reviewer`         |

**Suggestion Events**

| Event                 | What It Does                 | Key Data                                               |
| --------------------- | ---------------------------- | ------------------------------------------------------ |
| `suggestion:created`  | New suggestion submitted     | `suggestion`, `author`, `text`, `message`              |
| `suggestion:accepted` | Suggestion approved by staff | `suggestion`, `acceptedBy`, `reason`, `originalAuthor` |
| `suggestion:denied`   | Suggestion rejected by staff | `suggestion`, `deniedBy`, `reason`, `originalAuthor`   |

**Leveling Events**

| Event      | What It Does                | Key Data                                               |
| ---------- | --------------------------- | ------------------------------------------------------ |
| `level:up` | User gains XP and levels up | `user`, `newLevel`, `oldLevel`, `xpGained`, `userData` |

**Auto-Moderation Events**

| Event                    | What It Does                     | Key Data                                                |
| ------------------------ | -------------------------------- | ------------------------------------------------------- |
| `autoReact:triggered`    | Bot auto-reacts to keyword       | `message`, `keyword`, `emoji`, `reaction`               |
| `autoResponse:triggered` | Bot sends auto-response          | `message`, `trigger`, `responseType`, `responseContent` |
| `moderation:antiSpam`    | Anti-spam/mass mention triggered | `type`, `user`, `action`, `reason`, `duration`          |

**Music Events**

| Event              | What It Does         | Key Data                        |
| ------------------ | -------------------- | ------------------------------- |
| `music:trackStart` | Track starts playing | `track`, `requestedBy`, `queue` |
| `music:trackAdded` | Track added to queue | `track`, `requestedBy`, `queue` |

**Giveaway Events**

| Event              | What It Does                        | Key Data                                       |
| ------------------ | ----------------------------------- | ---------------------------------------------- |
| `giveaway:created` | New giveaway started                | `giveaway`, `prize`, `winnerCount`, `hostedBy` |
| `giveaway:ended`   | Giveaway finished, winners selected | `giveaway`, `winners`, `prize`, `totalEntries` |

**Invite Events**

| Event                 | What It Does                    | Key Data                                  |
| --------------------- | ------------------------------- | ----------------------------------------- |
| `invite:memberJoined` | Member joins via tracked invite | `member`, `inviter`, `inviterInviteCount` |

**Moderation Events (Slash Commands)**

| `moderation:ban`             | A user is banned via slash command or audit log | `type`, `target`, `moderator`, `reason`, `guild`, `dmSent`, `method`                                       |
| ---------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `moderation:unban`           | A previously banned user is unbanned            | `type`, `targetUserId`, `moderator`, `reason`, `guild`, `method`                                           |
| `moderation:kick`            | A member is removed from the server             | `type`, `target`, `moderator`, `reason`, `guild`, `dmSent`, `method`                                       |
| `moderation:warn`            | A moderator issues a warning                    | `type`, `target`, `moderator`, `reason`, `guild`, `warningCount`, `warning`, `method`                      |
| `moderation:unwarn`          | A warning is removed from a user                | `type`, `target`, `moderator`, `removedWarning`, `warningId`, `guild`, `remainingWarnings`, `method`       |
| `moderation:timeout`         | A user is muted/timed out                       | `type`, `subType`, `target`, `moderator`, `reason`, `duration`, `durationMs`, `endTime`, `guild`, `method` |
| `moderation:timeout_clear`   | Timeout or mute is lifted                       | `type`, `target`, `moderator`, `guild`, `wasMuted`, `method`                                               |
| `moderation:tempban`         | A moderator applies a timed ban                 | `type`, `target`, `moderator`, `reason`, `duration`, `endTime`, `guild`, `dmSent`, `method`                |
| `moderation:nickname_change` | A moderator edits a user’s nickname             | `type`, `target`, `moderator`, `oldNickname`, `newNickname`, `guild`, `method`                             |
| `moderation:purge`           | A moderator bulk deletes messages               | `type`, `moderator`, `channel`, `guild`, `messageCount`, `purgeType`, `originalAmount`, `method`           |

**Addon Lifecycle Events**

| Event              | What It Does                       | Key Data               |
| ------------------ | ---------------------------------- | ---------------------- |
| `addon:loaded`     | Addon loaded successfully          | `name`, `path`, `type` |
| `addon:unloaded`   | Addon unloaded                     | `name`, `path`         |
| `addon:registered` | Addon registered with event system | `name`, `events`       |

***

### 🔧 Custom Events

Emit and listen for your own events:

{% code expandable="true" %}

```javascript
// Emit
global.addonLoader.getEventManager().emitSafe('my-addon:custom-event', {
    data: 'some data',
    user,
    guild
});

// Listen
events: {
    'my-addon:custom-event': async (eventData, context) => {
        const { data, user, guild } = eventData;
        // Handle custom event
    }
}
```

{% endcode %}

***

### 🧰 Context Object

Every handler receives:

{% code expandable="true" %}

```javascript
{
    client: Client,       // Discord.js client
    config: Object,       // Bot config
    lang: Object,         // Language config
    eventName: String,    // Current event
    timestamp: Date,      // Emitted at
    guild: Guild|null,    // Guild if available
    user: User|null       // User if available
}
```

{% endcode %}

***

### ⚙️ Advanced Features

#### Priority System

Control execution order:

```javascript
module.exports = {
    name: 'HighPriority',
    priority: 100, // Higher runs first
    events: { /* ... */ }
};
```

#### Error Handling

Addons run independently:

{% code expandable="true" %}

```javascript
events: {
    'discord:messageCreate': async (eventData, context) => {
        try {
            // your logic
        } catch (err) {
            console.error('Error in my addon:', err);
            // Won't crash other addons
        }
    }
}
```

{% endcode %}

#### Database Integration

Use Mongoose inside addons:

{% code expandable="true" %}

```javascript
const mongoose = require('mongoose');

const mySchema = new mongoose.Schema({
    guildId: String,
    data: String
});

const MyModel = mongoose.model('MyData', mySchema);

// Use in events
await MyModel.findOneAndUpdate(
    { guildId: guild.id },
    { data: 'updated' },
    { upsert: true }
);
```

{% endcode %}

#### Conditional Event Handling

Run logic only in certain channels/users:

{% code expandable="true" %}

```javascript
'discord:messageCreate': async (eventData, context) => {
    const { message } = eventData;
    
    // Only in specific channels
    if (!['general', 'bot-commands'].includes(message.channel.name)) return;
    
    // Only non-bots
    if (message.author.bot) return;
    
    // Your logic here
}
```

{% endcode %}

***

### 🔄 Migration from Legacy Addons

#### Legacy Format (still works)

{% code expandable="true" %}

```javascript
module.exports = {
    run: async (client) => {
        client.on('messageCreate', async message => {
            if (message.content === '!hello') {
                await message.channel.send('Hello!');
            }
        });
    }
};
```

{% endcode %}

#### New Event API Format

{% code expandable="true" %}

```javascript
module.exports = {
    name: 'MyAddon',
    version: '1.0.0',
    events: {
        'discord:messageCreate': async (eventData, context) => {
            const { message } = eventData;
            if (message.content === '!hello') {
                await message.channel.send('Hello!');
            }
        }
    },
    
    // Optional: Keep initialization logic
    run: async (client, eventManager) => {
        console.log('Addon initialized!');
    }
};
```

{% endcode %}

#### Key Differences

* **Legacy** → `run` function, no `name` property
* **New** → `name` required, uses `events`
* **New format benefits:** event-driven API, hot reloading, enable/disable, error isolation, priorities

***

### 📋 Requirements Summary

#### Absolutely Required

* `name` (string) — Unique addon identifier

#### Required (pick one)

* `events` (object) — Event handlers
* `run` (function) — Init function

#### Optional (defaults)

* `version` → `'1.0.0'`
* `description` → `''`
* `author` → `'Unknown'`
* `priority` → `0`
* `permissions` → `[]`
* `dependencies` → `[]`

#### Minimal Working Addon

```javascript
module.exports = {
    name: 'Minimal',
    events: {
        'discord:messageCreate': async (eventData, context) => {
            // Your code here
        }
    }
};
```

***

### 💡 Practical Examples

#### Staff Notification System

{% code expandable="true" %}

```javascript
module.exports = {
    name: 'StaffNotifications',
    events: {
        'ticket:created': async ({ ticket, user, ticketType }) => {
            const staffChannel = ticket.guild.channels.cache.find(ch => ch.name === 'staff-alerts');
            if (staffChannel) {
                await staffChannel.send(`🎫 New ${ticketType.Name} ticket #${ticket.ticketId} by ${user.username}`);
            }
        },
        
        'suggestion:created': async ({ suggestion, author, text }) => {
            const staffChannel = suggestion.guild.channels.cache.find(ch => ch.name === 'suggestions');
            if (staffChannel) {
                const message = await staffChannel.send(`💡 New suggestion: "${text}" by ${author.username}`);
                await message.react('👍');
                await message.react('👎');
            }
        }
    }
};
```

{% endcode %}

#### Level Rewards System

{% code expandable="true" %}

```javascript
module.exports = {
    name: 'LevelRewards',
    events: {
        'level:up': async ({ user, newLevel, guild }) => {
            const member = guild.members.cache.get(user.id);
            
            // Milestone rewards
            if (newLevel === 10) {
                const role = guild.roles.cache.find(r => r.name === 'Active Member');
                if (role) await member.roles.add(role);
            }
            
            if (newLevel === 50) {
                const role = guild.roles.cache.find(r => r.name === 'Veteran');
                if (role) await member.roles.add(role);
            }
            
            // Celebrate big milestones
            if (newLevel % 25 === 0) {
                const channel = guild.channels.cache.find(ch => ch.name === 'general');
                if (channel) {
                    await channel.send(`🎉 ${user.username} reached level ${newLevel}! Amazing! 🎉`);
                }
            }
        }
    }
};
```

{% endcode %}

#### Auto-Moderation Logger

{% code expandable="true" %}

```javascript
module.exports = {
    name: 'ModLogger',
    events: {
        'moderation:antiSpam': async ({ type, user, action, reason, guild }) => {
            const logChannel = guild.channels.cache.find(ch => ch.name === 'mod-logs');
            if (logChannel) {
                await logChannel.send({
                    embeds: [{
                        title: '🛡️ Auto-Moderation',
                        description: `**User:** ${user.username}\n**Type:** ${type}\n**Action:** ${action}\n**Reason:** ${reason}`,
                        color: 0xff6b6b,
                        timestamp: new Date()
                    }]
                });
            }
        }
    }
};
```

{% endcode %}
