Repository: zulip/zulip

Issue:
internationalization or configuration of ***REDACTED*** message in push notifications
for now, redacted message in push notifications does not honour internationalization and also is not configurable. 

apparently it's hard-coded string in 

```
# cat zerver/lib/push_notifications.py |grep -C3 REDACTED
        return plain_text

    if settings.PUSH_NOTIFICATION_REDACT_CONTENT:
        return "***REDACTED***"

    elem = lxml.html.fromstring(rendered_content)
    plain_text = process(elem)
```

please make that string at least configurable via /etc/zulip config files, so non-english speaking users get a better clue what that really means. 

it would also be good to explain, why it's being redacted at all, so i would like to replace that message with something like "Inhalt aus Datenschutzgründen nicht übermittelt" (content not transmitted for reason of data protection).

i'm no native english speaker, but i know english to some degree and even me needed to consult a dictionary to get the proper meaning of this word. dict.cc telling redacted is "euphemism for: censored" , and nobody likes censorship....






Discussion:
Hello @zulip/server-i18n members, this issue was labeled with the "area: i18n" label, so you may want to check it out!

<!-- areaLabelAddition -->
Yeah, this should just be tagged for translation.  I'd also consider just changing the string; I'm not sure "redacted" is what I'd choose.

Resolving patch:
diff --git a/zerver/lib/push_notifications.py b/zerver/lib/push_notifications.py
--- a/zerver/lib/push_notifications.py
+++ b/zerver/lib/push_notifications.py
@@ -14,6 +14,7 @@
 from django.db.models import F
 from django.utils.timezone import now as timezone_now
 from django.utils.translation import gettext as _
+from django.utils.translation import override as override_language
 
 from zerver.decorator import statsd_increment
 from zerver.lib.avatar import absolute_avatar_url
@@ -629,7 +630,13 @@ def process(elem: lxml.html.HtmlElement) -> str:
         return plain_text
 
     if settings.PUSH_NOTIFICATION_REDACT_CONTENT:
-        return "***REDACTED***"
+        return (
+            "*"
+            + _(
+                "This organization has disabled including message content in mobile push notifications"
+            )
+            + "*"
+        )
 
     elem = lxml.html.fromstring(rendered_content)
     plain_text = process(elem)
@@ -744,17 +751,18 @@ def get_message_payload_apns(user_profile: UserProfile, message: Message) -> Dic
     )
 
     assert message.rendered_content is not None
-    content, _ = truncate_content(get_mobile_push_content(message.rendered_content))
-    apns_data = {
-        "alert": {
-            "title": get_apns_alert_title(message),
-            "subtitle": get_apns_alert_subtitle(message),
-            "body": content,
-        },
-        "sound": "default",
-        "badge": get_apns_badge_count(user_profile),
-        "custom": {"zulip": zulip_data},
-    }
+    with override_language(user_profile.default_language):
+        content, _ = truncate_content(get_mobile_push_content(message.rendered_content))
+        apns_data = {
+            "alert": {
+                "title": get_apns_alert_title(message),
+                "subtitle": get_apns_alert_subtitle(message),
+                "body": content,
+            },
+            "sound": "default",
+            "badge": get_apns_badge_count(user_profile),
+            "custom": {"zulip": zulip_data},
+        }
     return apns_data
 
 
@@ -765,17 +773,18 @@ def get_message_payload_gcm(
     """A `message` payload + options, for Android via GCM/FCM."""
     data = get_message_payload(user_profile, message)
     assert message.rendered_content is not None
-    content, truncated = truncate_content(get_mobile_push_content(message.rendered_content))
-    data.update(
-        event="message",
-        alert=get_gcm_alert(message),
-        zulip_message_id=message.id,  # message_id is reserved for CCS
-        time=datetime_to_timestamp(message.date_sent),
-        content=content,
-        content_truncated=truncated,
-        sender_full_name=message.sender.full_name,
-        sender_avatar_url=absolute_avatar_url(message.sender),
-    )
+    with override_language(user_profile.default_language):
+        content, truncated = truncate_content(get_mobile_push_content(message.rendered_content))
+        data.update(
+            event="message",
+            alert=get_gcm_alert(message),
+            zulip_message_id=message.id,  # message_id is reserved for CCS
+            time=datetime_to_timestamp(message.date_sent),
+            content=content,
+            content_truncated=truncated,
+            sender_full_name=message.sender.full_name,
+            sender_avatar_url=absolute_avatar_url(message.sender),
+        )
     gcm_options = {"priority": "high"}
     return data, gcm_options
 


Test patch:
diff --git a/zerver/tests/test_push_notifications.py b/zerver/tests/test_push_notifications.py
--- a/zerver/tests/test_push_notifications.py
+++ b/zerver/tests/test_push_notifications.py
@@ -1661,7 +1661,7 @@ def test_get_message_payload_apns_redacted_content(self) -> None:
             "alert": {
                 "title": "Cordelia, Lear's daughter, King Hamlet, Othello, the Moor of Venice",
                 "subtitle": "King Hamlet:",
-                "body": "***REDACTED***",
+                "body": "*This organization has disabled including message content in mobile push notifications*",
             },
             "sound": "default",
             "badge": 0,
@@ -1807,7 +1807,7 @@ def test_get_message_payload_gcm_redacted_content(self) -> None:
                 "alert": "New stream message from King Hamlet in Denmark",
                 "zulip_message_id": message.id,
                 "time": datetime_to_timestamp(message.date_sent),
-                "content": "***REDACTED***",
+                "content": "*This organization has disabled including message content in mobile push notifications*",
                 "content_truncated": False,
                 "server": settings.EXTERNAL_HOST,
                 "realm_id": hamlet.realm.id,