Skip to content

Commit

Permalink
make things work with messaging backends
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyorlando committed Feb 8, 2024
1 parent 27ecdd4 commit c071ce6
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ def _preformat_request_data(self, request_data):
preformatted_data = request_data
return preformatted_data

def _preformat(self, data):
def _preformat(self, data: str) -> str:
return data

def _postformat(self, templated_alert):
def _postformat(self, templated_alert: TemplatedAlert) -> TemplatedAlert:
return templated_alert

def _apply_templates(self, data):
Expand Down

This file was deleted.

4 changes: 0 additions & 4 deletions engine/apps/alerts/models/alert_receive_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,6 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
alert_group_labels_template: str | None = models.TextField(null=True, default=None)
"""Stores a Jinja2 template for "advanced label templating" for alert group labels."""

mobile_app_title_template = models.TextField(null=True, default=None)
# TODO: should this be named "message" template or "subtitle" template
mobile_app_message_template = models.TextField(null=True, default=None)

class Meta:
constraints = [
# This constraint ensures that there's at most one active direct paging integration per team
Expand Down
4 changes: 1 addition & 3 deletions engine/apps/api/serializers/alert_receive_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ def _get_messaging_backend_templates(self, obj: "AlertReceiveChannel"):
is_default = False
if obj.messaging_backends_templates:
value = obj.messaging_backends_templates.get(backend_id, {}).get(field)
if not value:
if not value and not backend.skip_default_template_fields:
value = obj.get_default_template_attribute(backend_id, field)
is_default = True
field_name = f"{backend.slug}_{field}_template"
Expand Down Expand Up @@ -598,8 +598,6 @@ def core_templates_names(self) -> typing.List[str]:
"grouping_id_template",
"resolve_condition_template",
"acknowledge_condition_template",
"mobile_app_title_template",
"mobile_app_message_template",
]

if settings.FEATURE_SLACK_INTEGRATION_ENABLED:
Expand Down
1 change: 1 addition & 0 deletions engine/apps/base/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class BaseMessagingBackend:

templater = None
template_fields = ("title", "message", "image_url")
skip_default_template_fields = False

def __init__(self, *args, **kwargs):
self.notification_channel_id = kwargs.get("notification_channel_id")
Expand Down
73 changes: 26 additions & 47 deletions engine/apps/mobile_app/alert_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,56 @@

from emoji import emojize

from apps.alerts.incident_appearance.templaters.alert_templater import AlertTemplater
from apps.alerts.incident_appearance.templaters.alert_templater import AlertTemplater, TemplatedAlert
from apps.alerts.models import AlertGroup
from apps.labels.alert_group_labels import gather_labels_from_alert_receive_channel_and_raw_request_data
from common.jinja_templater.apply_jinja_template import (
JinjaTemplateError,
JinjaTemplateWarning,
apply_jinja_template_to_alert_payload_and_labels,
)
from common.utils import str_or_backup

MAX_ALERT_TITLE_LENGTH = 200
"""
NOTE: technically FCM limits the data we send based on total # of bytes, not characters for title/subtitle. For now
lets simply limit the title and subtitle to 200 characters and see how that goes with avoiding the `message is too big`
FCM exception

https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode
"""
def _validate_fcm_length_limit(value: typing.Optional[str]) -> str:
"""
NOTE: technically FCM limits the data we send based on total # of bytes, not characters for title/subtitle. For now
lets simply limit the title and subtitle to 200 characters and see how that goes with avoiding the `message is too big`
FCM exception
https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode
"""
MAX_ALERT_TITLE_LENGTH = 200

if value is None:
return ""
return f"{value[:MAX_ALERT_TITLE_LENGTH]}..." if len(value) > MAX_ALERT_TITLE_LENGTH else value


class AlertMobileAppTemplater(AlertTemplater):
def _render_for(self):
return "MOBILE_APP"

def _postformat(self, templated_alert: TemplatedAlert) -> TemplatedAlert:
templated_alert.title = _validate_fcm_length_limit(templated_alert.title)
templated_alert.message = _validate_fcm_length_limit(templated_alert.message)
return templated_alert

def _templatize_alert(
alert_group: AlertGroup,
integration_attribute: typing.Literal["mobile_app_title_template", "mobile_app_message_template"],
) -> typing.Optional[str]:
alert = alert_group.alerts.first()
alert_receive_channel = alert_group.channel
alert_payload = alert.raw_request_data

parsed_labels = gather_labels_from_alert_receive_channel_and_raw_request_data(alert_receive_channel, alert_payload)

try:
return apply_jinja_template_to_alert_payload_and_labels(
getattr(alert_receive_channel, integration_attribute),
alert.raw_request_data,
parsed_labels,
result_length_limit=MAX_ALERT_TITLE_LENGTH,
)
except (JinjaTemplateError, JinjaTemplateWarning):
return None
def _templatize_alert(alert_group: AlertGroup) -> TemplatedAlert:
alert = alert_group.alerts.first()
return AlertMobileAppTemplater(alert).render()


def get_push_notification_title(alert_group: AlertGroup, critical: bool) -> str:
def _determine_title() -> str:
return "New Important Alert" if critical else "New Alert"

if not alert_group.channel.mobile_app_title_template:
return _determine_title()

return _templatize_alert(alert_group, "mobile_app_title_template") or _determine_title()
return _templatize_alert(alert_group).title or ("New Important Alert" if critical else "New Alert")


def get_push_notification_subtitle(alert_group: AlertGroup) -> str:
if alert_group.channel.mobile_app_message_template is not None:
templatized_subtitle = _templatize_alert(alert_group).message
if templatized_subtitle:
# only return the templatized subtitle if it resolves to something that is not None
# otherwise fallback to the default
templatized_subtitle = _templatize_alert(alert_group, "mobile_app_message_template")

if templatized_subtitle:
return templatized_subtitle
return templatized_subtitle

alert = alert_group.alerts.first()
templated_alert = AlertMobileAppTemplater(alert).render()

alert_title = str_or_backup(templated_alert.title, "Alert Group")
if len(alert_title) > MAX_ALERT_TITLE_LENGTH:
alert_title = f"{alert_title[:MAX_ALERT_TITLE_LENGTH]}..."
alert_title = _validate_fcm_length_limit(str_or_backup(templated_alert.title, "Alert Group"))

status_verbose = "Firing" # TODO: we should probably de-duplicate this text
if alert_group.resolved:
Expand Down
12 changes: 4 additions & 8 deletions engine/apps/mobile_app/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ class MobileAppBackend(BaseMessagingBackend):
label = "Mobile push"
short_label = "Mobile push"
available_for_use = True
template_fields = ["title"]

templater = "apps.mobile_app.alert_rendering.AlertMobileAppTemplater"
template_fields = ("title", "message")
skip_default_template_fields = True

def generate_user_verification_code(self, user):
from apps.mobile_app.models import MobileAppVerificationToken
Expand Down Expand Up @@ -51,13 +54,6 @@ def notify_user(self, user, alert_group, notification_policy, critical=False):
critical=critical,
)

@property
def customizable_templates(self):
"""
Disable customization if templates for mobile app
"""
return False


class MobileAppCriticalBackend(MobileAppBackend):
"""
Expand Down
Loading

0 comments on commit c071ce6

Please sign in to comment.