Skip to content

Commit 41e2b53

Browse files
authored
Merge pull request #38 from surface-security/add_interactive_messages_support
Add interactive message support
2 parents b40dc58 + 49dfbe6 commit 41e2b53

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

slackbot/base.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def __init__(self, rtm_client, web_client) -> None:
1414
self.client = rtm_client
1515
self.web = web_client
1616
self.user_id = self.web.auth_test()["user_id"]
17+
self.priority = 10
1718

1819
@staticmethod
1920
def user_has_perm(user, perm):
@@ -70,6 +71,13 @@ def handle(self, message, user=None, channel=None, ts=None, raw=None) -> Optiona
7071
"""
7172
raise NotImplementedError("abstract method")
7273

74+
def process_interactive(self, **payload):
75+
return self.handle_interactive(**payload)
76+
77+
def handle_interactive(self, **payload) -> Optional[Union[int, tuple[int, int]]]:
78+
# This method is currently a placeholder.
79+
pass
80+
7381

7482
class NoMatchSlackCommand(Exception):
7583
pass

slackbot/management/commands/run_bot.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ def handle_message(self, **payload):
4040
close_old_connections()
4141
self.handle_message_really(**payload)
4242

43+
def handle_interactive(self, **payload):
44+
processed_at_least_one = False
45+
for p in self.processors:
46+
try:
47+
r = p.process_interactive(**payload)
48+
if r:
49+
if not isinstance(r, tuple):
50+
r = (r,)
51+
if MessageProcessor.PROCESSED in r:
52+
processed_at_least_one = True
53+
if MessageProcessor.STOP in r:
54+
break
55+
except Exception as e:
56+
self.log_exception("Processor failed for interactive event: %s %s", payload, str(e))
57+
return processed_at_least_one
58+
4359
def handle_reaction(self, **payload):
4460
event = payload.get("event", {})
4561
processed_at_least_one = False
@@ -125,6 +141,7 @@ def set_up(self, **payload):
125141
self.my_name = data.get("user")
126142

127143
self.processors = [x(self.client, self.web) for x in MessageProcessor.__subclasses__()]
144+
self.processors.sort(key=lambda x: x.priority)
128145
self.stdout.write(f"Connected as {self.my_name}")
129146
self.stdout.write(
130147
f"Processors: {','.join(f'{x.__class__.__module__}.{x.__class__.__name__}' for x in self.processors)}"
@@ -147,6 +164,10 @@ def process_reaction(self, client: SocketModeClient, req: SocketModeRequest):
147164
event = req.payload["event"]
148165
if event["type"] in ("reaction_added", "reaction_removed"):
149166
return self.handle_reaction(**req.payload)
167+
168+
def process_interactive(self, client: SocketModeClient, req: SocketModeRequest):
169+
if req.type == "interactive":
170+
return self.handle_interactive(**req.payload)
150171

151172
def handle(self, *args, **options):
152173
# faster cold boot
@@ -161,6 +182,7 @@ def handle(self, *args, **options):
161182
self.set_up()
162183
self.client.socket_mode_request_listeners.append(self.process)
163184
self.client.socket_mode_request_listeners.append(self.process_reaction)
185+
self.client.socket_mode_request_listeners.append(self.process_interactive)
164186
self.stdout.write("Connecting...\n")
165187
self.client.connect()
166188

0 commit comments

Comments
 (0)