Mobile app FCM support (#923)
* Add ability to configure FCM_API_KEY and FCM_POST_URL * Delete APNSDevice and GCMDevice instances when unlinking the mobile app backend * Add a simple FCM relay endpoint * GCM -> FCM * comment
This commit is contained in:
parent
c08eeb72a3
commit
1878b7e596
5 changed files with 59 additions and 8 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from push_notifications.models import APNSDevice, GCMDevice
|
||||
|
||||
from apps.base.messaging import BaseMessagingBackend
|
||||
from apps.mobile_app.tasks import notify_user_async
|
||||
|
|
@ -33,6 +34,10 @@ class MobileAppBackend(BaseMessagingBackend):
|
|||
token = MobileAppAuthToken.objects.get(user=user)
|
||||
token.delete()
|
||||
|
||||
# delete push notification related info for user
|
||||
APNSDevice.objects.filter(user=user).delete()
|
||||
GCMDevice.objects.filter(user=user).delete()
|
||||
|
||||
def serialize_user(self, user):
|
||||
from apps.mobile_app.models import MobileAppAuthToken
|
||||
|
||||
|
|
|
|||
26
engine/apps/mobile_app/fcm_relay.py
Normal file
26
engine/apps/mobile_app/fcm_relay.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
from push_notifications.gcm import send_message
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
REQUIRED_FIELDS = {"registration_ids", "notification", "data"}
|
||||
|
||||
|
||||
class FCMRelayView(APIView):
|
||||
def post(self, request):
|
||||
"""
|
||||
This view accepts requests from OSS instances of Grafana OnCall and forwards these requests to FCM.
|
||||
Requests will be sent with the FCM_API_KEY configured in server settings
|
||||
(see PUSH_NOTIFICATIONS_SETTINGS in settings/base.py)
|
||||
"""
|
||||
|
||||
if not REQUIRED_FIELDS.issubset(request.data.keys()):
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
registration_ids = request.data["registration_ids"]
|
||||
data = {
|
||||
**request.data["data"],
|
||||
**request.data["notification"],
|
||||
}
|
||||
|
||||
return send_message(registration_ids=registration_ids, data=data, cloud_type="FCM")
|
||||
|
|
@ -1,13 +1,21 @@
|
|||
from apps.mobile_app.views import APNSDeviceAuthorizedViewSet, GCMDeviceAuthorizedViewSet, MobileAppAuthTokenAPIView
|
||||
from django.conf import settings
|
||||
|
||||
from apps.mobile_app.fcm_relay import FCMRelayView
|
||||
from apps.mobile_app.views import APNSDeviceAuthorizedViewSet, FCMDeviceAuthorizedViewSet, MobileAppAuthTokenAPIView
|
||||
from common.api_helpers.optional_slash_router import OptionalSlashRouter, optional_slash_path
|
||||
|
||||
app_name = "mobile_app"
|
||||
router = OptionalSlashRouter()
|
||||
|
||||
router.register("apns", APNSDeviceAuthorizedViewSet, basename="apns")
|
||||
router.register("gcm", GCMDeviceAuthorizedViewSet, basename="gcm")
|
||||
router.register("fcm", FCMDeviceAuthorizedViewSet, basename="fcm")
|
||||
|
||||
urlpatterns = [
|
||||
*router.urls,
|
||||
optional_slash_path("auth_token", MobileAppAuthTokenAPIView.as_view(), name="auth_token"),
|
||||
]
|
||||
|
||||
if settings.FCM_RELAY_ENABLED:
|
||||
urlpatterns += [
|
||||
optional_slash_path("fcm_relay", FCMRelayView.as_view(), name="fcm_relay"),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
from push_notifications.api.rest_framework import APNSDeviceAuthorizedViewSet as BaseAPNSDeviceAuthorizedViewSet
|
||||
from push_notifications.api.rest_framework import GCMDeviceAuthorizedViewSet as BaseGCMDeviceAuthorizedViewSet
|
||||
from push_notifications.api.rest_framework import GCMDeviceAuthorizedViewSet, GCMDeviceSerializer
|
||||
from rest_framework import status
|
||||
from rest_framework.exceptions import NotFound
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import HiddenField
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from apps.mobile_app.auth import MobileAppAuthTokenAuthentication, MobileAppVerificationTokenAuthentication
|
||||
|
|
@ -13,8 +14,17 @@ class APNSDeviceAuthorizedViewSet(BaseAPNSDeviceAuthorizedViewSet):
|
|||
authentication_classes = (MobileAppAuthTokenAuthentication,)
|
||||
|
||||
|
||||
class GCMDeviceAuthorizedViewSet(BaseGCMDeviceAuthorizedViewSet):
|
||||
class FCMDeviceAuthorizedViewSet(GCMDeviceAuthorizedViewSet):
|
||||
class FCMDeviceSerializer(GCMDeviceSerializer):
|
||||
"""
|
||||
GCMDevice has cloud_message_type equal to "GCM" by default, in this serializer cloud_message_type is always set
|
||||
to "FCM" no matter what was provided in the request.
|
||||
"""
|
||||
|
||||
cloud_message_type = HiddenField(default="FCM")
|
||||
|
||||
authentication_classes = (MobileAppAuthTokenAuthentication,)
|
||||
serializer_class = FCMDeviceSerializer
|
||||
|
||||
|
||||
class MobileAppAuthTokenAPIView(APIView):
|
||||
|
|
|
|||
|
|
@ -552,16 +552,18 @@ if FEATURE_MOBILE_APP_INTEGRATION_ENABLED:
|
|||
]
|
||||
|
||||
PUSH_NOTIFICATIONS_SETTINGS = {
|
||||
"FCM_API_KEY": os.environ.get("FCM_API_KEY", None),
|
||||
"GCM_API_KEY": os.environ.get("GCM_API_KEY", None),
|
||||
"FCM_API_KEY": os.getenv("FCM_API_KEY"),
|
||||
"FCM_POST_URL": os.getenv("FCM_POST_URL", default="https://fcm.googleapis.com/fcm/send"),
|
||||
"USER_MODEL": "user_management.User",
|
||||
"UPDATE_ON_DUPLICATE_REG_ID": True,
|
||||
# TODO: remove APNS related endpoints after the hackathon app is deprecated
|
||||
"APNS_AUTH_KEY_PATH": os.environ.get("APNS_AUTH_KEY_PATH", None),
|
||||
"APNS_TOPIC": os.environ.get("APNS_TOPIC", None),
|
||||
"APNS_AUTH_KEY_ID": os.environ.get("APNS_AUTH_KEY_ID", None),
|
||||
"APNS_TEAM_ID": os.environ.get("APNS_TEAM_ID", None),
|
||||
"APNS_USE_SANDBOX": getenv_boolean("APNS_USE_SANDBOX", True),
|
||||
"USER_MODEL": "user_management.User",
|
||||
"UPDATE_ON_DUPLICATE_REG_ID": True,
|
||||
}
|
||||
FCM_RELAY_ENABLED = getenv_boolean("FCM_RELAY_ENABLED", default=False)
|
||||
|
||||
SELF_HOSTED_SETTINGS = {
|
||||
"STACK_ID": 5,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue