2020-08-25 19:04:24 +02:00
|
|
|
# Frank
|
2020-08-26 12:22:18 +02:00
|
|
|
## Description
|
|
|
|
Playing around with creating a Discord bot is a fun pass-time, and a good way to learn a programming language. Sadly,
|
|
|
|
however, discord.py can be a little hard to work with at times. That's when I got the idea to create Frank. The goal of
|
|
|
|
Frank is to make creating Discord bots easier. It handles all the bot-related stuff in the background, so you can focus
|
|
|
|
on writing the functionality of the bot itself, not how the bot works/interacts with Discord.
|
|
|
|
|
|
|
|
Frank works by dividing the bot into modules. Each module has its own prefix, commands, and daemons. Frank handles
|
|
|
|
routing the Discord commands to their respective functions.
|
|
|
|
|
2020-08-26 17:30:22 +02:00
|
|
|
## Installation
|
|
|
|
You can install the `frank-discord` package from PyPi:
|
|
|
|
|
|
|
|
```
|
|
|
|
pip install frank-discord
|
|
|
|
```
|
|
|
|
|
2020-08-26 12:22:18 +02:00
|
|
|
## Example Module
|
|
|
|
In this section, I've written an example module for you, to understand the basic mechanics behind Frank.
|
|
|
|
|
|
|
|
```python
|
|
|
|
import frank
|
|
|
|
|
|
|
|
class ExampleMod(frank.Module):
|
|
|
|
PREFIX = 'examp'
|
|
|
|
NAME = 'example'
|
|
|
|
HELP = 'an example module'
|
|
|
|
```
|
|
|
|
|
|
|
|
This first part shows the three important variables in any module.
|
|
|
|
- PREFIX defines the string used to use the commands defined in this module. This means you can use the module as such
|
|
|
|
inside your Discord server:
|
|
|
|
```
|
|
|
|
fr examp [NAME_OF_COMMAND] [ARGS]
|
|
|
|
```
|
|
|
|
With fr being the default prefix for Frank (can be overwritten). As you define more modules, they should all have a
|
|
|
|
unique prefix. This is how Frank's modular system works, and any modules added to the list will automatically be
|
|
|
|
picked up by Frank. The PREFIX value can also be list, allowing for multiple prefixes: for example a long,
|
2020-08-27 09:41:03 +02:00
|
|
|
descriptive one, and a short, easy to type one (e.g. minecraft and mc).
|
2020-08-26 12:22:18 +02:00
|
|
|
|
|
|
|
```python
|
|
|
|
def pre_start(self):
|
|
|
|
self.some_var = 'a value needed for working'
|
|
|
|
```
|
2020-08-26 14:54:55 +02:00
|
|
|
|
2020-08-26 12:22:18 +02:00
|
|
|
The pre_start function is where you define any variables which should be created before any daemons are started or
|
|
|
|
commands are run. I don't recommend overwriting `__init__`, as this might break compatibility with future versions of
|
|
|
|
Frank.
|
|
|
|
|
|
|
|
```python
|
|
|
|
@frank.command('command', help_str='a small description of the command')
|
|
|
|
async def some_command(self, cmd, author, channel, mid):
|
|
|
|
# do some stuff
|
|
|
|
pass
|
|
|
|
|
|
|
|
@frank.daemon()
|
|
|
|
async def some_daemon(self):
|
|
|
|
while True:
|
|
|
|
# do some stuff
|
|
|
|
pass
|
|
|
|
|
|
|
|
@frank.default()
|
2020-08-27 09:41:03 +02:00
|
|
|
async def default_cmd(self, author, channel, mid):
|
2020-08-26 12:22:18 +02:00
|
|
|
# do some default action
|
|
|
|
pass
|
|
|
|
```
|
|
|
|
|
|
|
|
These three decorators are the bread and butter of Frank. Let's break them down:
|
|
|
|
- `frank.command` defines a command. The first argument is its keyword, which will be used to execute the command. The
|
|
|
|
help_str value is used in the help command, to show some information about the module. The syntax is the same as
|
|
|
|
before:
|
|
|
|
```
|
|
|
|
fr examp command [ARGS]
|
|
|
|
```
|
|
|
|
This is how you can define as many Discord commands as you want, without needing to know how to parse the messages
|
2020-08-27 09:41:03 +02:00
|
|
|
etc. Each command gets the `author`, `channel`, and `id` of the message. The `cmd` variable contains all the
|
|
|
|
arguments passed to the command.
|
2020-08-26 12:22:18 +02:00
|
|
|
- `frank.daemon` defines a daemon, a process that should run in the background for as long as the bot is active. It
|
|
|
|
should contain a while loop and preferably a sleep function using `asyncio.sleep()` (there are plans to improve this
|
|
|
|
behavior). Because a daemon is just a method of the module class, it has access to all class variables, including
|
|
|
|
those defined in `pre_start`.
|
2020-08-27 09:41:03 +02:00
|
|
|
- `frank.default` defines the command that should be run if the module is called without explicitly giving a command.
|
2020-08-26 12:22:18 +02:00
|
|
|
For example, if you call `fr examp` without specifying a command, it will run the default command. This is useful for
|
|
|
|
making a command that's used very often easier to execute.
|
2020-08-27 09:41:03 +02:00
|
|
|
|
|
|
|
In the end, all you need to do is add the following in your main script:
|
|
|
|
|
|
|
|
```python
|
|
|
|
from frank import Frank
|
|
|
|
# Or whatever your package containing your modules is called
|
|
|
|
from modules import ExampleMod
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
client = Frank([ExampleMod])
|
|
|
|
client.run(YOUR_DISCORD_TOKEN)
|
|
|
|
```
|