> 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/schedules.md).

# Schedules

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

***

## 1. Setting up the schedule file

1. Copy the schedule template.

```js
const scheduledTask = require('../../../../main/discord/core/schedule/schedule.js');

module.exports = class loop extends scheduledTask {
  constructor(heart) {
    super(heart, 'loop', { repeat: true, interval: 60000 });
  }

  execute() {
    this.heart.core.console.log(this.heart.core.console.type.log, '60 seconds have passed since the last time :-:');
  }
};
```

2. Create a new schedule file inside your `/plugins/<plugin_name>/src/schedules/` directory.
3. The name of the file must follow the format `<schedule_name>.js`.

### Parameters

* **`'loop'`:** A unique identifier for the schedule.
* **repeat:** Defines whether the file should be executed repeatedly every `<interval>` milliseconds, or only once after `<interval>` milliseconds.
* **interval:** The time in milliseconds between each execution.

***

## 2. Schedule response

Schedules are used to handle tasks that occur repeatedly. A common example is unmutes.

When a user is muted, the mute duration and punishment date are stored in the user database. The bot then loads all documents of currently muted users and, at each interval check, determines whether the mute has expired. If so, it automatically executes the `unmute` function.

For an example, see the unmute schedule from Athena’s source code:

```js
module.exports = class tempUnmute extends scheduledTask {
  constructor(heart) {
    super(heart, 'tempUnmute', { repeat: true, interval: 223000 });
  }

  async execute() {
    try {
      const commonConfig = this.heart.core.config.common.get();
      const guild = this.heart.core.discord.guilds.cache.get(commonConfig.bot.discord_guild_id);
      if (!guild) return;

      const mod = this.heart.core.discord.core.handler.manager.get('mod');
      const model = this.heart.core.database.getModel('user').getModel();
      const data = await model.find({
        guildId: guild.id,
        muted: true,
      });

      for (let i = 0, length = data.length; i < length; i++) {
        const punishment = await mod.load(data[i].mutes[data[i].mutes.length - 1]);
        const validTil = punishment.validTil();

        if (punishment.isActive() && !validTil.permanent && !validTil.active) {
          const user = await this.heart.core.discord.users.fetch(data[i].userId, { force: true, cache: true });
          if (!user) {
            await data[i].deleteOne();
            continue;
          }

          const unmute = await mod.unmute(guild, user, this.heart.core.discord.user, false, punishment);
          if (!unmute) {
            this.heart.core.console.log(this.heart.core.console.type.log, `User with the ID ${punishment.getUserId()} has been unmuted due to`);
            this.heart.core.console.log(this.heart.core.console.type.log, `his temporary mute running out. Punishment ID: ${punishment.getPunishmentId()}`);
          }
          await this.heart.core.util.util.sleep(2000);
        }
      }
    }
    catch (err) {
      this.heart.core.console.log(this.heart.core.console.type.error, `An issue occurred while executing schedule event ${this.getName()}`);
      new this.heart.core.error.interface(this.heart, err);
    }
  }
};
```

***

## 3. Additional information

{% hint style="warning" %}
Intervals are not executed immediately. Once the time until the next execution has passed, the schedule is pushed to Athena’s schedule queue, so it may take up to 20 additional seconds for your schedule to run.
{% endhint %}

{% 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 schedule event ${this.getName()}`);
  new this.heart.core.error.interface(this.heart, err);
}
```
