Skip to content

Commit

Permalink
feat(slack/case): allow page command in dedicated case channels
Browse files Browse the repository at this point in the history
  • Loading branch information
whitdog47 committed Feb 17, 2025
1 parent d7169f8 commit da320ca
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 12 deletions.
82 changes: 82 additions & 0 deletions src/dispatch/case/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from dispatch.incident.models import Incident, IncidentCreate
from dispatch.incident.priority.models import IncidentPriority
from dispatch.incident.type.models import IncidentType
from dispatch.individual import service as individual_service
from dispatch.individual.models import IndividualContactRead
from dispatch.models import OrganizationSlug, PrimaryKey
from dispatch.participant import flows as participant_flows
Expand All @@ -31,6 +32,7 @@
from dispatch.participant_role import flows as role_flow
from dispatch.participant_role.models import ParticipantRole, ParticipantRoleType
from dispatch.plugin import service as plugin_service
from dispatch.service import service as service_service
from dispatch.storage import flows as storage_flows
from dispatch.storage.enums import StorageAction
from dispatch.ticket import flows as ticket_flows
Expand Down Expand Up @@ -1105,3 +1107,83 @@ def case_create_resources_flow(

# we update the ticket
ticket_flows.update_case_ticket(case=case, db_session=db_session)


@background_task
def case_engage_oncall_flow(
user_email: str,
case_id: int,
oncall_service_external_id: str,
page=None,
organization_slug: str = None,
db_session=None,
):
"""Runs the case engage oncall flow."""
# we load the case instance
case = case_service.get(db_session=db_session, case_id=case_id)

# we resolve the oncall service
oncall_service = service_service.get_by_external_id_and_project_id(
db_session=db_session,
external_id=oncall_service_external_id,
project_id=case.project.id,
)

# we get the active oncall plugin
oncall_plugin = plugin_service.get_active_instance(
db_session=db_session, project_id=case.project.id, plugin_type="oncall"
)

if oncall_plugin:
if oncall_plugin.plugin.slug != oncall_service.type:
log.warning(
f"Unable to engage the oncall. Oncall plugin enabled not of type {oncall_plugin.plugin.slug}." # noqa
)
return None, None
else:
log.warning("Unable to engage the oncall. No oncall plugins enabled.")
return None, None

oncall_email = oncall_plugin.instance.get(service_id=oncall_service_external_id)

# we attempt to add the oncall to the case
oncall_participant_added = case_add_or_reactivate_participant_flow(
user_email=oncall_email,
case_id=case.id,
service_id=oncall_service.id,
db_session=db_session,
)

if not oncall_participant_added:
# we already have the oncall for the service in the case
return None, oncall_service

individual = individual_service.get_by_email_and_project(
db_session=db_session, email=user_email, project_id=case.project.id
)

event_service.log_case_event(
db_session=db_session,
source=oncall_plugin.plugin.title,
description=f"{individual.name} engages oncall service {oncall_service.name}",
case_id=case.id,
)

if page == "Yes":
# we page the oncall
oncall_plugin.instance.page(
service_id=oncall_service_external_id,
incident_name=case.name,
incident_title=case.title,
incident_description=case.description,
event_type="case",
)

event_service.log_case_event(
db_session=db_session,
source=oncall_plugin.plugin.title,
description=f"{oncall_service.name} on-call paged",
case_id=case.id,
)

return oncall_participant_added.individual, oncall_service
1 change: 1 addition & 0 deletions src/dispatch/plugins/dispatch_pagerduty/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def page(
incident_name=incident_name,
incident_title=incident_title,
incident_description=incident_description,
event_type=kwargs.get("event_type", "incident"),
)

def did_oncall_just_go_off_shift(self, schedule_id: str, hour: int) -> Optional[dict]:
Expand Down
3 changes: 2 additions & 1 deletion src/dispatch/plugins/dispatch_pagerduty/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,15 @@ def page_oncall(
incident_name: str,
incident_title: str,
incident_description: str,
event_type: str = "incident",
) -> dict:
"""Pages the oncall for a given service id."""
service = get_service(client, service_id)
escalation_policy_id = service["escalation_policy"]["id"]

headers = {"from": from_email}
data = {
"type": "incident",
"type": event_type,
"title": f"{incident_name} - {incident_title}",
"service": {"id": service_id, "type": "service_reference"},
"body": {"type": "incident_body", "details": incident_description},
Expand Down
36 changes: 25 additions & 11 deletions src/dispatch/plugins/dispatch_slack/incident/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -1746,14 +1746,18 @@ def handle_engage_oncall_command(
"""Handles the engage oncall command."""
ack()

# TODO: handle cases
project_id = None
if context["subject"].type == CaseSubjects.case:
raise CommandError("Command is not currently available for cases.")

incident = incident_service.get(db_session=db_session, incident_id=context["subject"].id)
case = case_service.get(db_session=db_session, case_id=context["subject"].id)
if not case.dedicated_channel:
raise CommandError("Command is not currently available for threaded cases.")
project_id = case.project.id
else:
incident = incident_service.get(db_session=db_session, incident_id=context["subject"].id)
project_id = incident.project.id

oncall_services = service_service.get_all_by_project_id_and_status(
db_session=db_session, project_id=incident.project.id, is_active=True
db_session=db_session, project_id=project_id, is_active=True
)

if not oncall_services.count():
Expand Down Expand Up @@ -1837,12 +1841,22 @@ def handle_engage_oncall_submission_event(
page_block = form_data.get(EngageOncallBlockIds.page)
page = page_block[0]["value"] if page_block else None # page_block[0]["value"] == "Yes"

oncall_individual, oncall_service = incident_flows.incident_engage_oncall_flow(
user.email,
context["subject"].id,
oncall_service_external_id,
page=page,
db_session=db_session,
oncall_individual, oncall_service = (
case_flows.case_engage_oncall_flow(
user_email=user.email,
case_id=context["subject"].id,
oncall_service_external_id=oncall_service_external_id,
page=page,
db_session=db_session,
)
if context["subject"].type == CaseSubjects.case
else incident_flows.incident_engage_oncall_flow(
user_email=user.email,
incident_id=context["subject"].id,
oncall_service_external_id=oncall_service_external_id,
page=page,
db_session=db_session,
)
)

if not oncall_individual and not oncall_service:
Expand Down

0 comments on commit da320ca

Please sign in to comment.