Support message shortcut broadcast (#4518)
# What this PR does Related to https://github.com/grafana/oncall-gateway/issues/206 ## 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] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes.
This commit is contained in:
parent
8f64a44e54
commit
b7dbb2a26e
2 changed files with 133 additions and 4 deletions
|
|
@ -3,6 +3,7 @@ import json
|
|||
import logging
|
||||
import typing
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.utils.text import Truncator
|
||||
|
||||
|
|
@ -76,16 +77,28 @@ class AddToResolutionNoteStep(scenario_step.ScenarioStep):
|
|||
|
||||
warning_text = "Unable to add this message to resolution note, this command works only in incident threads."
|
||||
|
||||
# thread_ts is only present for thread messages
|
||||
thread_ts = payload.get("message", {}).get("thread_ts")
|
||||
if not thread_ts:
|
||||
if settings.UNIFIED_SLACK_APP_ENABLED:
|
||||
# Message shortcut events are broadcasted to multiple regions by chatops-proxy
|
||||
# Do not open a warning window to avoid multiple regions opening the same window multiple times
|
||||
return
|
||||
|
||||
self.open_warning_window(payload, warning_text)
|
||||
return
|
||||
|
||||
try:
|
||||
slack_message = SlackMessage.objects.get(
|
||||
slack_id=payload["message"]["thread_ts"],
|
||||
_slack_team_identity=slack_team_identity,
|
||||
channel_id=channel_id,
|
||||
)
|
||||
except KeyError:
|
||||
self.open_warning_window(payload, warning_text)
|
||||
return
|
||||
except SlackMessage.DoesNotExist:
|
||||
if settings.UNIFIED_SLACK_APP_ENABLED:
|
||||
# Message shortcut events are broadcasted to multiple regions by chatops-proxy
|
||||
# Don't open a warning window as this event could be handled by another region
|
||||
return
|
||||
self.open_warning_window(payload, warning_text)
|
||||
return
|
||||
|
||||
|
|
@ -99,9 +112,17 @@ class AddToResolutionNoteStep(scenario_step.ScenarioStep):
|
|||
)
|
||||
return
|
||||
|
||||
if alert_group.channel.organization.deleted_at is not None:
|
||||
if settings.UNIFIED_SLACK_APP_ENABLED:
|
||||
# Message shortcut events are broadcasted to multiple regions by chatops-proxy
|
||||
# Don't open a warning window as this event could be handled by another region
|
||||
return
|
||||
|
||||
self.open_warning_window(payload, warning_text)
|
||||
return
|
||||
|
||||
if payload["message"]["type"] == "message" and "user" in payload["message"]:
|
||||
message_ts = payload["message_ts"]
|
||||
thread_ts = payload["message"]["thread_ts"]
|
||||
|
||||
result = self._slack_client.chat_getPermalink(channel=channel_id, message_ts=message_ts)
|
||||
permalink = None
|
||||
|
|
|
|||
|
|
@ -334,3 +334,111 @@ def test_resolution_notes_modal_closed_before_update(
|
|||
# Check that "views.update" API call was made
|
||||
call_args, _ = mock_slack_api_call.call_args
|
||||
assert call_args[0] == "views.update"
|
||||
|
||||
|
||||
@patch.object(SlackClient, "chat_getPermalink", return_value={"permalink": "https://example.com"})
|
||||
@pytest.mark.django_db
|
||||
def test_add_to_resolution_note(
|
||||
_,
|
||||
make_organization_and_user_with_slack_identities,
|
||||
make_alert_receive_channel,
|
||||
make_alert_group,
|
||||
make_alert,
|
||||
make_slack_message,
|
||||
settings,
|
||||
):
|
||||
organization, user, slack_team_identity, slack_user_identity = make_organization_and_user_with_slack_identities()
|
||||
alert_receive_channel = make_alert_receive_channel(organization)
|
||||
alert_group = make_alert_group(alert_receive_channel)
|
||||
make_alert(alert_group=alert_group, raw_request_data={})
|
||||
slack_message = make_slack_message(alert_group=alert_group)
|
||||
|
||||
payload = {
|
||||
"channel": {"id": slack_message.channel_id},
|
||||
"message_ts": "random_ts",
|
||||
"message": {
|
||||
"type": "message",
|
||||
"text": "Test resolution note",
|
||||
"ts": "random_ts",
|
||||
"thread_ts": slack_message.slack_id,
|
||||
"user": slack_user_identity.slack_id,
|
||||
},
|
||||
"trigger_id": "random_trigger_id",
|
||||
}
|
||||
|
||||
AddToResolutionNoteStep = ScenarioStep.get_step("resolution_note", "AddToResolutionNoteStep")
|
||||
step = AddToResolutionNoteStep(organization=organization, user=user, slack_team_identity=slack_team_identity)
|
||||
with patch.object(SlackClient, "reactions_add") as mock_reactions_add:
|
||||
step.process_scenario(slack_user_identity, slack_team_identity, payload)
|
||||
|
||||
mock_reactions_add.assert_called_once()
|
||||
assert alert_group.resolution_notes.get().text == "Test resolution note"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_add_to_resolution_note_broadcast(make_organization_and_user_with_slack_identities, settings):
|
||||
settings.UNIFIED_SLACK_APP_ENABLED = True
|
||||
|
||||
organization, user, slack_team_identity, slack_user_identity = make_organization_and_user_with_slack_identities()
|
||||
|
||||
payload = {
|
||||
"channel": {"id": "TEST"},
|
||||
"message_ts": "TEST",
|
||||
"message": {"thread_ts": "TEST"},
|
||||
"trigger_id": "TEST",
|
||||
}
|
||||
|
||||
AddToResolutionNoteStep = ScenarioStep.get_step("resolution_note", "AddToResolutionNoteStep")
|
||||
step = AddToResolutionNoteStep(organization=organization, user=user, slack_team_identity=slack_team_identity)
|
||||
with patch.object(SlackClient, "api_call") as mock_api_call:
|
||||
step.process_scenario(slack_user_identity, slack_team_identity, payload)
|
||||
|
||||
mock_api_call.assert_not_called() # no Slack API calls should be made
|
||||
|
||||
|
||||
@patch.object(SlackClient, "chat_getPermalink", return_value={"permalink": "https://example.com"})
|
||||
@pytest.mark.django_db
|
||||
def test_add_to_resolution_note_deleted_org(
|
||||
_,
|
||||
make_organization_and_user_with_slack_identities,
|
||||
make_alert_receive_channel,
|
||||
make_alert_group,
|
||||
make_alert,
|
||||
make_slack_message,
|
||||
make_organization,
|
||||
make_user_for_organization,
|
||||
settings,
|
||||
):
|
||||
settings.UNIFIED_SLACK_APP_ENABLED = True
|
||||
|
||||
organization, user, slack_team_identity, slack_user_identity = make_organization_and_user_with_slack_identities()
|
||||
alert_receive_channel = make_alert_receive_channel(organization)
|
||||
alert_group = make_alert_group(alert_receive_channel)
|
||||
make_alert(alert_group=alert_group, raw_request_data={})
|
||||
slack_message = make_slack_message(alert_group=alert_group)
|
||||
organization.delete()
|
||||
|
||||
other_organization = make_organization(slack_team_identity=slack_team_identity)
|
||||
other_user = make_user_for_organization(organization=other_organization, slack_user_identity=slack_user_identity)
|
||||
|
||||
payload = {
|
||||
"channel": {"id": slack_message.channel_id},
|
||||
"message_ts": "random_ts",
|
||||
"message": {
|
||||
"type": "message",
|
||||
"text": "Test resolution note",
|
||||
"ts": "random_ts",
|
||||
"thread_ts": slack_message.slack_id,
|
||||
"user": slack_user_identity.slack_id,
|
||||
},
|
||||
"trigger_id": "random_trigger_id",
|
||||
}
|
||||
|
||||
AddToResolutionNoteStep = ScenarioStep.get_step("resolution_note", "AddToResolutionNoteStep")
|
||||
step = AddToResolutionNoteStep(
|
||||
organization=other_organization, user=other_user, slack_team_identity=slack_team_identity
|
||||
)
|
||||
with patch.object(SlackClient, "api_call") as mock_api_call:
|
||||
step.process_scenario(slack_user_identity, slack_team_identity, payload)
|
||||
|
||||
mock_api_call.assert_not_called() # no Slack API calls should be made
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue