Package: dgg-chat-bot
DGG Chat BotA framework for building chat bots for thedestiny.ggchat. It allows you to register
commands for when a user whispers you, so you can then reply with something useful.
Built with thedgg-chatpackage.In case you want a more in-depth example, check out theremind me bot.InstallingThis package is available via pip!pipinstalldgg-chat-botA (very) minimal working example (more details below):fromdgg_chat_botimportDGGChatBotbot=DGGChatBot("<dgg auth token>")@bot.on_command('helloworld')defhello_world():bot.reply('Hello World!')bot.run_forever()How To UseTheDGGChatBotclass 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 theDGGChatBot().on_command()decorator.As it is with thedgg-chatpackage, 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 theexample.pyfile.Registering CommandsWhen using theon_command()decorator, the first argument will be the keyword associated with
that command, followed by any number of aliases. There's alsooverrideandoptional_args,
arguments explained later on.It is enforced that the same alias cannot be used for multiple commands. Unless you setoverridetoTrue, keywords also cannot be reused.overrideis specially useful to
define your ownhelpcommand, in case you don't like thedefault one.@bot.on_command('command','alias1','alias2')defon_command():...@bot.on_command('help','h',override=True)defcustom_on_help():...Defining A Command HandlerCommand 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')defon_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, andoptional_argsisTrue(default value),
missing arguments are received as empty (''or0for numeric arguments, as explained later).Ifoptional_argsis set toFalse,InvalidCommandArgumentsErrorexception is raised,
and theon_invalid_arguments()special handler is called instead, which is explained further on.Examples:@bot.on_command('command')defon_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)defon_other_command(arg1,arg2):# user invokes "!othercommand"# `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called insteadTyped ArgumentsArguments can be set to expect specific types usingannotations,
specially useful when you want an argument to be anintorfloat(arguments arestrby default).If the command is invoked using arguments of wrong type,InvalidCommandArgumentsErroris raised andon_invalid_arguments()is called.TheOptionalannotation from thetypingpackage can be used in conjunction withoptional_argsto
selectively enforce certain arguments. Default values can also be set as you'd expect.Examples:@bot.on_command('typedcommand')deftyped_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 insteadfromtypingimportOptional@bot.on_command('optionalcommand',optional_args=False)defoptional_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 insteadThe raw message received can also be retrieved by annotating the last argument with theMessagetype. This message will be of typeWhisperas defined in thedgg-chatpackage.
The available attributes are:user: Of typeChatUser, contains the user'snickand 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:fromdgg_chat_botimportMessage@bot.on_command('command')defcommand(arg1,arg2,message:Message):print(message.user.nick)Obs.: If used, theMessageargument HAS to be set as the last one.Command DescriptionOne other very important aspect of implementing a command handler is the description.
The defaulthelpcommand 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, thedocstrings.
Example:@bot.on_command('hello')defsay_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 HandlersThere are a few special scenarios worth mentioning:Thehelpcommand.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.Asdescribed before, use theoverrideoption of theon_command()decorator to
implement a customhelpcommand.As for the other handlers, use the respective decorators:on_invalid_arguments(),on_unknown_command(),on_generic_message(), andon_fail().Also, you can user thebefore_every_command()andafter_every_command()to define handlers that
are called before and after every command. The expected signature for these functions
can be seen in theexample.pyfile.Replying To MessagesAs shown in the previous examples, thereply()function can be used to reply to the user who sent
the command being processed. There's alsoreply_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.AuthenticationCheck theauthentication sectionin thedgg-chatpackage description.Extra FeaturesThis framework being built on top of thedgg-chatpackage, its functionality is exposed through thechatattribute of theDGGChatBotclass. So you can also use decorators to handle different events in chat,
like withchat.on_chat_message()andchat.on_user_joined().Thechat.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 thedgg-chatdocumentation.