> For the complete documentation index, see [llms.txt](https://docs.iynxdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iynxdev.com/addon-api/getting-started/events.md).

# Events

This page explains how to create your own event listeners for your AthenaBot plugin.

***

## 1. Setting up the event file

1. Copy the event template.

```js
const event = require('../../../../main/discord/core/events/event.js');
const { Events } = require('discord.js');

module.exports = class startUp extends event {
  constructor(heart) {
    super(heart, { name: 'startUp', event: { discord: Events.ClientReady, bypassManager: false, dm: false, bypassRestrictions: true, permissionLevel: null } });
  }

  execute(client) {
    this.heart.core.console.log(this.heart.core.console.type.log, 'The bot is ready now :)');
  }
};
```

2. Create a new event file inside your `/plugins/<plugin_name>/src/events/` directory.
3. The name of the file must follow the format `<event_name>.js`. Please note that in this case the event name does not match the Discord event. Try to use a unique event name.

### Parameters

* **name:** A unique identifier for the event.
* **discord:** The corresponding `discord.js` event name.
* **bypassManager:** Avoid setting this to `true` unless you are certain of the consequences.
* **dm:** Applicable only for `Discord.interactionCreate` events. Determines whether the interaction should also fire in DMs.
* **bypassRestrictions:** Must remain `true`.
* **permissionLevel:** Applicable only for `Discord.interactionCreate` events. This works like the permission configuration. Set to `null` to allow everyone.

> For custom events, the important value is `event.discord`. It must exactly match the emitted event name.

***

## 2. Event response

It is important to note that each event comes with its own parameters, which you receive in the method header. A full list of available events and their return values can be found in the Discord.js documentation.

### Interaction events

To begin, let’s look at a code snippet that creates a button.

```js
const button = new ActionRowBuilder().addComponents(
  new ButtonBuilder()
    .setCustomId(`iynx:athenabot:testButton:${interaction.user.id}:${Date.now()}`)
    .setLabel('Send')
    .setEmoji(this.heart.core.discord.core.emoji.manager.getEmoji(22))
    .setStyle(ButtonStyle.Primary));
interaction.reply({ content: 'Hello World!', components: [button] });
```

The corresponding event file:

```js
const event = require('../../../../main/discord/core/events/event.js');
const { Events, MessageFlags } = require('discord.js');

module.exports = class testButton extends event {
  constructor(heart) {
    super(heart, { name: 'testButton', event: { discord: Events.InteractionCreate, bypassManager: false, dm: false, bypassRestrictions: true, permissionLevel: null } });
  }

  async execute(interaction, interactionId, langConfig) {
    try {
      interaction.reply({ content: 'You just pressed a button.' });
    }
    catch (err) {
      this.heart.core.console.log(this.heart.core.console.type.error, `An issue occurred while executing event ${this.getName()}`);
      new this.heart.core.error.interface(this.heart, err);
      interaction.reply({ embeds: [this.heart.core.util.discord.generateErrorEmbed(langConfig.lang.unexpected_function_error.replace(/%function%/g, `${this.getName()}`))], flags: MessageFlags.Ephemeral });
    }
  }
};
```

Component interaction IDs are the unique identifiers for component interactions. They allow Athena to determine which event file should be executed and which configuration options should be applied. It is important that labels follow this format: `iynx:athenabot:<interaction_name>:<additional_data>`.

> The `<interaction_name>` must match the event name you defined, not the `discord.js` event name.

As you may have noticed, the `Discord.interactionCreate` event includes an additional parameter that `discord.js` does not provide: `interactionId`. This parameter represents the interaction label, returned as an array. For example: `['iynx', 'athenabot', 'testButton', '<executor_id>', '<data>']`.

If you want to restrict button access so only the user who ran the command can use it, add a simple check:

```js
if (interaction.user.id !== interactionId[3]) return interaction.reply({ content: 'No Access' });
```

***

## 3. Additional information

{% hint style="warning" %}
Athena provides a custom error logging system that is deeply integrated into the framework. Do not throw errors directly. Instead, catch them and handle them with Athena’s error interface.
{% endhint %}

```js
try {
  // Your code here
}
catch (err) {
  this.heart.core.console.log(this.heart.core.console.type.error, `An issue occurred while executing command ${this.getName()}`);
  new this.heart.core.error.interface(this.heart, err);

  interaction.reply({ embeds: [this.heart.core.util.discord.generateErrorEmbed(langConfig.lang.unexpected_function_error.replace(/%function%/g, `/${interaction.commandName}`))], flags: MessageFlags.Ephemeral });
}
```

{% hint style="info" %}
Athena also provides custom embed builders for warnings, errors, and success messages. See the internal API documentation for more details.
{% endhint %}
