django-push-notifications
django-push-notifications copied to clipboard
How to setup properly just for web?
I want to setup push notification for website. I just follwed as described in documenation but Unfurtunately it is now working.
Here is my settings.
PUSH_NOTIFICATIONS_SETTINGS = {
"WP_PRIVATE_KEY": BASE_DIR / 'private_key.perm',
"WP_CLAIMS": {'sub': "mailto: [email protected]"}
}
and here is my client side code
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Push Notifications</title>
</head>
<body>
<h1>Push Notification Example</h1>
<script>
// Utils functions:
function urlBase64ToUint8Array(base64String) {
var padding = '='.repeat((4 - base64String.length % 4) % 4)
var base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/')
var rawData = window.atob(base64)
var outputArray = new Uint8Array(rawData.length)
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i)
}
return outputArray;
}
function loadVersionBrowser(userAgent) {
var ua = userAgent;
var tem;
var M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return {name: 'IE', version: (tem[1] || '')};
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR\/(\d+)/);
if (tem != null) {
return {name: 'Opera', version: tem[1]};
}
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) {
M.splice(1, 1, tem[1]);
}
return {
name: M[0],
version: M[1]
};
};
var applicationServerKey = "BLygs7rQA7nPjI2JK4XEEcVB5gvpHZpOGJ5ldEXMYzRzj9DmcpxlLnfLrVzS-TlQ7cL9dO1C8WRFOtqpMrgk1tI";
// In your ready listener
if ('serviceWorker' in navigator) {
// The service worker has to store in the root of the app
// http://stackoverflow.com/questions/29874068/navigator-serviceworker-is-never-ready
var browser = loadVersionBrowser('chrome');
navigator.serviceWorker.register('navigatorPush.service.js?version=1.0.0').then(function (reg) {
reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(applicationServerKey)
}).then(function (sub) {
var endpointParts = sub.endpoint.split('/');
var registration_id = endpointParts[endpointParts.length - 1];
var data = {
'browser': browser.name.toUpperCase(),
'p256dh': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('p256dh')))),
'auth': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('auth')))),
'name': 'XXXXX',
'registration_id': registration_id
};
console.log(data);
})
}).catch(function (err) {
console.log(':^(', err);
});
}
</script>
</body>
</html>
and here is error snippets.
I don't know what I'm missing??.
I am setting up only the Web push too and somehow not sure how exactly to set up. Also not sure what API endpoint are there to start using the web push:
- is there an API endpoint to create the subscription?
- how exactly to set up the library (what keys are required and what claims are)?
- should I expose the public key to the client app myself? The documentation is not clear on this. Guess will have to read the sources (this and the dependency library pywebpush) and deduce what is what. P.S. Googled but didn't find any complete example on how to setup this specific library.
For the api endpoints to register the device you need to add the url's from the rest package.
from rest_framework.routers import SimpleRouter
from push_notifications.api.rest_framework import WebPushDeviceViewSet
....
api_router = SimpleRouter()
api_router.register(r'push/web', WebPushDeviceViewSet, basename='web_push')
...
urlpatterns += [
# Api
re_path('api/v1/', include(api_router.urls)),
...
]
On the client/Device you can now send the data for registration with a POST Method to your django.
Something like:
....
}).then(function (sub) {
var endpointParts = sub.endpoint.split('/');
var registration_id = endpointParts[endpointParts.length - 1];
var data = {
'browser': browser.name.toUpperCase(),
'p256dh': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('p256dh')))),
'auth': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('auth')))),
'name': 'XXXXX',
'registration_id': registration_id
};
console.log(data);
requestPOSTToServer(data); <---------
})
....
function requestPOSTToServer(data) {
let xhr = new XMLHttpRequest();
xhr.open("POST", "https://<YOUR_ADDRESS/push/web/");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = () => console.log(xhr.responseText);
xhr.send(data);
}
Then your devices are registered #658
For the api endpoints to register the device you need to add the url's from the rest package.
from rest_framework.routers import SimpleRouter from push_notifications.api.rest_framework import WebPushDeviceViewSet .... api_router = SimpleRouter() api_router.register(r'push/web', WebPushDeviceViewSet, basename='web_push') ... urlpatterns += [ # Api re_path('api/v1/', include(api_router.urls)), ... ]
On the client/Device you can now send the data for registration with a POST Method to your django.
Something like:
.... }).then(function (sub) { var endpointParts = sub.endpoint.split('/'); var registration_id = endpointParts[endpointParts.length - 1]; var data = { 'browser': browser.name.toUpperCase(), 'p256dh': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('p256dh')))), 'auth': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('auth')))), 'name': 'XXXXX', 'registration_id': registration_id }; console.log(data); requestPOSTToServer(data); <--------- }) .... function requestPOSTToServer(data) { let xhr = new XMLHttpRequest(); xhr.open("POST", "https://<YOUR_ADDRESS/push/web/"); xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.onload = () => console.log(xhr.responseText); xhr.send(data); }
Then your devices are registered #658
Thank you. That's basically what I ended up doing. Just wondering why was this so hard for me to do? Will try to share the concepts using the library. Also noticed that there is no Safari browser in the browser list.
@gagamil @viktorisacenko @saileshkush95 Any feedback on this PR, #674, specfically this file, which aims to explain wepush configuration https://github.com/jazzband/django-push-notifications/blob/4fb64be08a5e9d4b9275e9632426d022d5a84a70/docs/WebPush.rst
Fixed by #674