# How does features and events work?

## ✨ **Welcome to Events & Features section!**

### **Features**

A feature can include multiple event listeners and other systems to handle how your bot works. You can create a "features" folder and place all your features in that folder.&#x20;

The files will be automatically imported and ran. Here's an example:

{% tabs %}
{% tab title="JavaScript" %}
{% code title="features/server-logs.js" %}

```javascript
const { Feature } = require('sl-commands')

new Feature()
  /** This will be executed once when the handler starts */
  .setInit(({ client, handler }) => {
    console.log('This will be ran once.')
  })
  /** This will be executed continuously with the interval of your choice */
  .addTimed(({ client, handler }) => {
    console.log('This will be ran every 5 seconds.')
  }, 5000) // 1000 = 1 second
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="features/server-logs.ts" %}

```typescript
import { Feature } from 'sl-commands'

new Feature()
  /** This will be executed once when the handler starts */
  .setInit(({ client, handler }) => {
    console.log('This will be ran once.')
  })
  /** This will be executed continuously with the interval of your choice */
  .addTimed(({ client, handler }) => {
    console.log('This will be ran every 5 seconds.')
  }, 5000) // 1000 = 1 second
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Events

But if you want just one event listener and nothing more, you can create an event in an "events" folder. The files imported will be ran whenever the event is emitted. You can create an event using this structure:

{% tabs %}
{% tab title="JavaScript" %}
{% code title="events/welcome.js" %}

```javascript
const { Event } = require('sl-commands')

/** 
 * In this case the event will be ran whenever thE
 * "guildMemberAdd" event is emitted. 
 */

/** 
 * The first argument must be a keyof DiscordJS ClientEvents 
 * or SLCommands HandlerEvents
 */
new Event(
  'guildMemberAdd', 
  ({ client, handler }, member) => {
    /** Access the guild that they joined */
    let { guild } = member
  
    /** Get the channel named "welcome" */
    let channel = guild.channel.cache.find(
      (channel) => channel.name === 'welcome'
    )
  
    /** Ensuring the channel exists */
    if (!channel) return
  
    /** Send the welcome message */
    channel.send(`Welcome ${member}!`)
  },
  false // Here you can set if the event will be ran just once or not.
)
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}

<pre class="language-typescript" data-title="events/welcome.ts"><code class="lang-typescript">import { Event } from 'sl-commands'

/** 
 * In this case the event will be ran whenever thE
 * "guildMemberAdd" event is emitted. 
 */

/** 
 * The first argument must be a keyof DiscordJS ClientEvents 
 * or SLCommands HandlerEvents
 */
<strong>new Event(
</strong>  'guildMemberAdd', 
  ({ client, handler }, member) => {
    /** Access the guild that they joined */
    let { guild } = member
  
    /** Get the channel named "welcome" */
    let channel = guild.channel.cache.find(
      (channel) => channel.name === 'welcome'
    )
  
    /** Ensuring the channel exists */
    if (!channel) return
  
    /** Send the welcome message */
    channel.send(`Welcome ${member}!`)
  },
  false // Here you can set if the event will be ran just once or not.
)
</code></pre>

{% endtab %}
{% endtabs %}

This can be used to handle SLCommands events too! You can see more here:

{% content-ref url="/pages/Xiw0Yxuzwy9kMJoTzlnD" %}
[SLCommands Events](/sl-commands/events-and-features/slcommands-events.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://synclab.gitbook.io/sl-commands/events-and-features/explanation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
