Build chat bots for the destiny.gg chat
Project description
DGG Chat Bot
A framework for building chat bots for the destiny.gg chat. It allows you to register
commands for when a user whispers you, so you can then reply with something useful.
Built with the dgg-chat
package.
In case you want a more in-depth example, check out the remind me bot.
Installing
This package is available via pip!
pip install dgg-chat-bot
A (very) minimal working example (more details below):
from dgg_chat_bot import DGGChatBot
bot = DGGChatBot("<dgg auth token>")
@bot.on_command('helloworld')
def hello_world():
bot.reply('Hello World!')
bot.run_forever()
How To Use
The DGGChatBot
class runs the main event loop. It parses messages users sent to you for a command
and invokes any functions registered. Registering a function to a command can be done with the
DGGChatBot().on_command()
decorator.
As it is with the dgg-chat
package, all handlers are called synchronously, that is, a handler
will only be called after the previous one finished its work. If you want to do time intensive tasks,
the asynchronous aspect has to be done manually. Native asynchronous support might be implemented in the future.
A more complete example can be found in the example.py
file.
Registering Commands
When using the on_command()
decorator, the first argument will be the keyword associated with
that command, followed by any number of aliases. There's also override
and optional_args
,
arguments explained later on.
It is enforced that the same alias cannot be used for multiple commands. Unless you set
override
to True
, keywords also cannot be reused. override
is specially useful to
define your own help
command, in case you don't like the default one.
@bot.on_command('command', 'alias1', 'alias2')
def on_command():
...
@bot.on_command('help', 'h', override=True)
def custom_on_help():
...
Defining A Command Handler
Command handlers can have any number of arguments. Arguments are defined as each word that follows the command keyword in the message received, separated by spaces. If the handler defines no arguments, everything after the keyword is ignored. Example:
@bot.on_command('command')
def on_command(arg1, arg2):
# user invokes "!command abc 123"
# arg1 = 'abc', arg2 = '123'
In case the command is invoked with more arguments than defined, all exceeding words are grouped as the last argument.
In case arguments received are less than expected, and optional_args
is True
(default value),
missing arguments are received as empty (''
or 0
for numeric arguments, as explained later).
If optional_args
is set to False
, InvalidCommandArgumentsError
exception is raised,
and the on_invalid_arguments()
special handler is called instead, which is explained further on.
Examples:
@bot.on_command('command')
def on_command(arg1, arg2, multi_word_arg):
# user invokes "!command arg1"
# arg1 = 'arg1', other args equal to ''
#
# user invokes "!command 1 2 3 4 5 6"
# arg1 = '1', arg2 = '2', and multi_word_arg = '3 4 5 6'
@bot.on_other_command('othercommand', optional_args=False)
def on_other_command(arg1, arg2):
# user invokes "!othercommand"
# `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead
Typed Arguments
Arguments can be set to expect specific types using annotations,
specially useful when you want an argument to be an int
or float
(arguments are str
by default).
If the command is invoked using arguments of wrong type, InvalidCommandArgumentsError
is raised and
on_invalid_arguments()
is called.
The Optional
annotation from the typing
package can be used in conjunction with optional_args
to
selectively enforce certain arguments. Default values can also be set as you'd expect.
Examples:
@bot.on_command('typedcommand')
def typed_command(str_arg, int_arg: int, float_arg: float):
# user invokes "!typedcommand 123 123 123.0"
# str_arg = '123', int_arg = 123, and float_arg = 123.0
#
# user invokes "!typedcommand a b c"
# `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead
from typing import Optional
@bot.on_command('optionalcommand', optional_args=False)
def optional_command(required, optional: Optional[int] = 5):
# user invoked "!optionalcommand abc 123
# required = 'abc', optional = 123
#
# user invoked "!optionalcommand abc
# required = 'abc', optional = 5 (would be 0 if no default were set)
#
# user invoked "!optionalcommand
# `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead
The raw message received can also be retrieved by annotating the last argument with the
Message
type. This message will be of type Whisper
as defined in the
dgg-chat
package.
The available attributes are:
user
: Of typeChatUser
, contains the user'snick
and their chatfeatures
.message_id
: Message id as defined in the chat backend, rarely useful.timestamp
: Unix timestamp for when the message was sent.content
: The raw message content the user originally sent.
Example:
from dgg_chat_bot import Message
@bot.on_command('command')
def command(arg1, arg2, message: Message):
print(message.user.nick)
Obs.: If used, the Message
argument HAS to be set as the last one.
Command Description
One other very important aspect of implementing a command handler is the description.
The default help
command implementation uses it to describe to the user what the
command does and how it's supposed to be used, so don't forget to write it!
To do so, use the standard way of documenting functions, the docstrings.
Example:
@bot.on_command('hello')
def say_hello(message: Message):
"""
Replies hello to you!
Example: "!hello".
"""
bot.reply(f"Hi {message.user.nick}!")
Try to keep the description below 400 characters, since by default it is sent in one message along with other information, and messages have a size limit of 512 characters.
Special Handlers
There are a few special scenarios worth mentioning:
- The
help
command. - A command with invalid arguments was invoked.
- An unknown command was invoked.
- A message which didn't start with the command prefix ("!" by default) was received.
- An unhandled exception was raised while processing the command.
All of them have default implementations (which can be reviewed here), so implementing them is not necessary.
As described before, use the override
option of the on_command()
decorator to
implement a custom help
command.
As for the other handlers, use the respective decorators: on_invalid_arguments()
,
on_unknown_command()
, on_generic_message()
, and on_fail()
.
Also, you can user the before_every_command()
and after_every_command()
to define handlers that
are called before and after every command. The expected signature for these functions
can be seen in the example.py
file.
Replying To Messages
As shown in the previous examples, the reply()
function can be used to reply to the user who sent
the command being processed. There's also reply_multine()
, which does what the name suggests.
Expect a small delay (~200-500 ms) between messages, since they'd get throttled otherwise.
Replying will be disabled by default. Follow down the source code to figure out how to enable it. This is just to make sure you know what you're doing before allowing message sending.
Authentication
Check the authentication section in the dgg-chat
package description.
Extra Features
This framework being built on top of the dgg-chat
package, its functionality is exposed through the chat
attribute of the DGGChatBot
class. So you can also use decorators to handle different events in chat,
like with chat.on_chat_message()
and chat.on_user_joined()
.
The chat.send_whisper()
method is also available, which is specially useful when you need
to send a whisper not as an immediate reply (e.g.: a command that does something for a longer
amount of time and sends a message when it is done).
For more details, go check out the dgg-chat
documentation.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file dgg-chat-bot-0.1.10a0.tar.gz
.
File metadata
- Download URL: dgg-chat-bot-0.1.10a0.tar.gz
- Upload date:
- Size: 13.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0579485bc656bc66fd9ca41693913af15f961a3461de9b99514ff486f50eaa68 |
|
MD5 | d38b102cbb55e49261d2e188364b8671 |
|
BLAKE2b-256 | b3130db798d4ef710b11325828d33adf50301424e39b142d6e5c23e8354e2f9f |
File details
Details for the file dgg_chat_bot-0.1.10a0-py3-none-any.whl
.
File metadata
- Download URL: dgg_chat_bot-0.1.10a0-py3-none-any.whl
- Upload date:
- Size: 11.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ad84211b00cc750f060935730e66894f58de912cb8c5023efadd415de8d0d821 |
|
MD5 | ccaa8d1d11009ec58b5a03586e94673c |
|
BLAKE2b-256 | 2b8c38485e452c214899df7c18d91059920ea59f10018986f00491ab4b6c91c7 |