diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3fd2e99d..5ab47fc734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move Insights to OnCall as a separate page ([#2382](https://github.com/grafana/oncall-private/issues/2382)) - Allow mobile app to access paging endpoint @imtoori ([#3619](https://github.com/grafana/oncall/pull/3619)) +- Create log record when there is a telegram formatting error in notification ([#3628](https://github.com/grafana/oncall/pull/3628)) ### Fixed diff --git a/engine/apps/base/models/user_notification_policy_log_record.py b/engine/apps/base/models/user_notification_policy_log_record.py index 2c20fc517e..a2383c5403 100644 --- a/engine/apps/base/models/user_notification_policy_log_record.py +++ b/engine/apps/base/models/user_notification_policy_log_record.py @@ -70,7 +70,8 @@ class UserNotificationPolicyLogRecord(models.Model): ERROR_NOTIFICATION_FORBIDDEN, ERROR_NOTIFICATION_TELEGRAM_USER_IS_DEACTIVATED, ERROR_NOTIFICATION_MOBILE_USER_HAS_NO_ACTIVE_DEVICE, - ) = range(28) + ERROR_NOTIFICATION_FORMATTING_ERROR, + ) = range(29) # for this errors we want to send message to general log channel ERRORS_TO_SEND_IN_SLACK_CHANNEL = [ @@ -270,6 +271,8 @@ def render_log_line_action(self, for_slack=False, substitute_author_with_tag=Fal == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MOBILE_USER_HAS_NO_ACTIVE_DEVICE ): result += f"failed to send push notification to {user_verbal} because user has no device set up" + elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_FORMATTING_ERROR: + result += f"failed to send message to {user_verbal} due to a formatting error" else: # TODO: handle specific backend errors try: diff --git a/engine/apps/telegram/models/connectors/personal.py b/engine/apps/telegram/models/connectors/personal.py index 9e988712a0..81a704dc81 100644 --- a/engine/apps/telegram/models/connectors/personal.py +++ b/engine/apps/telegram/models/connectors/personal.py @@ -113,6 +113,13 @@ def send_full_alert_group(self, alert_group: AlertGroup, notification_policy: Us alert_group=alert_group, ) except error.BadRequest: + TelegramToUserConnector.create_telegram_notification_error( + alert_group, + self.user, + notification_policy, + UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_FORMATTING_ERROR, + reason="Notification sent but there was a formatting error in the rendered template", + ) telegram_client.send_message( chat_id=self.telegram_chat_id, message_type=TelegramMessage.FORMATTING_ERROR, diff --git a/engine/apps/telegram/tests/test_personal_connector.py b/engine/apps/telegram/tests/test_personal_connector.py index 12c7e9a33d..11b0edf89c 100644 --- a/engine/apps/telegram/tests/test_personal_connector.py +++ b/engine/apps/telegram/tests/test_personal_connector.py @@ -1,4 +1,4 @@ -from unittest.mock import patch +from unittest.mock import call, patch import pytest from telegram import error @@ -186,3 +186,47 @@ def test_personal_connector_send_full_alert_group( log_record = notification_policy.personal_log_records.last() assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS + + +@patch.object(TelegramClient, "send_message", side_effect=[error.BadRequest("error"), None]) +@pytest.mark.django_db +def test_personal_connector_send_full_alert_group_formatting_error( + mock_send_message, + make_organization_and_user, + make_telegram_user_connector, + make_user_notification_policy, + make_alert_receive_channel, + make_alert_group, + make_alert, +): + # set up a user with Telegram account connected + organization, user = make_organization_and_user() + make_telegram_user_connector(user) + notification_policy = make_user_notification_policy( + user, + UserNotificationPolicy.Step.NOTIFY, + notify_by=UserNotificationPolicy.NotificationChannel.TELEGRAM, + important=False, + ) + + # create an alert group with an existing Telegram message in channel + 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=alert_receive_channel.config.example_payload) + + user.telegram_connection.send_full_alert_group(alert_group, notification_policy) + + failed_call, notification_call = mock_send_message.mock_calls + assert failed_call == call( + chat_id=user.telegram_connection.telegram_chat_id, + message_type=TelegramMessage.PERSONAL_MESSAGE, + alert_group=alert_group, + ) + assert notification_call == call( + chat_id=user.telegram_connection.telegram_chat_id, + message_type=TelegramMessage.FORMATTING_ERROR, + alert_group=alert_group, + ) + + log_record = notification_policy.personal_log_records.last() + assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED