From 9f3f691ea4010ccf9ef7e1d02aa3d4154d83ab4a Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 28 Sep 2022 16:59:57 +0200 Subject: [PATCH] Feat 549 - add telegram permalink to alert groups http response (#551) * rename AlertGroup.permalink to slack_permalink * add telegram key to alert_groups permalinks object in public API response --- CHANGELOG.md | 6 ++++- .../oncall-api-reference/alertgroups.md | 3 ++- .../renderers/email_renderer.py | 2 +- .../renderers/sms_renderer.py | 4 ++- engine/apps/alerts/models/alert_group.py | 25 ++++++++++++++++--- engine/apps/api/serializers/alert_group.py | 2 +- .../apps/public_api/serializers/incidents.py | 11 +++++++- .../apps/public_api/tests/test_incidents.py | 1 + .../apps/slack/scenarios/distribute_alerts.py | 4 +-- .../src/models/alertgroup/alertgroup.types.ts | 2 +- .../src/pages/incident/Incident.tsx | 2 +- 11 files changed, 49 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df1284de..b1cdd055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Change Log -## v1.0.37 (2022-09-23) +## v1.0.38 (2022-09-22) + +- Add `telegram` key to `permalinks` property in `AlertGroup` public API response schema + +## v1.0.37 (2022-09-21) - Improve API token creation form - Fix alert group bulk action bugs diff --git a/docs/sources/oncall-api-reference/alertgroups.md b/docs/sources/oncall-api-reference/alertgroups.md index 8b673b64..8e90f6d3 100644 --- a/docs/sources/oncall-api-reference/alertgroups.md +++ b/docs/sources/oncall-api-reference/alertgroups.md @@ -35,7 +35,8 @@ The above command returns JSON structured in the following way: "acknowledged_at": null, "title": "Memory above 90% threshold", "permalinks": { - "slack": null + "slack": "https://ghostbusters.slack.com/archives/C1H9RESGA/p135854651500008", + "telegram": "https://t.me/c/5354/1234?thread=1234" } } ] diff --git a/engine/apps/alerts/incident_appearance/renderers/email_renderer.py b/engine/apps/alerts/incident_appearance/renderers/email_renderer.py index 5107988b..eb18e190 100644 --- a/engine/apps/alerts/incident_appearance/renderers/email_renderer.py +++ b/engine/apps/alerts/incident_appearance/renderers/email_renderer.py @@ -29,7 +29,7 @@ class AlertGroupEmailRenderer(AlertGroupBaseRenderer): content = render_to_string( "email_notification.html", { - "url": self.alert_group.permalink or self.alert_group.web_link, + "url": self.alert_group.slack_permalink or self.alert_group.web_link, "title": str_or_backup(templated_alert.title, title_fallback), "message": str_or_backup(templated_alert.message, ""), # not render message it all if smth go wrong "amixr_team": self.alert_group.channel.organization, diff --git a/engine/apps/alerts/incident_appearance/renderers/sms_renderer.py b/engine/apps/alerts/incident_appearance/renderers/sms_renderer.py index c050e4ee..13924771 100644 --- a/engine/apps/alerts/incident_appearance/renderers/sms_renderer.py +++ b/engine/apps/alerts/incident_appearance/renderers/sms_renderer.py @@ -18,7 +18,9 @@ class AlertGroupSmsRenderer(AlertGroupBaseRenderer): def render(self): templated_alert = self.alert_renderer.templated_alert title = str_or_backup(templated_alert.title, DEFAULT_BACKUP_TITLE) - if self.alert_group.channel.organization.slack_team_identity and (permalink := self.alert_group.permalink): + if self.alert_group.channel.organization.slack_team_identity and ( + permalink := self.alert_group.slack_permalink + ): incident_link = permalink else: incident_link = self.alert_group.web_link diff --git a/engine/apps/alerts/models/alert_group.py b/engine/apps/alerts/models/alert_group.py index 7b4681fd..cb08e8e1 100644 --- a/engine/apps/alerts/models/alert_group.py +++ b/engine/apps/alerts/models/alert_group.py @@ -401,15 +401,34 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. raise NotImplementedError @property - def permalink(self): + def slack_permalink(self): if self.slack_message is not None: return self.slack_message.permalink + @property + def telegram_permalink(self) -> typing.Optional[str]: + """ + This property will attempt to access an attribute, `prefetched_telegram_messages`, representing a list of + prefetched telegram messages. If this attribute does not exist, it falls back to performing a query. + + See `apps.public_api.serializers.incidents.IncidentSerializer.PREFETCH_RELATED` as an example. + """ + from apps.telegram.models.message import TelegramMessage + + if hasattr(self, "prefetched_telegram_messages"): + return self.prefetched_telegram_messages[0].link if self.prefetched_telegram_messages else None + + main_telegram_message = self.telegram_messages.filter( + chat_id__startswith="-", message_type=TelegramMessage.ALERT_GROUP_MESSAGE + ).first() + + return main_telegram_message.link if main_telegram_message else None + @property def permalinks(self) -> Permalinks: - # TODO: refactor 'permalink' property (maybe 'slack_permalink'?) once we add the next permalink return { - "slack": self.permalink, + "slack": self.slack_permalink, + "telegram": self.telegram_permalink, } @property diff --git a/engine/apps/api/serializers/alert_group.py b/engine/apps/api/serializers/alert_group.py index f9ecf443..a71cfde2 100644 --- a/engine/apps/api/serializers/alert_group.py +++ b/engine/apps/api/serializers/alert_group.py @@ -132,7 +132,7 @@ class AlertGroupSerializer(AlertGroupListSerializer): fields = AlertGroupListSerializer.Meta.fields + [ "alerts", "render_after_resolve_report_json", - "permalink", + "slack_permalink", "last_alert_at", ] diff --git a/engine/apps/public_api/serializers/incidents.py b/engine/apps/public_api/serializers/incidents.py index 5010f88f..00ec64f6 100644 --- a/engine/apps/public_api/serializers/incidents.py +++ b/engine/apps/public_api/serializers/incidents.py @@ -1,6 +1,8 @@ +from django.db.models import Prefetch from rest_framework import serializers from apps.alerts.models import AlertGroup +from apps.telegram.models.message import TelegramMessage from common.api_helpers.mixins import EagerLoadingMixin @@ -15,7 +17,14 @@ class IncidentSerializer(EagerLoadingMixin, serializers.ModelSerializer): state = serializers.SerializerMethodField() SELECT_RELATED = ["channel", "channel_filter", "slack_message"] - PREFETCH_RELATED = ["alerts"] + PREFETCH_RELATED = [ + "alerts", + Prefetch( + "telegram_messages", + TelegramMessage.objects.filter(chat_id__startswith="-", message_type=TelegramMessage.ALERT_GROUP_MESSAGE), + to_attr="prefetched_telegram_messages", + ), + ] class Meta: model = AlertGroup diff --git a/engine/apps/public_api/tests/test_incidents.py b/engine/apps/public_api/tests/test_incidents.py index 73685c25..45a5d115 100644 --- a/engine/apps/public_api/tests/test_incidents.py +++ b/engine/apps/public_api/tests/test_incidents.py @@ -41,6 +41,7 @@ def construct_expected_response_from_incidents(incidents): "title": None, "permalinks": { "slack": None, + "telegram": None, }, } ) diff --git a/engine/apps/slack/scenarios/distribute_alerts.py b/engine/apps/slack/scenarios/distribute_alerts.py index 109577b1..91814f6d 100644 --- a/engine/apps/slack/scenarios/distribute_alerts.py +++ b/engine/apps/slack/scenarios/distribute_alerts.py @@ -354,9 +354,9 @@ class SelectAttachGroupStep( f"attached incidents ({attached_incidents.count()}):\n" ) for dependent_alert in attached_incidents: - if dependent_alert.permalink: + if dependent_alert.slack_permalink: dependent_alert_text = ( - f"\n<{dependent_alert.permalink}|{dependent_alert.long_verbose_name_without_formatting}>" + f"\n<{dependent_alert.slack_permalink}|{dependent_alert.long_verbose_name_without_formatting}>" ) else: dependent_alert_text = f"\n{dependent_alert.long_verbose_name}" diff --git a/grafana-plugin/src/models/alertgroup/alertgroup.types.ts b/grafana-plugin/src/models/alertgroup/alertgroup.types.ts index d704c34e..d7e55b4f 100644 --- a/grafana-plugin/src/models/alertgroup/alertgroup.types.ts +++ b/grafana-plugin/src/models/alertgroup/alertgroup.types.ts @@ -55,7 +55,7 @@ export interface Alert { acknowledged_by_user: User; acknowledged_on_source: boolean; channel: Channel; - permalink?: string; + slack_permalink?: string; related_users: User[]; render_after_resolve_report_json?: TimeLineItem[]; render_for_slack: { attachments: any[] }; diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx index ca4eb213..cb291724 100644 --- a/grafana-plugin/src/pages/incident/Incident.tsx +++ b/grafana-plugin/src/pages/incident/Incident.tsx @@ -297,7 +297,7 @@ class IncidentPage extends React.Component Copy Link - +