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

# Getting Started

This page explains how to create your own plugin for AthenaBot using the [Plugin Template](https://github.com/Zeroknights16/AthenaBot-PluginTemplate). The internal Developer API makes it easy to extend AthenaBot’s functionality without touching the core code.

{% hint style="warning" %}
Familiarity with Node.js and discord.js is required to follow this documentation.
{% endhint %}

***

## 1. Setting up your editor

If you are using Visual Studio Code, you can enable typings for AthenaBot by creating a configuration file in the root directory. This will help you see available functions directly in your editor.

```json
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
    "target": "ES2020",
    "jsx": "react",
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "baseUrl": "./",
    "paths": {
      "*": ["types/*"]
    }
  },
  "exclude": [
    "node_modules",
    "**/node_modules/*"
  ]
}
```

We also use [ESLint](https://www.npmjs.com/package/eslint) to keep the codebase clean and consistent. If you want to follow the same style rules, create a file called `.eslintrc.json` in the root directory and paste the following:

```json
{
  "extends": ["eslint:recommended"],
  "env": {
    "node": true,
    "es6": true
  },
  "parserOptions": {
    "ecmaVersion": 2020
  },
  "rules": {
    "brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
    "comma-dangle": ["error", "always-multiline"],
    "comma-spacing": "error",
    "comma-style": "error",
    "curly": ["error", "multi-line", "consistent"],
    "dot-location": ["error", "property"],
    "handle-callback-err": "off",
    "indent": ["error", "tab"],
    "max-nested-callbacks": ["error", { "max": 4 }],
    "max-statements-per-line": ["error", { "max": 2 }],
    "no-console": "off",
    "no-empty-function": "error",
    "no-floating-decimal": "error",
    "no-inline-comments": "off",
    "no-lonely-if": "error",
    "no-multi-spaces": "error",
    "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
    "no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }],
    "no-trailing-spaces": ["error"],
    "no-var": "off",
    "object-curly-spacing": ["error", "always"],
    "prefer-const": "error",
    "quotes": ["error", "single"],
    "semi": ["error", "always"],
    "space-before-blocks": "error",
    "space-before-function-paren": ["error", {
      "anonymous": "never",
      "named": "never",
      "asyncArrow": "always"
    }],
    "space-in-parens": "error",
    "space-infix-ops": "error",
    "space-unary-ops": "error",
    "spaced-comment": "error",
    "yoda": "error"
  }
}
```

***

## 2. Downloading the plugin template

1. Go to the [Plugin Template repository](https://github.com/Zeroknights16/AthenaBot-PluginTemplate).
2. Download the template files with Code → Download ZIP or clone it with Git.
3. Place the entire folder into your AthenaBot installation under `/plugins/`.

Your directory structure should look like this:

```
AthenaBot/
├── backup/
├── configuration/
├── logs/
├── main/
├── node_modules/
├── plugins/
│   └── MyFirstPlugin/
│       ├── main.js
│       ├── data/
│       │   ├── configs/
│       │   └── dashboard/
│       └── src/
│           └── dashboard/
```

***

## 3. Understanding the plugin template

### Main file

Below is the entry point of your plugin. This example was taken from the template itself. We will go through the whole `main.js` file step by step.

```js
const plugin = require('../../main/discord/core/plugins/plugin.js');
const testHandler = require('./src/handler/test.js');

module.exports = class test extends plugin {
  constructor(heart) {
    super(heart, { name: 'test', author: 'Zeroknights', version: '1.0.0', requiredAthenaVersion: '2.2.0', priority: 0, dependencies: ['core'], softDependencies: [], nodeDependencies: [], channels: [], dashboard: { cannotDisable: false } });
  }

  async preLoad() {
    this.heart.core.console.log(this.heart.core.console.type.startup, 'The plugin is pre-loading now...');
    const helloConfig = new this.heart.core.discord.core.config.interface(
      this.heart,
      { name: 'hello', plugin: this.getName(), dashboardConfigurable: true },
      {
        config: {
          bot_name: undefined,
          bot_id: undefined,
          bot: undefined,
          permissions: {
            test_command: undefined,
            info_command: undefined,
            ticket_inactivity_event: undefined,
          },
          dashboard_panels: undefined,
          alert_rules: undefined,
        }
      },
    );
    const loadHelloConfig = await this.heart.core.discord.core.config.manager.load(helloConfig);
    if (!loadHelloConfig) {
      this.setDisabled();
      this.heart.core.console.log(this.heart.core.console.type.error, `Disabling plugin ${this.getName()}...`);
      return;
    }
  }

  async load() {
    this.heart.core.console.log(this.heart.core.console.type.startup, 'The plugin is loading now...');
    this.heart.core.discord.core.handler.manager.register(new testHandler(this.heart));
  }
};
```

> The `heart` object is your access point to the Developer API, including logging, configs, and utilities.

### Class constructor

```js
super(heart, { name: 'test', author: 'Zeroknights', version: '1.0.0', requiredAthenaVersion: '2.2.0', priority: 0, dependencies: ['core'], softDependencies: [], nodeDependencies: [], channels: [], dashboard: { cannotDisable: false } });
```

* **Name:** Your plugin name. Make sure this is unique.
* **Author:** Your username.
* **Version:** Your plugin version.
* **RequiredAthenaVersion:** Specifies the minimum AthenaBot version needed for the plugin.
* **Priority:** The higher the number, the earlier your plugin will be loaded.
* **Dependencies:** List of plugin dependencies required for this plugin to run. All plugins depend on the core plugin.
* **softDependencies:** Optional plugin dependencies.
* **nodeDependencies:** Node.js dependencies that are installed before loading.
* **channels:** Registered channels that can be configured through Athena’s `/setup` command.
* **dashboard.cannotDisable:** If set to `true`, the plugin cannot be disabled in the dashboard.

### Config constructor

If your plugin does not offer a config, you can remove the following code snippet from your plugin template.

```js
const helloConfig = new this.heart.core.discord.core.config.interface(
  this.heart,
  { name: 'hello', plugin: this.getName() },
  {
    config: {
      bot_name: undefined,
      bot_id: undefined,
      bot: undefined,
      permissions: {
        test_command: undefined,
        info_command: undefined,
        ticket_inactivity_event: undefined,
      },
      dashboard_panels: undefined,
      alert_rules: undefined,
    }
  },
);
const loadHelloConfig = await this.heart.core.discord.core.config.manager.load(helloConfig);
if (!loadHelloConfig) {
  this.setDisabled();
  this.heart.core.console.log(this.heart.core.console.type.error, `Disabling plugin ${this.getName()}...`);
  return;
}
```

* **Line 1:** Always keep the `heart` object for the config manager.
* **Line 2:** `name` is the config name. In this example, your config is called `hello`.
* **Line 3-17:** This defines the structure of your plugin configuration file.

> Important: Your configuration file must start with a top-level `config` object.

```js
{
  config: {
    bot_name: 'Athena',
    bot_id: '22354373457231251362',
    bot: true,
    permissions: {
      test_command: 'everyone',
      info_command: 'member',
      ticket_inactivity_event: 'everyone',
    },
  }
}
```
