def update_report_incident_modal( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict = None, db_session=None, slack_client=None, ): """Creates a modal for reporting an incident.""" trigger_id = action["trigger_id"] submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) # we must pass existing values if they exist modal_update_template = report_incident( db_session=db_session, channel_id=channel_id, title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], project_name=parsed_form_data[IncidentBlockId.project]["value"], ) update_modal_with_user( client=slack_client, trigger_id=trigger_id, view_id=action["view"]["id"], modal=modal_update_template, )
def update_update_participant_modal( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session=None, slack_client=None, ): """Pushes an updated view to the update participant modal.""" trigger_id = action["trigger_id"] submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) participant_id = parsed_form_data[UpdateParticipantBlockId.participant]["value"] selected_participant = participant_service.get( db_session=db_session, participant_id=participant_id ) incident = incident_service.get(db_session=db_session, incident_id=incident_id) modal_update_template = update_participant(incident=incident, participant=selected_participant) update_modal_with_user( client=slack_client, trigger_id=trigger_id, view_id=action["view"]["id"], modal=modal_update_template, )
def update_participant_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session=None, slack_client=None, ): """Saves form data.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) added_reason = parsed_form_data.get(UpdateParticipantBlockId.reason_added) participant_id = int(parsed_form_data.get(UpdateParticipantBlockId.participant)["value"]) selected_participant = participant_service.get( db_session=db_session, participant_id=participant_id ) participant_service.update( db_session=db_session, participant=selected_participant, participant_in=ParticipantUpdate(added_reason=added_reason), ) send_ephemeral_message( client=slack_client, conversation_id=channel_id, user_id=user_id, text="You have successfully updated the participant.", )
def run_workflow_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session=None, slack_client=None, ): """Runs an external flow.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) params = {} named_params = [] for i in parsed_form_data.keys(): if i.startswith(RunWorkflowBlockId.param): key = i.split("-")[1] value = parsed_form_data[i] params.update({key: value}) named_params.append({"key": key, "value": value}) workflow_id = parsed_form_data.get( RunWorkflowBlockId.workflow_select)["value"] run_reason = parsed_form_data.get(RunWorkflowBlockId.run_reason) incident = incident_service.get(db_session=db_session, incident_id=incident_id) workflow = workflow_service.get(db_session=db_session, workflow_id=workflow_id) creator_email = get_user_email(slack_client, action["user"]["id"]) instance = workflow_service.create_instance( db_session=db_session, instance_in=WorkflowInstanceCreate( workflow={"id": workflow.id}, incident={"id": incident.id}, creator={"email": creator_email}, run_reason=run_reason, parameters=named_params, ), ) params.update({ "incident_id": incident.id, "incident_name": incident.name, "instance_id": instance.id }) workflow.plugin.instance.run(workflow.resource_id, params) send_workflow_notification( incident.conversation.channel_id, INCIDENT_WORKFLOW_CREATED_NOTIFICATION, db_session, instance_creator_name=instance.creator.individual.name, workflow_name=instance.workflow.name, workflow_description=instance.workflow.description, )
def report_incident_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, config: SlackConversationConfiguration = None, db_session: SessionLocal = None, slack_client=None, ): submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) # Send a confirmation to the user blocks = create_incident_reported_confirmation_message( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], incident_type=parsed_form_data[IncidentBlockId.type]["value"], incident_priority=parsed_form_data[IncidentBlockId.priority]["value"], ) send_ephemeral_message( client=slack_client, conversation_id=channel_id, user_id=user_id, text="", blocks=blocks, ) tags = [] for t in parsed_form_data.get(IncidentBlockId.tags, []): # we have to fetch as only the IDs are embedded in slack tag = tag_service.get(db_session=db_session, tag_id=int(t["value"])) tags.append(tag) project = {"name": parsed_form_data[IncidentBlockId.project]["value"]} incident_in = IncidentCreate( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], incident_type={"name": parsed_form_data[IncidentBlockId.type]["value"]}, incident_priority={"name": parsed_form_data[IncidentBlockId.priority]["value"]}, project=project, tags=tags, ) if not incident_in.reporter: incident_in.reporter = ParticipantUpdate(individual=IndividualContactRead(email=user_email)) # Create the incident incident = incident_service.create(db_session=db_session, incident_in=incident_in) incident_flows.incident_create_flow( incident_id=incident.id, db_session=db_session, organization_slug=incident.project.organization.slug, )
def update_incident_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, config: SlackConversationConfiguration = None, db_session=None, slack_client=None, ): """Massages slack dialog data into something that Dispatch can use.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) incident = incident_service.get(db_session=db_session, incident_id=incident_id) tags = [] for t in parsed_form_data.get(IncidentBlockId.tags, []): # we have to fetch as only the IDs are embedded in slack tag = tag_service.get(db_session=db_session, tag_id=int(t["value"])) tags.append(tag) incident_in = IncidentUpdate( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], resolution=parsed_form_data[IncidentBlockId.resolution], incident_type={"name": parsed_form_data[IncidentBlockId.type]["value"]}, incident_priority={"name": parsed_form_data[IncidentBlockId.priority]["value"]}, status=parsed_form_data[IncidentBlockId.status]["value"], tags=tags, ) previous_incident = IncidentRead.from_orm(incident) # we don't allow visibility to be set in slack so we copy it over incident_in.visibility = incident.visibility updated_incident = incident_service.update( db_session=db_session, incident=incident, incident_in=incident_in ) commander_email = updated_incident.commander.individual.email reporter_email = updated_incident.reporter.individual.email incident_flows.incident_update_flow( user_email, commander_email, reporter_email, incident_id, previous_incident, db_session=db_session, ) if updated_incident.status != IncidentStatus.closed: send_ephemeral_message( slack_client, channel_id, user_id, "You have sucessfully updated the incident." )
def add_timeline_event_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, config: SlackConversationConfiguration = None, db_session=None, slack_client=None, ): """Adds event to incident timeline based on submitted form data.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) event_date = parsed_form_data.get(AddTimelineEventBlockId.date) event_hour = parsed_form_data.get(AddTimelineEventBlockId.hour)["value"] event_minute = parsed_form_data.get(AddTimelineEventBlockId.minute)["value"] event_timezone_selection = parsed_form_data.get(AddTimelineEventBlockId.timezone)["value"] event_description = parsed_form_data.get(AddTimelineEventBlockId.description) participant = participant_service.get_by_incident_id_and_email( db_session=db_session, incident_id=incident_id, email=user_email ) event_timezone = event_timezone_selection if event_timezone_selection == "profile": participant_profile = get_user_profile_by_email(slack_client, user_email) if participant_profile.get("tz"): event_timezone = participant_profile.get("tz") event_dt = datetime.fromisoformat(f"{event_date}T{event_hour}:{event_minute}") event_dt_utc = pytz.timezone(event_timezone).localize(event_dt).astimezone(pytz.utc) event_service.log( db_session=db_session, source="Slack Plugin - Conversation Management", started_at=event_dt_utc, description=f'"{event_description}," said {participant.individual.name}', incident_id=incident_id, individual_id=participant.individual.id, ) send_ephemeral_message( client=slack_client, conversation_id=channel_id, user_id=user_id, text="Event sucessfully added to timeline.", )
def report_incident_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session: SessionLocal = None, slack_client=None, ): submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) # Send a confirmation to the user blocks = create_incident_reported_confirmation_message( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], incident_type=parsed_form_data[IncidentBlockId.type]["value"], incident_priority=parsed_form_data[IncidentBlockId.priority]["value"], ) send_ephemeral_message( client=slack_client, conversation_id=channel_id, user_id=user_id, text="", blocks=blocks, ) tags = [] for t in parsed_form_data.get(IncidentBlockId.tags, []): tags.append({"id": t["value"]}) incident_in = IncidentCreate( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], incident_type={"name": parsed_form_data[IncidentBlockId.type]["value"]}, incident_priority={"name": parsed_form_data[IncidentBlockId.priority]["value"]}, project={"name": parsed_form_data[IncidentBlockId.project]["value"]}, reporter=IndividualContactCreate(email=user_email), tags=tags, ) # Create the incident incident = incident_service.create(db_session=db_session, incident_in=incident_in) incident_flows.incident_create_flow(incident_id=incident.id, db_session=db_session)
def rating_feedback_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, config: SlackConversationConfiguration = None, db_session=None, slack_client=None, ): """Adds rating and feeback to incident based on submitted form data.""" incident = incident_service.get(db_session=db_session, incident_id=incident_id) participant = participant_service.get_by_incident_id_and_email( db_session=db_session, incident_id=incident_id, email=user_email ) submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) feedback = parsed_form_data.get(RatingFeedbackBlockId.feedback) rating = parsed_form_data.get(RatingFeedbackBlockId.rating, {}).get("value") feedback_in = FeedbackCreate( rating=rating, feedback=feedback, project=incident.project, incident=incident ) feedback = feedback_service.create(db_session=db_session, feedback_in=feedback_in) incident.feedback.append(feedback) # we only really care if this exists, if it doesn't then flag is false if not parsed_form_data.get(RatingFeedbackBlockId.anonymous): participant.feedback.append(feedback) db_session.add(participant) db_session.add(incident) db_session.commit() send_message( client=slack_client, conversation_id=user_id, text="Thank you for your feedback!", )
def rating_feedback_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session=None, slack_client=None, ): """Adds rating and feeback to incident based on submitted form data.""" incident = incident_service.get(db_session=db_session, incident_id=incident_id) participant = participant_service.get_by_incident_id_and_email( db_session=db_session, incident_id=incident_id, email=user_email) submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) feedback = parsed_form_data.get(RatingFeedbackBlockId.feedback) rating = parsed_form_data.get(RatingFeedbackBlockId.rating)["value"] anonymous = parsed_form_data.get(RatingFeedbackBlockId.anonymous)["value"] feedback_in = FeedbackCreate(rating=rating, feedback=feedback, project=incident.project) feedback = feedback_service.create(db_session=db_session, feedback_in=feedback_in) incident.feedback.append(feedback) if anonymous == "": participant.feedback.append(feedback) db_session.add(participant) db_session.add(incident) db_session.commit() send_message( client=slack_client, conversation_id=user_id, text="Thank you for your feedback!", )
def update_incident_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, db_session=None, slack_client=None, ): """Massages slack dialog data into something that Dispatch can use.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) tags = [] for t in parsed_form_data.get(IncidentBlockId.tags, []): tags.append({"id": t["value"]}) incident_in = IncidentUpdate( title=parsed_form_data[IncidentBlockId.title], description=parsed_form_data[IncidentBlockId.description], incident_type={"name": parsed_form_data[IncidentBlockId.type]["value"]}, incident_priority={"name": parsed_form_data[IncidentBlockId.priority]["value"]}, status=parsed_form_data[IncidentBlockId.status]["value"], tags=tags, ) incident = incident_service.get(db_session=db_session, incident_id=incident_id) existing_incident = IncidentRead.from_orm(incident) # we don't allow visibility to be set in slack so we copy it over incident_in.visibility = incident.visibility updated_incident = incident_service.update( db_session=db_session, incident=incident, incident_in=incident_in ) incident_flows.incident_update_flow( user_email, incident_id, existing_incident, db_session=db_session ) if updated_incident.status != IncidentStatus.closed: send_ephemeral_message( slack_client, channel_id, user_id, "You have sucessfully updated the incident." )
def update_notifications_group_from_submitted_form( user_id: str, user_email: str, channel_id: str, incident_id: int, action: dict, config: SlackConversationConfiguration = None, db_session=None, slack_client=None, ): """Updates notifications group based on submitted form data.""" submitted_form = action.get("view") parsed_form_data = parse_submitted_form(submitted_form) current_members = ( submitted_form["blocks"][1]["element"]["initial_value"].replace(" ", "").split(",") ) updated_members = ( parsed_form_data.get(UpdateNotificationsGroupBlockId.update_members) .replace(" ", "") .split(",") ) members_added = list(set(updated_members) - set(current_members)) members_removed = list(set(current_members) - set(updated_members)) incident = incident_service.get(db_session=db_session, incident_id=incident_id) group_plugin = plugin_service.get_active_instance( db_session=db_session, project_id=incident.project.id, plugin_type="participant-group" ) group_plugin.instance.add(incident.notifications_group.email, members_added) group_plugin.instance.remove(incident.notifications_group.email, members_removed) send_ephemeral_message( client=slack_client, conversation_id=channel_id, user_id=user_id, text="You have successfully updated the notifications group.", )
def get_tags( db_session: SessionLocal, user_id: int, user_email: str, channel_id: str, incident_id: str, query_str: str, request: Request, ): """Fetches tags based on the current query.""" # use the project from the incident if available filter_spec = {} if incident_id: incident = incident_service.get(db_session=db_session, incident_id=incident_id) # scope to current incident project filter_spec = { "and": [{ "model": "Project", "op": "==", "field": "id", "value": incident.project.id }] } submitted_form = request.get("view") parsed_form_data = parse_submitted_form(submitted_form) project = parsed_form_data.get(IncidentBlockId.project) if project: filter_spec = { "and": [{ "model": "Project", "op": "==", "field": "name", "value": project["value"] }] } # attempt to filter by tag type if "/" in query_str: tag_type, tag_name = query_str.split("/") type_filter = { "model": "TagType", "op": "==", "field": "name", "value": tag_type } if filter_spec.get("and"): filter_spec["and"].append(type_filter) else: filter_spec = {"and": [type_filter]} if not tag_name: query_str = None tags = search_filter_sort_paginate(db_session=db_session, model="Tag", query_str=query_str, filter_spec=filter_spec) else: tags = search_filter_sort_paginate(db_session=db_session, model="Tag", query_str=query_str, filter_spec=filter_spec) options = [] for t in tags["items"]: options.append({ "text": { "type": "plain_text", "text": f"{t.tag_type.name}/{t.name}" }, "value": str( t.id ), # NOTE slack doesn't not accept int's as values (fails silently) }) return {"options": options}