# Making Features

Features are a cool feature that Worn Off Keys made. They are side functions, that run along side your bot. Instead of putting them in the main event files.

## Example of a Suggestion Feature

{% tabs %}
{% tab title="JavaScript" %}
{% code title="suggestions.js" %}

```javascript
module.exports = (bot, hkandelr) => {
  bot.on("message", (message) => {
    if (message.author.bot) return;
    if (message.channel.name == "suggestions") {
      message.react("✅");
      message.react("❌");
    }
  });
};
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="suggestions.ts" %}

```typescript
import { Client } from "discord.js"
import { HKandler } from "hkutilities/dist/structures/hkandler"
export = (bot, hkandler) => {
  bot.on("message", (message) => {
    if (message.author.bot) return;
    if (message.channel.name == "suggestions") {
      message.react("✅");
      message.react("❌");
    }
  });
};
```

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

## Reaction Roles

You can also have several listeners inside a feature

{% hint style="info" %}
Make sure to have partials!
{% endhint %}

{% tabs %}
{% tab title="JavaScript" %}
{% code title="reactionroles.js" %}

```javascript
import { Client } from "discord.js"
import { HKandler } from "hkutilities/dist/structures/hkandler"

const role1 = "123456789"
const role2 = "987654321"

const channelID = "13579"

module.exports = (bot, hkandler) => {
  bot.on("messageReactionAdd", async (reaction, user) => {
    if (reaction.message.partial) await reaction.message.fetch();
    if (reaction.partial) await reaction.fetch();
    if (user.bot) return;

    if (reaction.message.channel.id === channelID) {
      let emoji = reaction.emoji.name;
      switch (emoji) {
        case "1️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.add(role1);
          break;
        case "2️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.add(role2);
          break;
      }
    }
  });
  bot.on("messageReactionRemove", async (reaction, user) => {
    if (reaction.message.partial) await reaction.message.fetch();
    if (reaction.partial) await reaction.fetch();
    if (user.bot) return;

    if (reaction.message.channel.id === channelID) {
      let emoji = reaction.emoji.name;
      switch (emoji) {
        case "1️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.remove(role1);
          break;
        case "2️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.remove(role2);
          break;
      }
    }
  });
};

```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="reactionroles.ts" %}

```typescript
const role1 = "123456789"
const role2 = "987654321"

const channelID = "13579"

export = (bot, hkandler) => {
  bot.on("messageReactionAdd", async (reaction, user) => {
    if (reaction.message.partial) await reaction.message.fetch();
    if (reaction.partial) await reaction.fetch();
    if (user.bot) return;

    if (reaction.message.channel.id === channelID) {
      let emoji = reaction.emoji.name;
      switch (emoji) {
        case "1️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.add(role1);
          break;
        case "2️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.add(role2);
          break;
      }
    }
  });
  bot.on("messageReactionRemove", async (reaction, user) => {
    if (reaction.message.partial) await reaction.message.fetch();
    if (reaction.partial) await reaction.fetch();
    if (user.bot) return;

    if (reaction.message.channel.id === channelID) {
      let emoji = reaction.emoji.name;
      switch (emoji) {
        case "1️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.remove(role1);
          break;
        case "2️⃣":
          await reaction.message.guild.members.cache.get(user.id).roles.remove(role2);
          break;
      }
    }
  });
};

```

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