-
Notifications
You must be signed in to change notification settings - Fork 0
/
_dgg_chat_bot.py
183 lines (145 loc) · 6.04 KB
/
_dgg_chat_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import logging
from time import sleep
from dgg_chat import DGGChat
from .exceptions import InvalidMessageError, AnonymousConnectionError
from ._commands import Commands, Message, Whisper
from ._utils import parametrized_decorator_method, enclose
class DGGChatBot:
def __init__(self, auth_token=None, command_prefix='!', extra_help='', greeting=''):
"""
Parameters
----------
`auth_token` : `str`
an authentication token for a dgg account.
can be created at `https://www.destiny.gg/profile/developer`.
`command_prefix` : `str`
the character sequence at the start of a message
to indicate it's a command.
`"!"` by default.
`extra_help` : `str`
extra details to be put at the end of the default help function reply.
`greeting` : `str`
the reply sent back when using the default `on_generic_message()` handler.
use `{user}` inside the string to reference the user's nick.
a reference to the `help` command is added at the end by default.
"""
self._auth_token = auth_token
self.command_prefix = command_prefix
self.extra_help = extra_help
self._last_whisper_received = None
self.greeting = greeting or "Hey, {user}! I'm a bot 🤖 *beep* *boop*."
self._commands = Commands(command_prefix)
self._chat = DGGChat(auth_token)
self._setup_default_commands()
self._setup_chat_handlers()
@property
def auth_token(self):
return self._auth_token
@property
def commands(self):
return self._commands
@property
def chat(self):
return self._chat
def _setup_default_commands(self):
@self.on_command('help', 'h', 'commands', optional_args=True)
def on_help(cmd):
"""documentation set below"""
if cmd:
if not (command := self._commands.get_root(cmd)):
return self.reply('The command `{cmd}` was not found.')
aliases = ', '.join(enclose(command.aliases, '"')) or 'none'
desc = command.handler.description
msg = f'"{self.command_prefix}{command.keyword}" (aliases: {aliases}) -> {desc}'
return self.reply(msg)
commands = ', '.join(enclose(self._commands.all_aliases, '"'))
if not commands:
msg = 'No commands are available ☹.'
return self.reply(msg)
msg = f'Available commands: {commands}. For more info about a specific command, try "{self.command_prefix}help <command>". {self.extra_help}'
return self.reply(msg)
# setting manually since formatting is needed
on_help.__doc__ = f"""
"!help [<command>]".
The command you're using!
Use it to get info about available commands.
Examples: "{self.command_prefix}help", "{self.command_prefix}help <command>".
"""
@self.on_unknown_command
def on_unknown_command(command):
msg = f"""Sorry, I don't know that one 🤔. Try "{self.command_prefix}help"."""
self.reply(msg)
@self.on_regular_message
def on_regular_message(message: Message):
msg = f'{self.greeting.format(user=message.user.nick)} To check everything I can do, try "{self.command_prefix}help".'
self.reply(msg)
@self.on_invalid_arguments
def on_invalid_arguments(command, error_message=''):
keyword = command.keyword
error_message = f" Error message: {error_message}." if error_message else ''
msg = f"""I don't think this you how you use that 🤔.{error_message} Try "{self.command_prefix}help {keyword}" for more info."""
self.reply(msg)
@self.on_fail
def on_fail(command, error_message=''):
error_message = f" Error message: {error_message}." if error_message else ''
msg = f"""Something went wrong while processing your command.{error_message}"""
self.reply(msg)
def _setup_chat_handlers(self):
# @self._chat.on_chat_message
@self._chat.on_whisper
def on_whisper(whisper: Whisper):
self._last_whisper_received = whisper
self._commands.handle(whisper)
def connect(self):
self._chat.connect()
def disconnect(self):
self._chat.disconnect()
def run_forever(self):
self._chat.run_forever()
def on_regular_message(self, f):
self._commands.on_regular_message = f
return f
def on_unknown_command(self, f):
self._commands.on_unknown_command = f
return f
def on_invalid_arguments(self, f):
self._commands.on_invalid_arguments = f
return f
def on_fail(self, f):
self._commands.on_fail = f
return f
def before_every_command(self, f):
return self._commands.add_before_every_command(f)
def after_every_command(self, f):
return self._commands.add_after_every_command(f)
@parametrized_decorator_method
def on_command(
self, f, keyword, *aliases,
override=False,
optional_args=False,
):
if not self._auth_token:
raise AnonymousConnectionError(
'setting command handlers is not very useful without a connection'
)
self._commands.add(
f, keyword, *aliases,
override=override,
optional_args=optional_args
)
return f
def reply_multiline(self, messages):
"""
Replies to the last whisper received with multiple messages.
Use sparingly, since you're likely to get throttled.
"""
for m in messages:
self.reply(m)
def reply(self, message):
"""
Replies to the last whisper received.
"""
if not self._chat.message_is_valid(message):
raise InvalidMessageError(message)
user = self._last_whisper_received.user.nick
self._chat.send_whisper(user, message)