* move mobile notifications to a separate backend, remove critical notification * remove outdated mobile app code * MOBILE_APP_PUSH_NOTIFICATIONS_ENABLED -> FEATURE_MOBILE_APP_INTEGRATION_ENABLED * create error log if no devices are set up * move mobile auth related code to the mobile_app Django app * move mobile auth related code to the mobile_app Django app * move mobile auth related code to the mobile_app Django app * fix typing * add GCMDevice todos * add user connection capabilities * add user connect/disconnect to the messaging backend * move APNS endpoint to mobile_app Django app * restore critical notifications * support hackathon app * tweak migrations so mobile app auth tokens are preserved * reuse notify_by IDs * use mobile app template to render push notification * add GCM/FCM (Android) support * fix unlink user * logger.error -> logger.info
95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
from celery.utils.log import get_task_logger
|
|
from django.conf import settings
|
|
from push_notifications.models import APNSDevice, GCMDevice
|
|
|
|
from apps.alerts.models import AlertGroup
|
|
from apps.mobile_app.alert_rendering import get_push_notification_message
|
|
from apps.user_management.models import User
|
|
from common.custom_celery_tasks import shared_dedicated_queue_retry_task
|
|
|
|
MAX_RETRIES = 1 if settings.DEBUG else 10
|
|
logger = get_task_logger(__name__)
|
|
|
|
|
|
@shared_dedicated_queue_retry_task(autoretry_for=(Exception,), retry_backoff=True, max_retries=MAX_RETRIES)
|
|
def notify_user_async(user_pk, alert_group_pk, notification_policy_pk, critical):
|
|
# avoid circular import
|
|
from apps.base.models import UserNotificationPolicy, UserNotificationPolicyLogRecord
|
|
|
|
try:
|
|
user = User.objects.get(pk=user_pk)
|
|
except User.DoesNotExist:
|
|
logger.warning(f"User {user_pk} does not exist")
|
|
return
|
|
|
|
try:
|
|
alert_group = AlertGroup.all_objects.get(pk=alert_group_pk)
|
|
except AlertGroup.DoesNotExist:
|
|
logger.warning(f"Alert group {alert_group_pk} does not exist")
|
|
return
|
|
|
|
try:
|
|
notification_policy = UserNotificationPolicy.objects.get(pk=notification_policy_pk)
|
|
except UserNotificationPolicy.DoesNotExist:
|
|
logger.warning(f"User notification policy {notification_policy_pk} does not exist")
|
|
return
|
|
|
|
# APNS is for notifying iOS devices, GCM for Android
|
|
apns_devices_to_notify = APNSDevice.objects.filter(user=user)
|
|
gcm_devices_to_notify = GCMDevice.objects.filter(user=user)
|
|
|
|
# create an error log in case user has no devices set up
|
|
if not apns_devices_to_notify.exists() and not gcm_devices_to_notify.exists():
|
|
UserNotificationPolicyLogRecord.objects.create(
|
|
author=user,
|
|
type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
|
|
notification_policy=notification_policy,
|
|
alert_group=alert_group,
|
|
reason="Mobile push notification error",
|
|
notification_step=notification_policy.step,
|
|
notification_channel=notification_policy.notify_by,
|
|
)
|
|
logger.info(f"Error while sending a mobile push notification: user {user_pk} has no devices set up")
|
|
return
|
|
|
|
message = get_push_notification_message(alert_group)
|
|
thread_id = f"{alert_group.channel.organization.public_primary_key}:{alert_group.public_primary_key}"
|
|
|
|
if critical:
|
|
aps = {
|
|
"alert": f"Critical page: {message}",
|
|
"interruption-level": "critical",
|
|
"sound": "ambulance.aiff",
|
|
}
|
|
else:
|
|
aps = {
|
|
"alert": message,
|
|
"sound": "bingbong.aiff",
|
|
}
|
|
|
|
apns_devices_to_notify.send_message(
|
|
message,
|
|
thread_id=thread_id,
|
|
category="USER_NEW_INCIDENT", # TODO: rename to USER_NEW_ALERT_GROUP
|
|
extra={
|
|
"orgId": alert_group.channel.organization.public_primary_key,
|
|
"orgName": alert_group.channel.organization.stack_slug,
|
|
"alertGroupId": alert_group.public_primary_key,
|
|
"incidentId": alert_group.public_primary_key, # TODO: remove after hackathon app is deprecated
|
|
"status": alert_group.status,
|
|
"aps": aps,
|
|
},
|
|
)
|
|
|
|
gcm_devices_to_notify.send_message(
|
|
message,
|
|
thread_id=thread_id,
|
|
category="USER_NEW_INCIDENT", # TODO: rename to USER_NEW_ALERT_GROUP
|
|
extra={
|
|
"orgId": alert_group.channel.organization.public_primary_key,
|
|
"orgName": alert_group.channel.organization.stack_slug,
|
|
"alertGroupId": alert_group.public_primary_key,
|
|
"status": alert_group.status,
|
|
"aps": aps,
|
|
},
|
|
)
|