/
carebot.py
95 lines (80 loc) · 2.71 KB
/
carebot.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
import importlib
import logging
import re
from slackbot.bot import Bot
from slackbot.bot import respond_to
from slackbot.bot import listen_to
import sys
import app_config
from util.slack import SlackTools
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
slack_tools = SlackTools()
"""
Go through the plugins and add any listeners we need
"""
listeners = []
plugins = [getattr(importlib.import_module(mod), cls) for (mod, cls) in (plugin.rsplit(".", 1) for plugin in app_config.CAREBOT_PLUGINS)]
for plugin in plugins:
plugin = plugin()
try:
listeners.extend(plugin.get_listeners())
except NotImplementedError:
pass
@respond_to('.*', re.IGNORECASE)
def response_dispatcher(message, text=None):
"""
We start out responding to everything -- there doesn't seem to be a way for a
more specific regex to take precedence over the generic case.
"""
if not text:
text = message.body['text']
any_match = False
for listener in listeners:
match = listener[1].findall(text)
if match:
logger.info("Recognized message: %s", message.body['text'])
logger.info("Dispatching to message: %s", listener[0])
any_match = True
# Some listeners have a first message that says "hold tight, stats
# are coming soon":
try:
slack_tools.send_message(
message.body['channel'],
listener[3](),
None,
unfurl_links=False,
)
except:
pass
# Get the reply
reply = listener[2](message)
if reply:
slack_tools.send_message(
message.body['channel'],
reply['text'],
reply.get('attachments', None),
unfurl_links=False,
)
if not any_match:
logger.info("Did not recognize message: {0}".format(message.body['text']))
message.reply("Hi! I got your message, but I don't know enough yet to respond to it.")
@listen_to('^@*[Cc]arebot[:|,]\s*(.*)', re.IGNORECASE)
def reply(message, text):
"""
Listen passively for any mention of Carebot: at the beginning of the line
If we don't listen to this generic message, users would have to use exact
syntax to get a response out of carebot.
"""
response_dispatcher(message, text)
def main():
bot = Bot()
print "Carebot is running. Invite it to a channel to begin."
bot.run()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print "Thanks for caring! See you next time."
sys.exit()