Improvements to macros (#123)

* Attempts at getting macro aliases to work

* Store instances of macros as well as just the classes

* Add ?unresolve and ?open aliases for ?reopen

* Add an error message for invalid macros

* Add ?close as an alias for ?resolve

* Add error message for running a macro on a closed ticket

* Allow ?thread to be run on closed tickets

* Add type annotation to macro list
This commit is contained in:
Mish 2025-11-29 11:22:08 +00:00 committed by GitHub
parent be77c20a18
commit 2fc6a90a4d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 61 additions and 10 deletions

View file

@ -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}"],

View file

@ -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):

View file

@ -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:
"""

View file

@ -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

View file

@ -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)