diff --git a/slackbot/base.py b/slackbot/base.py index 2c6a72f..c9f1045 100644 --- a/slackbot/base.py +++ b/slackbot/base.py @@ -14,6 +14,7 @@ def __init__(self, rtm_client, web_client) -> None: self.client = rtm_client self.web = web_client self.user_id = self.web.auth_test()["user_id"] + self.priority = 10 @staticmethod def user_has_perm(user, perm): @@ -70,6 +71,13 @@ def handle(self, message, user=None, channel=None, ts=None, raw=None) -> Optiona """ raise NotImplementedError("abstract method") + def process_interactive(self, **payload): + return self.handle_interactive(**payload) + + def handle_interactive(self, **payload) -> Optional[Union[int, tuple[int, int]]]: + # This method is currently a placeholder. + pass + class NoMatchSlackCommand(Exception): pass diff --git a/slackbot/management/commands/run_bot.py b/slackbot/management/commands/run_bot.py index c0d569a..20c455f 100644 --- a/slackbot/management/commands/run_bot.py +++ b/slackbot/management/commands/run_bot.py @@ -40,6 +40,22 @@ def handle_message(self, **payload): close_old_connections() self.handle_message_really(**payload) + def handle_interactive(self, **payload): + processed_at_least_one = False + for p in self.processors: + try: + r = p.process_interactive(**payload) + if r: + if not isinstance(r, tuple): + r = (r,) + if MessageProcessor.PROCESSED in r: + processed_at_least_one = True + if MessageProcessor.STOP in r: + break + except Exception as e: + self.log_exception("Processor failed for interactive event: %s %s", payload, str(e)) + return processed_at_least_one + def handle_reaction(self, **payload): event = payload.get("event", {}) processed_at_least_one = False @@ -125,6 +141,7 @@ def set_up(self, **payload): self.my_name = data.get("user") self.processors = [x(self.client, self.web) for x in MessageProcessor.__subclasses__()] + self.processors.sort(key=lambda x: x.priority) self.stdout.write(f"Connected as {self.my_name}") self.stdout.write( 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): event = req.payload["event"] if event["type"] in ("reaction_added", "reaction_removed"): return self.handle_reaction(**req.payload) + + def process_interactive(self, client: SocketModeClient, req: SocketModeRequest): + if req.type == "interactive": + return self.handle_interactive(**req.payload) def handle(self, *args, **options): # faster cold boot @@ -161,6 +182,7 @@ def handle(self, *args, **options): self.set_up() self.client.socket_mode_request_listeners.append(self.process) self.client.socket_mode_request_listeners.append(self.process_reaction) + self.client.socket_mode_request_listeners.append(self.process_interactive) self.stdout.write("Connecting...\n") self.client.connect()