From a2851d3f813c04768ce825c8af99e26912d80b4e Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Mon, 4 Sep 2023 19:03:18 +0100 Subject: [PATCH] Refactor `AlertGroup.slack_message` (#2957) # What this PR does Refactors the foreign key relationship between `AlertGroup` and `SlackMessage` models (see https://github.com/grafana/oncall-private/issues/1867 for more info). ## Which issue(s) this PR fixes https://github.com/grafana/oncall-private/issues/1867 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- CHANGELOG.md | 5 ++ ...2_remove_alertgroup_slack_message_state.py | 18 +++++ engine/apps/alerts/models/alert_group.py | 37 +++------ engine/apps/alerts/tasks/notify_user.py | 5 +- .../apps/slack/alert_group_slack_service.py | 46 +++-------- engine/apps/slack/models/slack_message.py | 18 +---- .../alert_group_representative.py | 2 +- .../apps/slack/scenarios/distribute_alerts.py | 30 ++----- .../apps/slack/scenarios/resolution_note.py | 9 +-- .../scenarios/slack_channel_integration.py | 8 +- engine/apps/slack/scenarios/step_mixins.py | 10 +-- engine/apps/slack/tasks.py | 3 +- .../test_alert_group_actions.py | 80 +++++++++---------- .../test_manage_responders.py | 3 +- .../test_resolution_note.py | 5 +- engine/apps/slack/views.py | 7 +- 16 files changed, 114 insertions(+), 172 deletions(-) create mode 100644 engine/apps/alerts/migrations/0032_remove_alertgroup_slack_message_state.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d583de..9d51d846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Make Slack integration not post an alert group message if it's already deleted + refactor AlertGroup and + SlackMessage foreign key relationship by @vadimkerr ([#2957](https://github.com/grafana/oncall/pull/2957)) + ## v1.3.31 (2023-09-04) ### Fixed diff --git a/engine/apps/alerts/migrations/0032_remove_alertgroup_slack_message_state.py b/engine/apps/alerts/migrations/0032_remove_alertgroup_slack_message_state.py new file mode 100644 index 00000000..e555a932 --- /dev/null +++ b/engine/apps/alerts/migrations/0032_remove_alertgroup_slack_message_state.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.20 on 2023-09-04 12:46 + +import common.migrations.remove_field +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('alerts', '0031_auto_20230831_1445'), + ] + + operations = [ + common.migrations.remove_field.RemoveFieldState( + model_name='AlertGroup', + name='slack_message', + ), + ] diff --git a/engine/apps/alerts/models/alert_group.py b/engine/apps/alerts/models/alert_group.py index 2bf9be0c..fb64d83c 100644 --- a/engine/apps/alerts/models/alert_group.py +++ b/engine/apps/alerts/models/alert_group.py @@ -148,7 +148,6 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. resolution_note_slack_messages: "RelatedManager['ResolutionNoteSlackMessage']" resolved_by_alert: typing.Optional["Alert"] root_alert_group: typing.Optional["AlertGroup"] - slack_message: typing.Optional["SlackMessage"] slack_log_message: typing.Optional["SlackMessage"] slack_messages: "RelatedManager['SlackMessage']" users: "RelatedManager['User']" @@ -341,14 +340,6 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. related_name="wiped_alert_groups", ) - slack_message = models.OneToOneField( - "slack.SlackMessage", - on_delete=models.SET_NULL, - null=True, - default=None, - related_name="_alert_group", - ) - slack_log_message = models.OneToOneField( "slack.SlackMessage", on_delete=models.SET_NULL, @@ -1795,23 +1786,21 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. return self.slack_message and self.channel.organization.slack_team_identity @property - def slack_channel_id(self): - slack_channel_id = None - if self.channel.organization.slack_team_identity is not None: - slack_message = self.get_slack_message() - if slack_message is not None: - slack_channel_id = slack_message.channel_id - elif self.channel_filter is not None: - slack_channel_id = self.channel_filter.slack_channel_id_or_general_log_id - return slack_channel_id + def slack_channel_id(self) -> str | None: + if not self.channel.organization.slack_team_identity: + return None - def get_slack_message(self): - from apps.slack.models import SlackMessage + if self.slack_message: + return self.slack_message.channel_id - if self.slack_message is None: - slack_message = SlackMessage.objects.filter(alert_group=self).order_by("created_at").first() - return slack_message - return self.slack_message + if self.channel_filter: + return self.channel_filter.slack_channel_id_or_general_log_id + + return None + + @property + def slack_message(self) -> typing.Optional["SlackMessage"]: + return self.slack_messages.order_by("created_at").first() @cached_property def last_stop_escalation_log(self): diff --git a/engine/apps/alerts/tasks/notify_user.py b/engine/apps/alerts/tasks/notify_user.py index 21cfd762..5258b077 100644 --- a/engine/apps/alerts/tasks/notify_user.py +++ b/engine/apps/alerts/tasks/notify_user.py @@ -311,9 +311,8 @@ def perform_notification(log_record_pk): return retry_timeout_hours = 1 - slack_message = alert_group.get_slack_message() - if slack_message is not None: - slack_message.send_slack_notification(user, alert_group, notification_policy) + if alert_group.slack_message: + alert_group.slack_message.send_slack_notification(user, alert_group, notification_policy) task_logger.debug(f"Finished send_slack_notification for alert_group {alert_group.pk}.") # check how much time has passed since log record was created # to prevent eternal loop of restarting perform_notification task diff --git a/engine/apps/slack/alert_group_slack_service.py b/engine/apps/slack/alert_group_slack_service.py index 971166b3..78f79454 100644 --- a/engine/apps/slack/alert_group_slack_service.py +++ b/engine/apps/slack/alert_group_slack_service.py @@ -32,21 +32,16 @@ class AlertGroupSlackService: self._slack_client = SlackClientWithErrorHandling(slack_team_identity.bot_access_token) def update_alert_group_slack_message(self, alert_group: "AlertGroup") -> None: - logger.info(f"Started _update_slack_message for alert_group {alert_group.pk}") from apps.alerts.models import AlertReceiveChannel - from apps.slack.models import SlackMessage - slack_message = alert_group.slack_message - attachments = alert_group.render_slack_attachments() - blocks = alert_group.render_slack_blocks() logger.info(f"Update message for alert_group {alert_group.pk}") try: self._slack_client.api_call( "chat.update", - channel=slack_message.channel_id, - ts=slack_message.slack_id, - attachments=attachments, - blocks=blocks, + channel=alert_group.slack_message.channel_id, + ts=alert_group.slack_message.slack_id, + attachments=alert_group.render_slack_attachments(), + blocks=alert_group.render_slack_blocks(), ) logger.info(f"Message has been updated for alert_group {alert_group.pk}") except SlackAPIRateLimitException as e: @@ -61,22 +56,8 @@ class AlertGroupSlackService: raise e except SlackAPIException as e: - if e.response["error"] == "message_not_found": - logger.info(f"message_not_found for alert_group {alert_group.pk}, trying to post new message") - result = self._slack_client.api_call( - "chat.postMessage", channel=slack_message.channel_id, attachments=attachments, blocks=blocks - ) - slack_message_updated = SlackMessage( - slack_id=result["ts"], - organization=slack_message.organization, - _slack_team_identity=slack_message.slack_team_identity, - channel_id=slack_message.channel_id, - alert_group=alert_group, - ) - slack_message_updated.save() - alert_group.slack_message = slack_message_updated - alert_group.save(update_fields=["slack_message"]) - logger.info(f"Message has been posted for alert_group {alert_group.pk}") + if e.response["error"] == "message_not_found": # message deleted from channel + logger.info(f"Skip updating slack message for alert_group {alert_group.pk} due message_not_found") elif e.response["error"] == "is_inactive": # deleted channel error logger.info(f"Skip updating slack message for alert_group {alert_group.pk} due to is_inactive") elif e.response["error"] == "account_inactive": @@ -95,17 +76,13 @@ class AlertGroupSlackService: if alert_group.channel.is_rate_limited_in_slack: return - from apps.slack.models import SlackMessage - - slack_message = alert_group.get_slack_message() - channel_id = slack_message.channel_id try: result = self._slack_client.api_call( "chat.postMessage", - channel=channel_id, + channel=alert_group.slack_message.channel_id, text=text, attachments=attachments, - thread_ts=slack_message.slack_id, + thread_ts=alert_group.slack_message.slack_id, mrkdwn=mrkdwn, unfurl_links=unfurl_links, ) @@ -137,10 +114,9 @@ class AlertGroupSlackService: else: raise e else: - SlackMessage( + alert_group.slack_messages.create( slack_id=result["ts"], organization=alert_group.channel.organization, _slack_team_identity=self.slack_team_identity, - channel_id=channel_id, - alert_group=alert_group, - ).save() + channel_id=alert_group.slack_message.channel_id, + ) diff --git a/engine/apps/slack/models/slack_message.py b/engine/apps/slack/models/slack_message.py index 9af2157d..3c4fe016 100644 --- a/engine/apps/slack/models/slack_message.py +++ b/engine/apps/slack/models/slack_message.py @@ -77,17 +77,6 @@ class SlackMessage(models.Model): self.save() return self._slack_team_identity - def get_alert_group(self) -> "AlertGroup": - try: - return self._alert_group - except SlackMessage._alert_group.RelatedObjectDoesNotExist: - if self.alert_group: - self.alert_group.slack_message = self - self.alert_group.save(update_fields=["slack_message"]) - return self.alert_group - else: - raise - @property def permalink(self): if self.slack_team_identity is not None and self.cached_permalink is None: @@ -118,7 +107,7 @@ class SlackMessage(models.Model): def send_slack_notification(self, user, alert_group, notification_policy): from apps.base.models import UserNotificationPolicyLogRecord - slack_message = alert_group.get_slack_message() + slack_message = alert_group.slack_message user_verbal = user.get_username_with_slack_verbal(mention=True) slack_user_identity = user.slack_user_identity @@ -189,13 +178,12 @@ class SlackMessage(models.Model): ).save() return else: - SlackMessage( + alert_group.slack_messages.create( slack_id=result["ts"], organization=self.organization, _slack_team_identity=self.slack_team_identity, channel_id=channel_id, - alert_group=alert_group, - ).save() + ) # Check if escalated user is in channel. Otherwise send notification and request to invite him. try: diff --git a/engine/apps/slack/representatives/alert_group_representative.py b/engine/apps/slack/representatives/alert_group_representative.py index edf80814..1ef8b5c5 100644 --- a/engine/apps/slack/representatives/alert_group_representative.py +++ b/engine/apps/slack/representatives/alert_group_representative.py @@ -103,7 +103,7 @@ class AlertGroupSlackRepresentative(AlertGroupAbstractRepresentative): self.log_record = log_record def is_applicable(self): - slack_message = self.log_record.alert_group.get_slack_message() + slack_message = self.log_record.alert_group.slack_message slack_team_identity = self.log_record.alert_group.channel.organization.slack_team_identity return ( slack_message is not None diff --git a/engine/apps/slack/scenarios/distribute_alerts.py b/engine/apps/slack/scenarios/distribute_alerts.py index b23a0920..40cbebe6 100644 --- a/engine/apps/slack/scenarios/distribute_alerts.py +++ b/engine/apps/slack/scenarios/distribute_alerts.py @@ -16,7 +16,6 @@ from apps.alerts.tasks import custom_button_result from apps.alerts.utils import render_curl_command from apps.api.permissions import RBACPermission from apps.slack.constants import CACHE_UPDATE_INCIDENT_SLACK_MESSAGE_LIFETIME, SLACK_RATE_LIMIT_DELAY -from apps.slack.models import SlackMessage from apps.slack.scenarios import scenario_step from apps.slack.scenarios.slack_renderer import AlertGroupLogSlackRenderer from apps.slack.slack_client import SlackClientWithErrorHandling @@ -138,17 +137,13 @@ class AlertShootingStep(scenario_step.ScenarioStep): "chat.postMessage", channel=channel_id, attachments=attachments, blocks=blocks ) - slack_message = SlackMessage.objects.create( + alert_group.slack_messages.create( slack_id=result["ts"], organization=alert_group.channel.organization, _slack_team_identity=slack_team_identity, channel_id=channel_id, - alert_group=alert_group, ) - alert_group.slack_message = slack_message - alert_group.save(update_fields=["slack_message"]) - # If alert was made out of a message: if alert_group.channel.integration == AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL: channel = json.loads(alert.integration_unique_data)["channel"] @@ -159,13 +154,12 @@ class AlertShootingStep(scenario_step.ScenarioStep): text=":rocket: <{}|Incident registered!>".format(alert_group.slack_message.permalink), team=slack_team_identity, ) - SlackMessage( + alert_group.slack_messages.create( slack_id=result["ts"], organization=alert_group.channel.organization, _slack_team_identity=self.slack_team_identity, channel_id=channel, - alert_group=alert_group, - ).save() + ) alert.delivered = True except SlackAPITokenException: @@ -849,7 +843,6 @@ class AcknowledgeConfirmationStep(AcknowledgeGroupStep): ) def process_signal(self, log_record: AlertGroupLogRecord) -> None: - from apps.slack.models import SlackMessage from apps.user_management.models import Organization alert_group = log_record.alert_group @@ -913,13 +906,12 @@ class AcknowledgeConfirmationStep(AcknowledgeGroupStep): else: raise e else: - SlackMessage( + alert_group.slack_messages.create( slack_id=response["ts"], organization=alert_group.channel.organization, _slack_team_identity=self.slack_team_identity, channel_id=channel_id, - alert_group=alert_group, - ).save() + ) alert_group.slack_message.ack_reminder_message_ts = response["ts"] alert_group.slack_message.save(update_fields=["ack_reminder_message_ts"]) @@ -1026,10 +1018,7 @@ class UpdateLogReportMessageStep(scenario_step.ScenarioStep): self.update_log_message(alert_group) def post_log_message(self, alert_group: AlertGroup) -> None: - from apps.slack.models import SlackMessage - - slack_message = alert_group.get_slack_message() - + slack_message = alert_group.slack_message if slack_message is None: logger.info(f"Cannot post log message for alert_group {alert_group.pk} because SlackMessage doesn't exist") return None @@ -1064,15 +1053,13 @@ class UpdateLogReportMessageStep(scenario_step.ScenarioStep): raise e else: logger.debug(f"Create new slack_log_message for alert_group {alert_group.pk}") - slack_log_message = SlackMessage( + slack_log_message = alert_group.slack_messages.create( slack_id=result["ts"], organization=self.organization, _slack_team_identity=self.slack_team_identity, channel_id=slack_message.channel_id, last_updated=timezone.now(), - alert_group=alert_group, ) - slack_log_message.save() alert_group.slack_log_message = slack_log_message alert_group.save(update_fields=["slack_log_message"]) @@ -1084,8 +1071,7 @@ class UpdateLogReportMessageStep(scenario_step.ScenarioStep): self.update_log_message(alert_group) def update_log_message(self, alert_group: AlertGroup) -> None: - slack_message = alert_group.get_slack_message() - + slack_message = alert_group.slack_message if slack_message is None: logger.info( f"Cannot update log message for alert_group {alert_group.pk} because SlackMessage doesn't exist" diff --git a/engine/apps/slack/scenarios/resolution_note.py b/engine/apps/slack/scenarios/resolution_note.py index c43bf17d..980385a9 100644 --- a/engine/apps/slack/scenarios/resolution_note.py +++ b/engine/apps/slack/scenarios/resolution_note.py @@ -66,16 +66,15 @@ class AddToResolutionNoteStep(scenario_step.ScenarioStep): self.open_warning_window(payload, warning_text) return - try: - alert_group = slack_message.get_alert_group() - except SlackMessage.alert.RelatedObjectDoesNotExist as e: + alert_group = slack_message.alert_group + if not alert_group: self.open_warning_window(payload, warning_text) print( f"Exception: tried to add message from thread to Resolution Note: " f"Slack Team Identity pk: {self.slack_team_identity.pk}, " f"Slack Message id: {slack_message.slack_id}" ) - raise e + return if payload["message"]["type"] == "message" and "user" in payload["message"]: message_ts = payload["message_ts"] @@ -119,7 +118,7 @@ class AddToResolutionNoteStep(scenario_step.ScenarioStep): _slack_team_identity=slack_team_identity, channel_id=channel_id, ) - alert_group = slack_message.get_alert_group() + alert_group = slack_message.alert_group try: author_slack_user_identity = SlackUserIdentity.objects.get( slack_id=payload["message"]["user"], slack_team_identity=slack_team_identity diff --git a/engine/apps/slack/scenarios/slack_channel_integration.py b/engine/apps/slack/scenarios/slack_channel_integration.py index 045ccbf7..2c633f62 100644 --- a/engine/apps/slack/scenarios/slack_channel_integration.py +++ b/engine/apps/slack/scenarios/slack_channel_integration.py @@ -1,8 +1,6 @@ import logging import typing -from django.core.exceptions import ObjectDoesNotExist - from apps.slack.scenarios import scenario_step from apps.slack.types import EventPayload, EventType, MessageEventSubtype, PayloadType, ScenarioRoute @@ -73,9 +71,7 @@ class SlackChannelMessageEventStep(scenario_step.ScenarioStep): except SlackMessage.DoesNotExist: return - try: - alert_group = slack_message.get_alert_group() - except ObjectDoesNotExist: + if not slack_message.alert_group: # SlackMessage instances without alert_group set (e.g., SSR Slack messages) return @@ -101,7 +97,7 @@ class SlackChannelMessageEventStep(scenario_step.ScenarioStep): slack_thread_message, created = ResolutionNoteSlackMessage.objects.get_or_create( ts=message_ts, thread_ts=thread_ts, - alert_group=alert_group, + alert_group=slack_message.alert_group, defaults={ "user": self.user, "added_by_user": self.user, diff --git a/engine/apps/slack/scenarios/step_mixins.py b/engine/apps/slack/scenarios/step_mixins.py index fb366338..46b23b1a 100644 --- a/engine/apps/slack/scenarios/step_mixins.py +++ b/engine/apps/slack/scenarios/step_mixins.py @@ -29,6 +29,7 @@ class AlertGroupActionsMixin: or self._get_alert_group_from_message(payload) # Try to use alert_group_pk from ANY button in message or self._get_alert_group_from_slack_message_in_db(slack_team_identity, payload) # Fetch message from DB ) + assert alert_group is not None, "AlertGroup not found" # Repair alert group if Slack message is orphaned if alert_group.slack_message is None: @@ -68,7 +69,7 @@ class AlertGroupActionsMixin: except KeyError: message_id = payload["original_message"]["ts"] - slack_message = SlackMessage.objects.create( + SlackMessage.objects.create( slack_id=message_id, organization=alert_group.channel.organization, _slack_team_identity=slack_team_identity, @@ -76,9 +77,6 @@ class AlertGroupActionsMixin: alert_group=alert_group, ) - alert_group.slack_message = slack_message - alert_group.save(update_fields=["slack_message"]) - def _get_alert_group_from_action(self, payload: EventPayload) -> AlertGroup | None: """ Get AlertGroup instance from action data in payload. Action data is data encoded into buttons and select @@ -140,7 +138,7 @@ class AlertGroupActionsMixin: def _get_alert_group_from_slack_message_in_db( self, slack_team_identity: SlackTeamIdentity, payload: EventPayload - ) -> AlertGroup: + ) -> AlertGroup | None: """ Get AlertGroup instance from SlackMessage instance. Old messages may not have alert_group_pk encoded into buttons, so we need to query SlackMessage to figure out @@ -160,4 +158,4 @@ class AlertGroupActionsMixin: _slack_team_identity=slack_team_identity, channel_id=channel_id, ) - return slack_message.get_alert_group() + return slack_message.alert_group diff --git a/engine/apps/slack/tasks.py b/engine/apps/slack/tasks.py index 28d30c19..d94bd092 100644 --- a/engine/apps/slack/tasks.py +++ b/engine/apps/slack/tasks.py @@ -97,9 +97,8 @@ def check_slack_message_exists_before_post_message_to_thread( ) return retry_timeout_hours = 24 - slack_message = alert_group.get_slack_message() - if slack_message is not None: + if alert_group.slack_message: AlertGroupSlackService(slack_team_identity).publish_message_to_alert_group_thread(alert_group, text=text) # check how much time has passed since alert group was created diff --git a/engine/apps/slack/tests/test_scenario_steps/test_alert_group_actions.py b/engine/apps/slack/tests/test_scenario_steps/test_alert_group_actions.py index 9f91aac3..8e4af96a 100644 --- a/engine/apps/slack/tests/test_scenario_steps/test_alert_group_actions.py +++ b/engine/apps/slack/tests/test_scenario_steps/test_alert_group_actions.py @@ -231,6 +231,31 @@ def test_get_alert_group_from_slack_message_in_db( assert alert_group == result +@pytest.mark.django_db +def test_get_alert_group_from_slack_message_in_db_no_alert_group( + make_organization_and_user_with_slack_identities, + make_alert_receive_channel, + make_alert_group, + make_slack_channel, + make_slack_message, +): + organization, user, slack_team_identity, _ = make_organization_and_user_with_slack_identities() + + slack_channel = make_slack_channel(slack_team_identity) + slack_message = make_slack_message(alert_group=None, organization=organization, channel_id=slack_channel.slack_id) + + payload = { + "message_ts": slack_message.slack_id, + "channel": {"id": slack_channel.slack_id}, + "actions": [{"type": "button", "value": "RANDOM_VALUE"}], + } + + step = TestScenario(organization=organization, user=user, slack_team_identity=slack_team_identity) + + with pytest.raises(AssertionError): + step.get_alert_group(slack_team_identity, payload) + + @pytest.mark.parametrize( "payload", [ @@ -267,10 +292,7 @@ def test_step_acknowledge( alert_group = make_alert_group(alert_receive_channel, acknowledged=False, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "AcknowledgeGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -316,10 +338,7 @@ def test_step_unacknowledge( alert_group = make_alert_group(alert_receive_channel, acknowledged=True, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "UnAcknowledgeGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -365,10 +384,7 @@ def test_step_resolve( alert_group = make_alert_group(alert_receive_channel, resolved=False, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "ResolveGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -414,10 +430,7 @@ def test_step_unresolve( alert_group = make_alert_group(alert_receive_channel, resolved=True, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "UnResolveGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -469,10 +482,7 @@ def test_step_invite( alert_group = make_alert_group(alert_receive_channel, resolved=True, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "InviteOtherPersonToIncident") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -530,10 +540,7 @@ def test_step_stop_invite( alert_group = make_alert_group(alert_receive_channel, resolved=True, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) invitation = make_invitation(alert_group, user, second_user, pk=INVITATION_ID) @@ -586,10 +593,7 @@ def test_step_silence( alert_group = make_alert_group(alert_receive_channel, silenced=False, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "SilenceGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -640,10 +644,7 @@ def test_step_unsilence( alert_group = make_alert_group(alert_receive_channel, silenced=True, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "UnSilenceGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -683,10 +684,7 @@ def test_step_select_attach( alert_group = make_alert_group(alert_receive_channel, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "SelectAttachGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -740,10 +738,7 @@ def test_step_unattach( alert_group = make_alert_group(alert_receive_channel, root_alert_group=root_alert_group, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("distribute_alerts", "UnAttachGroupStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) @@ -795,10 +790,7 @@ def test_step_format_alert( alert_group = make_alert_group(alert_receive_channel, pk=ALERT_GROUP_ID) make_alert(alert_group, raw_request_data={}) - slack_message = make_slack_message( - alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=SLACK_MESSAGE_TS) step_class = ScenarioStep.get_step("alertgroup_appearance", "OpenAlertAppearanceDialogStep") step = step_class(organization=organization, user=user, slack_team_identity=slack_team_identity) diff --git a/engine/apps/slack/tests/test_scenario_steps/test_manage_responders.py b/engine/apps/slack/tests/test_scenario_steps/test_manage_responders.py index 094440f6..5682b55d 100644 --- a/engine/apps/slack/tests/test_scenario_steps/test_manage_responders.py +++ b/engine/apps/slack/tests/test_scenario_steps/test_manage_responders.py @@ -74,8 +74,7 @@ def manage_responders_setup( make_alert(alert_group, raw_request_data={}) slack_channel = make_slack_channel(slack_team_identity, slack_id=CHANNEL_ID) - slack_message = make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=MESSAGE_TS) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id=slack_channel.slack_id, slack_id=MESSAGE_TS) return organization, user, slack_team_identity, slack_user_identity diff --git a/engine/apps/slack/tests/test_scenario_steps/test_resolution_note.py b/engine/apps/slack/tests/test_scenario_steps/test_resolution_note.py index 1e31a8f2..285ead72 100644 --- a/engine/apps/slack/tests/test_scenario_steps/test_resolution_note.py +++ b/engine/apps/slack/tests/test_scenario_steps/test_resolution_note.py @@ -201,10 +201,7 @@ def test_resolution_notes_modal_closed_before_update( alert_receive_channel = make_alert_receive_channel(organization) alert_group = make_alert_group(alert_receive_channel) - slack_message = make_slack_message( - alert_group=alert_group, channel_id="RANDOM_CHANNEL_ID", slack_id="RANDOM_MESSAGE_ID" - ) - slack_message.get_alert_group() # fix FKs + make_slack_message(alert_group=alert_group, channel_id="RANDOM_CHANNEL_ID", slack_id="RANDOM_MESSAGE_ID") payload = { "trigger_id": "TEST", diff --git a/engine/apps/slack/views.py b/engine/apps/slack/views.py index 991a858d..ec7ff8ac 100644 --- a/engine/apps/slack/views.py +++ b/engine/apps/slack/views.py @@ -490,15 +490,16 @@ class SlackEventApiEndpointView(APIView): if not (channel_id and message_ts): return None - with suppress(ObjectDoesNotExist): + try: slack_message = SlackMessage.objects.get( _slack_team_identity=slack_team_identity, slack_id=message_ts, channel_id=channel_id, ) - return slack_message.get_alert_group().channel.organization + except SlackMessage.DoesNotExist: + return None - return None + return slack_message.alert_group.channel.organization if slack_message.alert_group else None def _open_warning_window_if_needed( self, payload: EventPayload, slack_team_identity: SlackTeamIdentity, warning_text: str