# Discord Bot

## Preface

This guide will work on any of the HelioHost servers.

Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together. Python's simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports modules and packages, which encourages program modularity and code reuse.

The Discord app works with desktop and mobile platforms, combining the features of a chat lobby, a message board and a VoIP chatting system into one app that's not going to hog resources on your phone or PC. Discord's popularity has only multiplied in recent years, with the app now reaching over 90 million registered users.

Bots and apps are the lifeblood of the Discord development community. They come in all shapes and sizes, from small hobby projects for your server with friends, to huge projects that live in hundreds of thousands of servers. We love seeing the unique, fun, and sometimes downright strange (in a good way) creations that come from our community.

## How to get Started with a Discord Bot

First you'll need to have a Discord account, and a Discord channel that you'll add the bot to later. Here's a good guide to get started:

{% embed url="https://www.howtogeek.com/364075/how-to-create-set-up-and-manage-your-discord-server/" %}

### Create the Bot

Once you have your Discord server all set up it's time to create the bot through Discord's site. Go to [https://discordapp.com/developers/applications](https://discordapp.com/developers/applications) and make sure you're logged in. Then click `New Application` in the top right.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-af6ae7cc749de38b2eff9770378adbd332ff226f%2FNew_application.png?alt=media)

Type a name and hit create. I decided to name my bot `HelioBot`.

### Add the Bot to your Discord Server

Click `OAuth2` on the left navigation.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-21ed971293a6cbfeae90cbeaa86320afd8d8dd26%2FOauth2.png?alt=media)

Then check the bot box under `SCOPES`, and scroll down and select `Administrator` under `BOT PERMISSIONS`. You could select the exact permissions that your bot needs one by one, but for this simple example it's easier to just allow the bot permission to do everything.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-0a9c0838e0c93e1f60345cc7a029036ee6ffbf92%2Fbot_admin.png?alt=media)

Click copy next to the URL that is generated and open that URL in a new tab. Then, select your Discord server from the dropdown menu.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-8c423c34bbca4108a34801982059f8895b6845f9%2FAdd_to_server.png?alt=media)

Click `Authorize` and complete the reCAPTCHA to add the bot to the Discord server. If you go to your Discord now you can see the bot on the offline user list.

![Bot on the offline user list](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-63e1c082d41bc5a3bac6f423f44dacf74a77bc85%2FOffline_bot.png?alt=media)

### Write the Bot Script in Python

Log in at [https://heliohost.org/login](https://heliohost.org/login/) and continue to Plesk. Then load up the file manager.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-2a2456f60c9ca81108c09c8786128dd3091bc0b4%2FFile_manager.png?alt=media)

In the top left corner click the `+` plus sign, and select `Create File`.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-03a49405293c05ffc88fa2342983bff9e452e7e1%2Fplus_file.png?alt=media)

Then type the name of your new file: `heliobot.py`.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-86c92bdd053c3791ada6511564ec60671b08d204%2Fcreate_heliobot.png?alt=media)

You want to create this bot in your home directory so random hackers and bots on the internet can't access it directly. Make sure it says `Add a file to: /` not `Add a file to: /httpdocs` or any other folder.

Scroll down in the file manager and click on the new `heliobot.py` file to edit it. Then copy/paste this code in:

```python
#!/usr/bin/python3.12

import os
import discord
from dotenv import load_dotenv

load_dotenv()
token = os.getenv('DISCORD_TOKEN')

import certifi
os.environ["SSL_CERT_FILE"] = certifi.where()

client = discord.Client(intents=discord.Intents.default())

class MyClient(discord.Client):
    async def on_ready(self):
        print(f'Logged in as {self.user} (ID: {self.user.id})')
        print('------')

    async def on_message(self, message):
        # we do not want the bot to reply to itself
        if message.author.id == self.user.id:
            return

        if message.content.startswith('!hello'):
            await message.reply('Hello!', mention_author=True)


intents = discord.Intents.default()
intents.message_content = True

client = MyClient(intents=intents)
client.run(token)
```

The first line is called the shebang, and it tells the system which version of Python you want to use. Johnny and Tommy also have Python 2.7, and Python 3.6, but we recommend using Python 3.10 like in the example.

Once you have your code copy/pasted in click save in the bottom left corner. Now we need the bot to be executable so in the file manager click the `rw- r-- r--` on the heliobot.py line.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-2293d724785b600b05bf52e18cd72191a3605d87%2Fchange_permissions.png?alt=media)

Check all three of the `Execute/Search` boxes so it looks like this and then click save in the bottom left corner.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-83792b2c6198727b2f898fcf5c47c61f90926e17%2F755_permissions.png?alt=media)

Now we need to provide our Discord token to the bot so click the `+` plus sign, and select `Create File` again and this time name the file `.env`.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-9dd476436cc8f5b49f0a057e088f9f10bc0cc98c%2Fdot_env.png?alt=media)

**Make sure you start the filename with a period.** It's easy to miss that in the screenshot. This file needs to be in the **same** directory as your Python script.

Go back to the Discord bot page and click bot on the left navigation again.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-63bef7f05362ac03a6bfd8fe183e17ab8eb7761b%2FSelect_bot.png?alt=media)

The first thing we need to do on this page is enable `Presence Intent`, `Server Members Intent`, and `Message Content Intent`. If you're sure your bot doesn't need all three of these enable just what you need, but for simplicity of this guide we're going to enable all three, and then save the changes.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-40864d3a0656a98bd17f436969de49f0d32ba391%2Fdiscord_intents.png?alt=media)

On the same page click the `Reset Token` button, and then copy/paste the token.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-4adcac9fc1012e420a679b0c1129cec679e0201a%2FCopy_token.png?alt=media)

If you ever think someone has gotten your token, for instance if you posted it on a public wiki like I just did, be sure to come back to this page and reset it. Anyone who has your token can do whatever permissions you granted your bot to your server. Now you need to paste this token into your `.env` file that you created. So go back to the Plesk file manager and click the `.env` file to edit it. Paste the token into the file like this:

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-64a28079464210508dcabef3d61c546e2b2811d0%2Fpaste_the_token.png?alt=media)

Make sure the line starts with `DISCORD_TOKEN=` like that. Then click `Save Changes` and close the tab. Saving your token separate from your Python code is good practice because this way you can share the code on GitHub or something like that without worrying about people getting access to your bot.

### Starting and Stopping Your Bot

You have a functional bot now, but you need a way to start and stop it.

{% hint style="warning" %}
Side note: Previous versions of this guide used Python scripts to start and stop the Discord bot. Unfortunately, the people who wanted to write their bot in Node.js always complained that they didn't want to use Python for anything. Likewise, if we used Node.js to start and stop the bot, the Python people would inevitably complain about not wanting to use Node.js for anything. Therefore, we wrote the start and stop scripts in Bash CGI to make absolutely sure that no one is happy.
{% endhint %}

We'll use Bash CGI to do that so you can control your bot through your web page. With the file manager, navigate to `/httpdocs` and create a new directory called `bot_control`.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-8c114c2bb5829cbfb413f0c9099d82ccc56fd80a%2Fbot_control.png?alt=media)

Now create a new file named `.htaccess` in the `/httpdocs/bot_control` directory.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-9e1e4293b7d9f285a5bbe773370c8e37f52a88cf%2Fcreate_htaccess.png?alt=media)

Paste this code into the new `.htaccess` file.

```
Options +ExecCGI
AddHandler cgi-script .sh
DirectoryIndex index.sh
```

Next create a new file named `index.sh` in the `/httpdocs/bot_control` directory.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-810c31791d57a43c1b71e1e190cf33718933d362%2Fcreate_indexsh.png?alt=media)

Paste in this code into the new file:

```bash
#!/bin/bash

# edit these to match your username, main domain, and bot filename
username="krydos"
main_domain="krydos.heliohost.org"
bot_name="heliobot.py"

###################################################################

printf 'Content-Type: text/html\n\n'
temp=`ps axo user:16,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,command|grep -v grep|grep "^$username"`
running=`echo "$temp"|grep -c "$bot_name"`
file_base=`echo $bot_name|tr -cd "a-zA-Z0-9"`
log_name="$file_base.txt"
if [ "$QUERY_STRING" == "" ]; then
    if [ $running -ne 0 ]; then
        mem_kb=`echo "$temp"|grep "$bot_name"|awk '{print $6}'`
        mem_mb=$( echo "scale=2;$mem_kb/1024"|bc )
        mem_24=$( echo "scale=2;$mem_kb*1440/1048576"|bc )
        echo "$bot_name is running. <a href='?action=stop'>Stop</a><br>Current memory usage: $mem_mb MB<br>Estimated 24 hour usage: $mem_24 GB - "
    else
        echo "$bot_name is not running. <a href='?action=start'>Start</a> - "
    fi
    echo "<a href='https://heliohost.org/dashboard/load/' target='_blank'>Check Load</a><br><br>Logs: <a href='?action=clear'>Clear Logs</a> - <a href='/bot_control/$log_name'>Full Logs</a><pre>"
    tail -30 /home/$main_domain/httpdocs/bot_control/$log_name
    echo "</pre><script>reloading = setTimeout('window.location.reload();', 10000);</script>"
fi
ts=`date +"%Y-%m-%d %H:%M:%S"`
if [ "$QUERY_STRING" == "action=stop" ]; then
    echo "[$ts] Stopping $bot_name." >> /home/$main_domain/httpdocs/bot_control/$log_name
    pid=`echo "$temp"|grep "$bot_name"|tail -1|awk '{print $2}'`
    if [ ${#pid} -ne 0 ]; then
        kill $pid
    fi
    echo "Stopping $bot_name...<script>window.location.replace('/bot_control/');</script>"
fi
if [ "$QUERY_STRING" == "action=start" ]; then
    echo "[$ts] Starting $bot_name." >> /home/$main_domain/httpdocs/bot_control/$log_name
    /usr/bin/python3.12 -u /home/$main_domain/$bot_name >> /home/$main_domain/httpdocs/bot_control/$log_name 2>&1 &
    echo "Starting $bot_name...<script>window.location.replace('/bot_control/');</script>"
fi
if [ "$QUERY_STRING" == "action=clear" ]; then
    cat /dev/null > /home/$main_domain/httpdocs/bot_control/$log_name
    echo "Clearing logs...<script>window.location.replace('/bot_control/');</script>"
fi
exit 0
```

Be sure to edit the three variables at the top of the file to match your username, main domain, and bot filename.

Now, we need to set the permissions of this `index.sh` file to be executable. On the file manager click the `rw- r-- r--` and check all the `Execute/Search` boxes just like we did the heliobot.py file earlier.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-83792b2c6198727b2f898fcf5c47c61f90926e17%2F755_permissions.png?alt=media)

### Test It Out

Now everything should be ready to be tested. Open your browser and go to `yourdomain.helioho.st/bot_control/` and when you click Start it should start the bot. You can check if the bot is running by going to Discord and seeing if HelioBot is showing up as online now. If it is, test it out by typing the command:

```
!hello
```

It should respond to you.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-495fc7e26a4250c3f09817d1b0dfd5f628cbadb3%2Ftesting_discord_bot.png?alt=media)

If it doesn't work go back and check all the steps again to make sure you did everything correctly. You can also check out the logs in the bot\_control dashboard to see if there is any errors listed. For example, if you try to import a modules that isn't already installed it will give an error like this:

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-b745a173569946b3295c3ee17edddbc4b8221f46%2Fbot_error.png?alt=media)

If you can't figure out what is wrong let us know by opening [a customer service ticket](https://helionet.org/index/forum/45-customer-service/?do=add).

### Watch Your Load

On Johnny and Tommy you are limited to 100 GB of memory and 10000 CPU per day, and bots use a lot of system resources so we recommend keeping an eye on your load if you don't want to get suspended. On the bot\_control dashboard it shows the current memory usage, and the estimated usage over the next 24 hours if your bot continues using the same amount of memory.

![](https://3395442955-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwjgns5x95EsDajJxZl%2Fuploads%2Fgit-blob-bf38c89cdeedfea72a3120ba99761951df2f3f2d%2Fbot_dashboard.png?alt=media)

If you followed the guide exactly your bot will use about 50 GB or memory per day, which is half of your allowed amount. If you edit your bot code, make your bot more complicated, and import more modules it will increase the memory usage though. Obviously if you have some sort of memory leak it could easily allow your bot to continue consuming more and more memory until you get suspended.

If everything is working you can shut your bot down by clicking the Stop button on the bot\_control dashboard. It's a good idea to keep your bot offline if you don't need it so you don't cause too much load. If you're having trouble staying under the limits you could also consider [moving to a VPS](https://heliohost.org/vps/) where you have root SSH access, dedicated memory and CPU, and no load limits.
