diff --git a/nephthys/macros/__init__.py b/nephthys/macros/__init__.py index cf29295..e96859e 100644 --- a/nephthys/macros/__init__.py +++ b/nephthys/macros/__init__.py @@ -8,6 +8,7 @@ from nephthys.macros.reopen import Reopen from nephthys.macros.resolve import Resolve from nephthys.macros.shipcertqueue import ShipCertQueue from nephthys.macros.thread import Thread +from nephthys.macros.types import Macro from nephthys.utils.env import env from nephthys.utils.logging import send_heartbeat from prisma.enums import TicketStatus @@ -15,7 +16,18 @@ from prisma.models import Ticket from prisma.models import User -macros = [Resolve, HelloWorld, FAQ, Identity, Fraud, ShipCertQueue, Thread, Reopen] +macro_list: list[type[Macro]] = [ + Resolve, + HelloWorld, + FAQ, + Identity, + Fraud, + ShipCertQueue, + Thread, + Reopen, +] + +macros = [macro() for macro in macro_list] async def run_macro( @@ -24,18 +36,29 @@ async def run_macro( """ Run the macro with the given name and arguments. """ + + async def error_msg(msg: str): + return await env.slack_client.chat_postEphemeral( + channel=env.slack_help_channel, + thread_ts=ticket.msgTs, + user=helper.slackId, + text=msg, + ) + for macro in macros: - if macro.name == name: + if name in macro.all_aliases(): if not macro.can_run_on_closed and ticket.status == TicketStatus.CLOSED: + await error_msg(f"`?{name}` cannot be run on a closed ticket.") return False new_kwargs = kwargs.copy() new_kwargs["text"] = text - await macro().run(ticket, helper, **new_kwargs) + await macro.run(ticket, helper, **new_kwargs) await env.slack_client.chat_delete( channel=env.slack_help_channel, ts=macro_ts, token=env.slack_user_token ) return True + await error_msg(f"`?{name}` is not a valid macro.") await send_heartbeat( f"Macro {name} not found from <@{helper.slackId}>.", messages=[f"Ticket ID: {ticket.id}", f"Helper ID: {helper.id}"], diff --git a/nephthys/macros/reopen.py b/nephthys/macros/reopen.py index d0dc790..397bd18 100644 --- a/nephthys/macros/reopen.py +++ b/nephthys/macros/reopen.py @@ -12,6 +12,7 @@ from prisma.enums import TicketStatus class Reopen(Macro): name = "reopen" + aliases = ["unresolve", "open"] can_run_on_closed = True async def run(self, ticket, helper, **kwargs): diff --git a/nephthys/macros/resolve.py b/nephthys/macros/resolve.py index f1552ab..2277de9 100644 --- a/nephthys/macros/resolve.py +++ b/nephthys/macros/resolve.py @@ -9,6 +9,7 @@ from prisma.models import User class Resolve(Macro): name = "resolve" + aliases = ["close"] async def run(self, ticket: Ticket, helper: User, **kwargs) -> None: """ diff --git a/nephthys/macros/thread.py b/nephthys/macros/thread.py index 986e6aa..7a65f6e 100644 --- a/nephthys/macros/thread.py +++ b/nephthys/macros/thread.py @@ -1,11 +1,15 @@ +from slack_sdk.errors import SlackApiError + from nephthys.actions.resolve import resolve from nephthys.macros.types import Macro from nephthys.utils.env import env from nephthys.utils.ticket_methods import delete_bot_replies +from prisma.enums import TicketStatus class Thread(Macro): name = "thread" + can_run_on_closed = True async def run(self, ticket, helper, **kwargs): """ @@ -19,10 +23,25 @@ class Thread(Macro): # Deletes the first (FAQ) message sent by the bot await delete_bot_replies(ticket.id) - await resolve( - ts=ticket.msgTs, - resolver=helper.slackId, - client=env.slack_client, - add_reaction=False, - send_resolved_message=False, - ) + if ticket.status != TicketStatus.CLOSED: + await resolve( + ts=ticket.msgTs, + resolver=helper.slackId, + client=env.slack_client, + add_reaction=False, + send_resolved_message=False, + ) + return + + # If the ticket was already closed, now we just need to remove any reactions + try: + reactions = ["thinking_face", "white_check_mark"] + for reaction in reactions: + await env.slack_client.reactions_remove( + channel=env.slack_help_channel, + timestamp=ticket.msgTs, + name=reaction, + ) + except SlackApiError as e: + if e.response["error"] != "no_reaction": + raise e diff --git a/nephthys/macros/types.py b/nephthys/macros/types.py index 54b36fd..05b5362 100644 --- a/nephthys/macros/types.py +++ b/nephthys/macros/types.py @@ -4,6 +4,7 @@ from prisma.models import User class Macro: name: str + aliases: list[str] = [] can_run_on_closed: bool = False async def run(self, ticket: Ticket, helper: User, **kwargs) -> None: @@ -11,3 +12,9 @@ class Macro: Run the macro with the given arguments. """ raise NotImplementedError("Subclasses must implement this method.") + + def all_aliases(self) -> set[str]: + """ + Get all names for this macro, including aliases. + """ + return set([self.name] + self.aliases)