jazzband / django-push-notifications

Send push notifications to mobile devices through GCM or APNS in Django.
MIT License
2.24k stars 605 forks source link

[WebPush] Support for Safari #673

Closed blighj closed 9 months ago

blighj commented 1 year ago

Safari 16.1 on Mac OS Ventura supports WebPush, with the potential for it to come to iOS in 2023

It will need a code change to make it work with django-push-notifications.

As I understand it, when you register for a push notifaction on the client side, the browser gives you the full endpoint url to use. The way it is modeled in the code here, is that we only want the last part of the path from the endpoint url (some sort of token) and will determine the full endpoint url based on pre configured settings for each browser. These settings don't exist for Safari yet.

Apple and Microsoft seem to have made the same implementation decision where the push notifaction endpoints can actually be one of multiple domains, (.notify.windows.com, .push.apple.com). So fixing a browser to just one endpoint may not be the best way to model the standard.

Would it be perferable to store the full endpoint url given by the browser in the registration_id of the model, instead of just the token and use exactly what the browser gave us when we send the message. We could depercate the old way, but still support it for a while with a fallback. https://github.com/jazzband/django-push-notifications/blob/a20819258cc33ed7855db7231831bb9231dfe1ca/push_notifications/webpush.py#L7

def get_subscription_info(application_id, uri, browser, auth, p256dh):
-   url = get_manager().get_wp_post_url(application_id, browser)
+   if uri.startswith("https://"):
+       endpoint = uri
+   else:
+       url = get_manager().get_wp_post_url(application_id, browser)
+       endpoint = "{}/{}".format(url, uri) 
    return {
-       "endpoint": "{}/{}".format(url, uri),
+       "endpoint": endpoint,
        "keys": {
            "auth": auth,
            "p256dh": p256dh,
        }
    }

If people are happy with that general approach I can do up a PR with updated docs and tests.

viktorisacenko commented 1 year ago

If you want to add webpush for Safari 16+ you need only to add the Browser type for safari in the models

push_notifications.models.py

BROWSER_TYPES = (
    ("CHROME", "Chrome"),
    ("FIREFOX", "Firefox"),
    ("OPERA", "Opera"),
    ("EDGE", "Edge"),
        ("SAFARI", "Safari") <--------------
)

and in the push_notifications.settings.py the new push service for apple

# WP (WebPush)
PUSH_NOTIFICATIONS_SETTINGS.setdefault("WP_POST_URL", {
    "CHROME": PUSH_NOTIFICATIONS_SETTINGS["FCM_POST_URL"],
    "OPERA": PUSH_NOTIFICATIONS_SETTINGS["FCM_POST_URL"],
    "FIREFOX": "https://updates.push.services.mozilla.com/wpush/v2",
    "EDGE": "https://wns2-par02p.notify.windows.com/w",
        "SAFARI": "https://web.push.apple.com",   <--------------
})

Nothing else. Then it works like charm :)

blighj commented 9 months ago

Solved by merge of #674