diff --git a/.gitignore b/.gitignore
index 4525073..85f6cee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
-node_modules/
config-dev.yml
package-lock.json
.vscode
node_modules
cache.json
.env
+.setup-complete
\ No newline at end of file
diff --git a/guide/blacklist-specific-nodes.md b/guide/blacklist-specific-nodes.md
new file mode 100644
index 0000000..ddc534a
--- /dev/null
+++ b/guide/blacklist-specific-nodes.md
@@ -0,0 +1,22 @@
+## Blacklist Specific Nodes
+
+1. Select a node from the node list on the admin page.
+
+
+
+
+
+2. Check the URL and copy the node ID.
+
+
+
+
+
+3. Paste the ID into the blacklist in the config.
+
+
+
+> [!TIP]
+> You can add more than one node to the blacklist.
+
+
\ No newline at end of file
diff --git a/guide/changing-env-configuration.md b/guide/changing-env-configuration.md
new file mode 100644
index 0000000..b7c233f
--- /dev/null
+++ b/guide/changing-env-configuration.md
@@ -0,0 +1,15 @@
+## Changing Env Configuration
+> [!TIP]
+> You can change other configuration at the `config.yml` file.
+
+1. Delete `.setup-complete` file in the root directory of the app/bot files.
+2. Run `node index.js` and answer the prompted questions to set up the app/bot.
+
+
+
+ - [Getting an Panel API key](https://github.com/HirziDevs/PteroStats/blob/main/guide/getting-panel-api-key.md)
+ - [Getting a Channel ID](https://github.com/HirziDevs/PteroStats/blob/main/guide/getting-channel-id.md)
+
+3. Run `node index.js` if you want to start the app/bot again, and you're done!
+
+
\ No newline at end of file
diff --git a/guide/docker.md b/guide/docker.md
new file mode 100644
index 0000000..15a65cd
--- /dev/null
+++ b/guide/docker.md
@@ -0,0 +1,26 @@
+## Docker
+
+This is a guide to run the bot using docker (alternative way to run the bot).
+
+### Installation
+
+```bash
+curl -fsSL https://get.docker.com | sh
+```
+
+### Docker Compose
+
+- Copy the `docker-compose.yml` file to your server and run `docker compose pull`
+- Copy the `config.yml` file at the same directory as the `docker-compose.yml` file and configure it (refer to the [Starting the App/Bot](https://github.com/HirziDevs/PteroStats#starting-the-appbot) section)
+
+ ```bash
+ docker compose up -d
+ docker compose logs -f pterostats
+ ```
+
+### Docker Run
+
+```bash
+docker run -d --name pterostats -v $(pwd)/config.yml:/app/config.yml ghcr.io/hirzidevs/pterostats:latest
+docker logs -f pterostats
+```
\ No newline at end of file
diff --git a/guide/getting-channel-id.md b/guide/getting-channel-id.md
new file mode 100644
index 0000000..58055f2
--- /dev/null
+++ b/guide/getting-channel-id.md
@@ -0,0 +1,8 @@
+## Getting Channel ID
+1. Enable Developer Mode in your Discord settings.
+
+
+
+2. Right-click the text channel and select `Copy ID`.
+
+
\ No newline at end of file
diff --git a/guide/getting-panel-api-key.md b/guide/getting-panel-api-key.md
new file mode 100644
index 0000000..5e9903c
--- /dev/null
+++ b/guide/getting-panel-api-key.md
@@ -0,0 +1,22 @@
+## Getting Panel API Key
+> [!WARNING]
+> The use of Application API keys is **deprecated**; you should use **Client API keys**.
+
+> [!TIP]
+> Make sure the owner of the Client API key has access to the administrator panel.
+
+1. Go to your `Pterodactyl` or `Pelican` Panel and navigate to the `Account Page`.
+
+
+
+2. Click on the `API Credentials` button.
+
+
+
+3. Fill in the `Description` and click the `Create` button.
+
+
+
+4. Copy the API key.
+
+
\ No newline at end of file
diff --git a/guide/notifier.md b/guide/notifier.md
new file mode 100644
index 0000000..fec6db9
--- /dev/null
+++ b/guide/notifier.md
@@ -0,0 +1,33 @@
+## Notifier
+Get a notification on Discord when your panel or specific nodes are currently down.
+
+
+
+
+### Enabling Notifier
+Open `config.yml` and set `enable` at the notifier configuration to `true`
+
+
+
+### Getting Discord Webhook URL
+1. Go to the channel settings of the channel you want to set for the notifier.
+
+
+
+2. Go to integrations and select `View Webhooks` or `Create Webhook`.
+
+
+
+3. Create a new webhook and copy the Webhook URL
+
+
+
+4. Paste the Webhook URL on the webhook notifier configuration.
+
+
+
+
+> [!TIP]
+> You can change the webhook icon and username on the webhook settings.
+
+
\ No newline at end of file
diff --git a/guide/using-custom-emoji.md b/guide/using-custom-emoji.md
new file mode 100644
index 0000000..6ec5d1f
--- /dev/null
+++ b/guide/using-custom-emoji.md
@@ -0,0 +1,16 @@
+## Using Custom Emoji
+1. Type `\` in the server that has the custom emoji you want.
+
+
+
+2. Select the custom emoji you want.
+
+
+
+3. Copy the text!
+
+
+
+4. Paste the emoji ID into the config.
+
+
\ No newline at end of file
diff --git a/handlers/setup.js b/handlers/setup.js
index b7275ff..a562622 100644
--- a/handlers/setup.js
+++ b/handlers/setup.js
@@ -1,7 +1,7 @@
-const axios = require("axios")
-const cliColor = require("cli-color")
-const { Client, GatewayIntentBits } = require("discord.js")
-const fs = require("fs")
+const axios = require("axios");
+const cliColor = require("cli-color");
+const { Client, GatewayIntentBits } = require("discord.js");
+const fs = require("node:fs");
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
@@ -82,8 +82,26 @@ module.exports = function Setup() {
console.log(cliColor.green("✓ Valid Discord Bot"));
client.channels.fetch(answers[Question.channelId]).then(() => {
console.log(cliColor.green("✓ Valid Discord Channel"));
- fs.writeFileSync(".env", `PanelURL=${answers[Question.panelUrl]}\nPanelKEY=${answers[Question.panelApiKey]}\nDiscordBotToken=${answers[Question.botToken]}\nDiscordChannel=${answers[Question.channelId]}`, "utf8")
- fs.writeFileSync("config.yml", fs.readFileSync("./config.yml", "utf8").replaceAll("Hosting Panel", answers[0]).replaceAll("https://panel.example.com", answers[1]), "utf-8")
+
+ fs.writeFileSync(".setup-complete", "If you want to re-run the setup process, you can delete this file.", "utf8");
+
+ fs.writeFileSync(
+ ".env",
+ `PanelURL=${answers[Question.panelUrl]}\n` +
+ `PanelKEY=${answers[Question.panelApiKey]}\n` +
+ `DiscordBotToken=${answers[Question.botToken]}\n` +
+ `DiscordChannel=${answers[Question.channelId]}`,
+ "utf8"
+ );
+
+ fs.writeFileSync(
+ "config.yml",
+ fs.readFileSync("./config.yml", "utf8")
+ .replaceAll("Hosting Panel", answers[0])
+ .replaceAll("https://panel.example.com", answers[1]),
+ "utf-8"
+ );
+
console.log(" \n" + cliColor.green(`Configuration saved in ${cliColor.blueBright(".env")} and ${cliColor.blueBright("config.yml")}.\n `));
require("./application.js")()
diff --git a/index.js b/index.js
index 2d73992..7c07717 100644
--- a/index.js
+++ b/index.js
@@ -18,6 +18,6 @@ console.log(
` \n \n${package.description}\n `
);
-if (!fs.existsSync(".env")) return require("./handlers/setup.js")();
+if (!fs.existsSync(".env") || !fs.existsSync(".setup-complete")) return require("./handlers/setup.js")();
-require("./handlers/application.js")();
+require("./handlers/application.js")();
\ No newline at end of file
diff --git a/setup.js b/setup.js
deleted file mode 100644
index 6b026a6..0000000
--- a/setup.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const fs = require("node:fs");
-const cliColor = require("cli-color");
-const package = require("./package.json");
-const readline = require('readline').createInterface({
- input: process.stdin,
- output: process.stdout
-});
-
-console.log(
- ` _${cliColor.blueBright.bold(`${cliColor.underline("Ptero")}dact${cliColor.underline("yl & P")}eli${cliColor.underline("can")}`)}___ ______ ______ \n` +
- ` /\\ ___\\ /\\__ _\\ /\\ __ \\ /\\__ _\\ /\\ ___\\ \n` +
- ` \\ \\___ \\ \\/_ \\ \\/ \\ \\ \\_\\ \\ \\/_/\\ \\/ \\ \\___ \\ \n` +
- ` \\/\\_____\\ \\ \\_\\ \\ \\_\\ \\_\\ \\ \\_\\ \\/\\_____\\ \n` +
- ` \\/_____/ \\/_/ \\/_/\\/_/ \\/_/ \\/_____/${cliColor.yellowBright.bold(`${package.version}`)}`
-);
-
-console.log(
- ` \nCopyright © 2022 - ${new Date().getFullYear()} HirziDevs & Contributors\n ` +
- " \nDiscord: https://discord.znproject.my.id" +
- " \n Source: https://github.com/HirziDevs/PteroStats" +
- " \nLicense: https://github.com/Hirzidevs/PteroStats/blob/main/LICENSE" +
- ` \n \n${package.description}\n `
-);
-
-if (!fs.existsSync(".env")) return require("./handlers/setup.js")();
-
-console.log(cliColor.yellowBright(
- "Configuration is already set. Please select one of the following options:\n \n" +
- `${cliColor.cyanBright("1")} ${cliColor.blueBright("»")} Start the App\n` +
- `${cliColor.cyanBright("2")} ${cliColor.blueBright("»")} Change configuration\n `
-));
-
-readline.question('> ', async (answer) => {
- readline.close();
-
- switch (answer) {
- case '2':
- require("./handlers/setup.js")();
- break;
- case '1':
- require("./handlers/application.js")();
- break;
- default:
- console.log(cliColor.redBright('Invalid input. Please type either 1 or 2.'));
- }
-});