diff --git a/CHANGELOG.md b/CHANGELOG.md index 59c7d8cd..5ca44d09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ([Use Tilt for local development](https://github.com/grafana/oncall/pull/1396)) +### Changed + +- Update slack schedule shift-changed notification ([#2949](https://github.com/grafana/oncall/pull/2949)) + ## v1.3.30 (2023-08-31) ### Added diff --git a/engine/apps/alerts/tests/test_notify_ical_schedule_shift.py b/engine/apps/alerts/tests/test_notify_ical_schedule_shift.py index 5f7ab590..bce4da6d 100644 --- a/engine/apps/alerts/tests/test_notify_ical_schedule_shift.py +++ b/engine/apps/alerts/tests/test_notify_ical_schedule_shift.py @@ -104,9 +104,10 @@ def test_next_shift_notification_long_shifts( notify_ical_schedule_shift(ical_schedule.pk) slack_blocks = mock_slack_api_call.call_args_list[0][1]["blocks"] - notification = slack_blocks[0]["text"]["text"] - assert "*New on-call shift:*\nuser2" in notification - assert "*Next on-call shift:*\nuser1" in notification + notification = slack_blocks[1]["text"]["text"] + assert "*New on-call shift*\nuser2" in notification + notification = slack_blocks[2]["text"]["text"] + assert "*Next on-call shift*\nuser1" in notification @pytest.mark.django_db @@ -366,7 +367,7 @@ def test_current_shift_changes_swap_split( with patch("apps.slack.client.SlackClientWithErrorHandling.chat_postMessage") as mock_slack_api_call: notify_ical_schedule_shift(schedule.pk) - text_block = mock_slack_api_call.call_args_list[0][1]["blocks"][0]["text"]["text"] + text_block = mock_slack_api_call.call_args_list[0][1]["blocks"][1]["text"]["text"] assert "user2" in text_block if swap_taken else "user1" in text_block @@ -817,9 +818,9 @@ def test_next_shift_notification_long_and_short_shifts( notify_ical_schedule_shift(schedule.pk) assert mock_slack_api_call.called - notification = mock_slack_api_call.call_args[1]["blocks"][0]["text"]["text"] - new_shift_notification, next_shift_notification = notification.split("\n\n") + new_shift_notification = mock_slack_api_call.call_args[1]["blocks"][1]["text"]["text"] + next_shift_notification = mock_slack_api_call.call_args[1]["blocks"][2]["text"]["text"] - assert "*New on-call shift:*\n[L1] user1" in new_shift_notification + assert "*New on-call shift*\n[L1] user1" in new_shift_notification assert "[L1] user3" in new_shift_notification - assert "*Next on-call shift:*\n[L1] user2" in notification + assert "*Next on-call shift*\n[L1] user2" in next_shift_notification diff --git a/engine/apps/slack/scenarios/schedules.py b/engine/apps/slack/scenarios/schedules.py index c28e58cc..d9c58290 100644 --- a/engine/apps/slack/scenarios/schedules.py +++ b/engine/apps/slack/scenarios/schedules.py @@ -14,7 +14,7 @@ from apps.slack.types import ( PayloadType, ScenarioRoute, ) -from apps.slack.utils import format_datetime_to_slack_with_time +from apps.slack.utils import SlackDateFormat, format_datetime_to_slack_with_time from common.insight_log import EntityEvent, write_resource_insight_log if typing.TYPE_CHECKING: @@ -183,7 +183,8 @@ class EditScheduleShiftNotifyStep(scenario_step.ScenarioStep): user_ids_from_shift = [u["pk"] for u in users] users = organization.users.filter(public_primary_key__in=user_ids_from_shift) now_text += cls.get_ical_shift_notification_text(shift, schedule.mention_oncall_start, users) - now_text = "*New on-call shift:*\n" + now_text + + now_text = "*New on-call shift*\n" + now_text if len(next_shifts) == 0: if len(new_shifts) == 0: @@ -197,9 +198,8 @@ class EditScheduleShiftNotifyStep(scenario_step.ScenarioStep): user_ids_from_shift = [u["pk"] for u in users] users = organization.users.filter(public_primary_key__in=user_ids_from_shift) next_text += cls.get_ical_shift_notification_text(shift, schedule.mention_oncall_next, users) - next_text = "\n*Next on-call shift:*\n" + next_text + next_text = "\n*Next on-call shift*\n" + next_text - text = f"{now_text}{next_text}" blocks: Block.AnyBlocks = [ typing.cast( Block.Section, @@ -207,7 +207,29 @@ class EditScheduleShiftNotifyStep(scenario_step.ScenarioStep): "type": "section", "text": { "type": "mrkdwn", - "text": text, + "text": f"On-call shifts update for schedule *<{schedule.web_detail_page_link}|{schedule.name}>*", + "verbatim": True, + }, + }, + ), + typing.cast( + Block.Section, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": now_text, + "verbatim": True, + }, + }, + ), + typing.cast( + Block.Section, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": next_text, "verbatim": True, }, }, @@ -226,18 +248,6 @@ class EditScheduleShiftNotifyStep(scenario_step.ScenarioStep): ], }, ), - typing.cast( - Block.Context, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": f"On-call schedule *{schedule.name}*", - }, - ], - }, - ), ] return blocks @@ -246,20 +256,20 @@ class EditScheduleShiftNotifyStep(scenario_step.ScenarioStep): notification = "" for user in users: if shift["all_day"]: - user_notification = user.get_username_with_slack_verbal(mention=mention) + user_notification = user.get_username_with_slack_verbal(mention=mention) + "\n" if shift["start"].day == shift["end"].day: all_day_text = shift["start"].strftime("%b %d") else: - all_day_text = f'From {shift["start"].strftime("%b %d")} to {shift["end"].strftime("%b %d")}' + all_day_text = f'{shift["start"].strftime("%b %d")} - {shift["end"].strftime("%b %d")}' user_notification += f' {all_day_text} _All-day event in timezone "UTC"_\n' else: shift_start_timestamp = shift["start"].astimezone(pytz.UTC).timestamp() shift_end_timestamp = shift["end"].astimezone(pytz.UTC).timestamp() + start_timestamp = format_datetime_to_slack_with_time(shift_start_timestamp, SlackDateFormat.DATE_LONG) + end_timestamp = format_datetime_to_slack_with_time(shift_end_timestamp, SlackDateFormat.DATE_LONG) user_notification = ( - user.get_username_with_slack_verbal(mention=mention) - + f" from {format_datetime_to_slack_with_time(shift_start_timestamp)}" - f" to {format_datetime_to_slack_with_time(shift_end_timestamp)}\n" + user.get_username_with_slack_verbal(mention=mention) + f"\n{start_timestamp} - {end_timestamp}\n" ) if not shift["is_override"]: priority = shift.get("priority_level", 0) or 0