{"id":16865897,"url":"https://github.com/gabrieljablonski/dgg-chat-bot","last_synced_at":"2025-07-29T16:34:56.601Z","repository":{"id":37646220,"uuid":"273186846","full_name":"gabrieljablonski/dgg-chat-bot","owner":"gabrieljablonski","description":"Build chat bots for the destiny.gg chat","archived":false,"fork":false,"pushed_at":"2022-06-22T02:21:56.000Z","size":127,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-12T17:07:00.298Z","etag":null,"topics":["chat-bot","chat-bots","chatbot-framework","chatbots-framework","destinygg","dgg"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrieljablonski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-18T08:44:19.000Z","updated_at":"2021-03-02T15:51:25.000Z","dependencies_parsed_at":"2022-09-04T20:10:23.616Z","dependency_job_id":null,"html_url":"https://github.com/gabrieljablonski/dgg-chat-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gabrieljablonski/dgg-chat-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieljablonski%2Fdgg-chat-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieljablonski%2Fdgg-chat-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieljablonski%2Fdgg-chat-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieljablonski%2Fdgg-chat-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrieljablonski","download_url":"https://codeload.github.com/gabrieljablonski/dgg-chat-bot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieljablonski%2Fdgg-chat-bot/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265075267,"owners_count":23707474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat-bot","chat-bots","chatbot-framework","chatbots-framework","destinygg","dgg"],"created_at":"2024-10-13T14:48:46.998Z","updated_at":"2025-07-29T16:34:56.511Z","avatar_url":"https://github.com/gabrieljablonski.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DEPRECATED :(\n\n# DGG Chat Bot\n\nA framework for building chat bots for the [destiny.gg](https://destiny.gg) chat. It allows you to register \ncommands for when a user whispers you, so you can then reply with something useful.\nBuilt with the [`dgg-chat`](https://github.com/gabrieljablonski/dgg-chat) package.\n\nIn case you want a more in-depth example, check out the [remind me bot](https://github.com/gabrieljablonski/dgg-remind-me).\n\n## Installing\n\nThis package is available via pip (requires python 3.8).\n\n```sh\npip install dgg-chat-bot\n```\n\nA (very) minimal working example (more details below):\n\n```python\nfrom dgg_chat_bot import DGGChatBot\n\nbot = DGGChatBot(\"\u003cdgg auth token\u003e\")\n\n@bot.on_command('helloworld')\ndef hello_world():\n    bot.reply('Hello World!')\n\nbot.run_forever()\n```\n\n## How To Use\n\nThe `DGGChatBot` class runs the main event loop. It parses messages users sent to you for a command \nand invokes any functions registered. Registering a function to a command can be done with the \n`DGGChatBot().on_command()` decorator.\n\nAs it is with the `dgg-chat` package, all handlers are called synchronously, that is, a handler \nwill only be called after the previous one finished its work. If you want to do time intensive tasks,\nthe asynchronous aspect has to be done manually. Native asynchronous support might be implemented in the future.\n\nA more complete example can be found in the [`example.py`](./example.py) file.\n\n## Registering Commands\n\nWhen using the `on_command()` decorator, the first argument will be the keyword associated with \nthat command, followed by any number of aliases. There's also `override` and `optional_args`, \narguments explained later on.\n\nIt is enforced that the same alias cannot be used for multiple commands. Unless you set \n`override` to `True`, keywords also cannot be reused. `override` is specially useful to \ndefine your own `help` command, in case you don't like the [default one](./dgg_chat_bot/_dgg_chat_bot.py#L61).\n\n```python\n@bot.on_command('command', 'alias1', 'alias2')\ndef on_command():\n    ...\n\n@bot.on_command('help', 'h', override=True)\ndef custom_on_help():\n    ...\n```\n\n### Defining A Command Handler\n\nCommand handlers can have any number of arguments. Arguments are defined as each\nword that follows the command keyword in the message received, separated by spaces.\nIf the handler defines no arguments, everything after the keyword is ignored.\nExample:\n\n```python\n@bot.on_command('command')\ndef on_command(arg1, arg2):\n    # user invokes \"!command abc 123\"\n    # arg1 = 'abc', arg2 = '123'\n```\n\nIn case the command is invoked with more arguments than defined, all exceeding words are grouped as the last argument. \n\nIf `optional_args` is set to `False` (default value), `InvalidCommandArgumentsError` exception is raised, \nand the `on_invalid_arguments()` special handler is called instead, which is explained further on. \n\nIn case arguments received are less than expected, and `optional_args` is `True`, missing arguments are \nreceived as empty value (`''` or `0` for numeric arguments, as explained later). \n\nExamples:\n\n```python\n@bot.on_command('command', optional_args=True)\ndef on_command(arg1, arg2, multi_word_arg):\n    # user invokes \"!command arg1\"\n    # arg1 = 'arg1', other args equal to ''\n    #\n    # user invokes \"!command 1 2 3 4 5 6\"\n    # arg1 = '1', arg2 = '2', and multi_word_arg = '3 4 5 6'\n\n@bot.on_other_command('othercommand')\ndef on_other_command(arg1, arg2):\n    # user invokes \"!othercommand\"\n    # `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead\n```\n\n#### Typed Arguments\n\nArguments can be set to expect specific types using [annotations](https://realpython.com/lessons/annotations/), \nspecially useful when you want an argument to be an `int` or `float` (arguments are `str` by default). \n\nIf the command is invoked using arguments of wrong type, `InvalidCommandArgumentsError` is raised and \n`on_invalid_arguments()` is called. \n\nThe `Optional` annotation from the `typing` package can be used to selectively enforce certain arguments,\ninstead of all of them being either optional or not when using `optional_args`. \nDefault values can also be set as you'd expect.\n\nExamples:\n\n```python\n@bot.on_command('typedcommand')\ndef typed_command(str_arg, int_arg: int, float_arg: float):\n    # user invokes \"!typedcommand 123 123 123.0\"\n    # str_arg = '123', int_arg = 123, and float_arg = 123.0\n    #\n    # user invokes \"!typedcommand a b c\"\n    # `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead\n\nfrom typing import Optional\n\n@bot.on_command('optionalcommand')\ndef optional_command(required, optional: Optional[int] = 5):\n    # user invoked \"!optionalcommand abc 123\"\n    # required = 'abc', optional = 123\n    #\n    # user invoked \"!optionalcommand abc\n    # required = 'abc', optional = 5 (would be 0 if no default were set)\n    #\n    # user invoked \"!optionalcommand\n    # `InvalidCommandArgumentsError` is raised, and `on_invalid_arguments()` is called instead\n```\n\nThe raw message received can also be retrieved by annotating the last argument with the\n`Message` type. This message will be of type `Whisper` as defined in the \n[`dgg-chat`](https://github.com/gabrieljablonski/dgg-chat/blob/master/dgg_chat/messages/_messages.py#L100) package.\nThe available attributes are: \n - `user`: Of type [`ChatUser`](https://github.com/gabrieljablonski/dgg-chat/blob/master/dgg_chat/messages/_messages.py#L6), contains the user's `nick` and their chat `features`.\n - `message_id`: Message id as defined in the chat backend, rarely useful.\n - `timestamp`: Unix timestamp for when the message was sent.\n - `content`: The raw message content the user originally sent.\n\nExample:\n\n```python\nfrom dgg_chat_bot import Message\n\n@bot.on_command('command')\ndef command(arg1, arg2, message: Message):\n    print(message.user.nick)\n```\n\n**Obs.: If used, the `Message` argument HAS to be set as the last one.**\n\n#### Command Description\n\nOne other very important aspect of implementing a command handler is the description.\nThe default `help` command implementation uses it to describe to the user what the\ncommand does and how it's supposed to be used, so don't forget to write it!\nTo do so, use the standard way of documenting functions, the [docstrings](https://www.programiz.com/python-programming/docstrings).\nExample:\n\n```python\n@bot.on_command('hello')\ndef say_hello(message: Message):\n    \"\"\"\n    Replies hello to you!\n    Example: \"!hello\".\n    \"\"\"\n    bot.reply(f\"Hi {message.user.nick}!\")\n```\n\nTry to keep the description below 400 characters, since by default it is sent in one \nmessage along with other information, and messages have a size limit of 512 characters.\n\n## Special Handlers\n\nThere are a few special scenarios worth mentioning:\n\n - The `help` command.\n - A command with invalid arguments was invoked.\n - An unknown command was invoked.\n - A message which didn't start with the command prefix (\"!\" by default) was received.\n - An unhandled exception was raised while processing the command.\n\nAll of them have default implementations ([which can be reviewed here](./dgg_chat_bot/_dgg_chat_bot.py#L61)), \nso implementing them is not necessary.\n\nAs [described before](#registering-commands), use the `override` option of the `on_command()` decorator to \nimplement a custom `help` command. \n\nAs for the other handlers, use the respective decorators: `on_invalid_arguments()`,\n`on_unknown_command()`, `on_generic_message()`, and `on_fail()`.\n\nAlso, you can user the `before_every_command()` and `after_every_command()` to define handlers that\nare called before and after every command. The expected signature for these functions\ncan be seen in the [`example.py`](./example.py#L133) file.\n\n## Replying To Messages\n\nAs shown in the previous examples, the `reply()` function can be used to reply to the user who sent\nthe command being processed. There's also `reply_multine()`, which does what the name suggests.\nExpect a small delay (~200-500 ms) between messages, since they'd get throttled otherwise.\n\nReplying will be disabled by default. Follow down the source code to figure out how to enable it.\nThis is just to make sure you know what you're doing before allowing message sending.\n\n## Authentication\n\nCheck the [authentication section](https://github.com/gabrieljablonski/dgg-chat#authentication) in the `dgg-chat` package description.\n\n## Extra Features\n\nAs this framework is built on top of the `dgg-chat` package, features are exposed through the `chat`\nattribute of the `DGGChatBot` class. So you can also use decorators to handle different events in chat,\nlike with `chat.on_chat_message()` and `chat.on_user_joined()`.\n\nThe `chat.send_whisper()` method is also available, which is specially useful when you need\nto send a whisper not as an immediate reply (e.g.: a command that does something for a longer \namount of time and sends a message when it is done).\n\nFor more details, go check out the [`dgg-chat` documentation](https://github.com/gabrieljablonski/dgg-chat).\n\n## TODO\n\n- Support regex for raising invalid args error automatically.\n- Maybe use `multiprocessing` instead of `threading` for message sending?\n- Improve the way **business logic** error messages are handled (maybe include message associated with it, if any?).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieljablonski%2Fdgg-chat-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrieljablonski%2Fdgg-chat-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieljablonski%2Fdgg-chat-bot/lists"}