Warum noch ein Führer?
Als ich mit dem Erstellen eines Entwurfs von Push-Benachrichtigungen beauftragt wurde, ergab eine schnelle Suche, dass es bereits viele Artikel zum Einrichten von Push-Benachrichtigungen auf dem Hub gab. Hier sind meiner Meinung nach die am besten geeigneten:
So funktioniert JS: Web-Push-BenachrichtigungenWeb PUSH-Benachrichtigungen schnell und einfach 924 /Servicemitarbeiter. Web Push und wo sie lebenDas ist alles in Ordnung, aber mir persönlich fehlte wirklich eine einfache und verständliche Anleitung, die es mir ermöglichen würde, sofort, praktisch durch Kopieren und Einfügen, alles sofort zum Laufen zu bringen. Außerdem gibt es in den Handbüchern keine Python, die für die Unterstützung geeignet ist.
Das Einrichten von Benachrichtigungen dauerte am Ende drei Tage und es scheint mir, dass dies etwas zu viel ist. Hoffentlich hilft mein Artikel jemandem, Push-Benachrichtigungen in drei Stunden statt in drei Tagen einzurichten.
Das Projekt, an dem ich arbeite, ist auf Django implementiert und ich werde den Fortschritt der Arbeit in Bezug auf dieses Framework beschreiben, aber diejenigen, die es wünschen, können es leicht an Flask oder etwas anderes anpassen.
Also, lass uns gehen.
Wir bekommen die Schlüssel
Ohne Schlüssel lassen sie uns natürlich nirgendwo hin, also fangen wir mit ihnen an. Um die Schlüssel zu generieren, habe ich
py_vapid verwendet . Es wird automatisch zusammen mit
pywebpush installiert, das wir später noch benötigen. Um nicht zweimal aufzustehen, beginnen wir mit pywebpush:
> bin/pip install pywebpush < > > bin/vapid --applicationServerKey No private_key.pem file found. Do you want me to create one for you? (Y/n)Y Generating private_key.pem Generating public_key.pem Application Server Key = < Server Key>
Der resultierende Anwendungsserverschlüsselwert wird der Datei settings.py hinzugefügt.
NOTIFICATION_KEY = < Server Key>
Außerdem müssen wir NOTIFICATION_KEY an den Kontext übergeben. Der einfachste Weg, dies zu tun, besteht darin,
Ihren context_processor zu schreiben.
Einen Servicemitarbeiter machen
Servicemitarbeiter, der es nicht weiß - dies ist eine spezielle Datei, die im Hintergrund ausgeführt wird. Wir brauchen es, um unsere Benachrichtigungen anzuzeigen.
Der einfachste Code für Servicemitarbeiter würde folgendermaßen aussehen:
self.addEventListener('push', function(event) { var message = JSON.parse(event.data.text());
Und jetzt müssen wir unseren Servicemitarbeiter registrieren. Der Prozess wird
hier grundsätzlich beschrieben. Deshalb kurz:
function checkWorkerAndPushManager () { if (!('serviceWorker' in navigator)) { console.log('Workers are not supported.'); return; } if (!('PushManager' in window)) { console.log('Push notifications are not supported.'); return; } } function registerWorker () { window.addEventListener('load', function () { navigator.serviceWorker.register('/static/js/sw.js').then(function (registration) { console.log('ServiceWorker registration successful'); }, function (err) { console.log('ServiceWorker registration failed: ', err); return; }); }); return true; } var supported = checkWorkerAndPushManager(); if (supported){ var worker = registerWorker (); }
Gut, Sie können die Arbeit unseres Servicemitarbeiters überprüfen. Gehen Sie dazu in einem Browser zu Developer Tools, stellen Sie sicher, dass auf der Konsole eine Meldung über die erfolgreiche Registrierung des Wokers angezeigt wird, gehen Sie zur Registerkarte Application und wählen Sie links Service Worker aus.

Wenn die Benachrichtigung nicht angezeigt wird, überprüfen Sie, ob die Benachrichtigungen in Ihrem Browser aktiviert sind.
Nun, wir wissen bereits, wie wir Benachrichtigungen an uns selbst senden können. Cool, lass uns weitermachen.
Holen Sie sich die Benutzerberechtigung zum Anzeigen von Benachrichtigungen
Bitten Sie den Benutzer nach der Registrierung des Wokers um die Erlaubnis, Benachrichtigungen anzuzeigen.
function requestPermission() { return new Promise(function(resolve, reject) { const permissionResult = Notification.requestPermission(function(result) {
Für diesen Code sind keine Kommentare erforderlich, er funktioniert einfach.
Abonnieren und speichern Sie Ihr Abonnement
Das Abonnement befindet sich ebenfalls auf der Vorderseite.
Sie finden den Abonnementcode hier , aber es wird keine urlBase64ToUint8Array-Funktion verwendet, daher codiere ich damit.
NOTIFICATION_KEY = '{{ NOTIFICATION_KEY }}; function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/') ; const rawData = window.atob(base64); return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0))); } function subscribeUserToPush(key) { return navigator.serviceWorker.register('/static/path/to/js/sw.js') .then(function(registration) { var subscribeOptions = { userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(key), }; return registration.pushManager.subscribe(subscribeOptions) }) .then(function(pushSubscription) { sendSubscriptionToBackEnd(pushSubscription); }); }
(Das hier verwendete urlBase64ToUint8Array stammt wahrscheinlich aus der Kategorie der Krücken und Fahrräder, aber der Versuch, die Daten mit btoa zu transkodieren, war nicht erfolgreich, ich weiß nicht warum. Vielleicht wird es Ihnen jemand sagen.)
Dann senden wir die empfangenen Daten an den Server. Ich habe es so implementiert:
function sendSubscriptionToBackEnd(subscription) { $.post( SAVE_REGISTRATION_URL, { 'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
Nun, dann speichern wir dies auf dem Server. Sie können direkt an der Linie. Ja, versuchen Sie nicht, eine Eins-zu-Eins-Benutzer-Abonnement-Beziehung herzustellen. Es scheint offensichtlich zu sein, aber plötzlich möchte es jeder.
Ich habe ein so einfaches Modell zum Speichern verwendet, dass es später verwendet wird, also werde ich es geben:
class UserSubscription(models.Model): subscription = models.CharField(max_length=500) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='subscriptions')
Der letzte Schritt. Senden einer Nachricht mit pywebpush
Alles ist im Tutorial, keine besonderen Feinheiten. Nun, außer dass die Nachricht in einer solchen Struktur erstellt wird, dass unser Servicemitarbeiter sie analysieren kann.
import json from pywebpush import webpush, WebPushException from django.conf import settings from .models import UserSubscription def push_notification(user_id): user_subscriptions = UserSubscription.objects.filter(user_id=notification.user_id) for subscription in user_subscriptions: data = json.dumps({ 'title': 'Hello', 'body': 'there', }) try: webpush( subscription_info=json.loads(subscription.subscription), data=data, vapid_private_key='./private_key.pem', vapid_claims={ 'sub': 'mailto:{}'.format(settings.ADMIN_EMAIL), } ) notification.sent = True notification.save() except WebPushException as ex: print('I\'m sorry, Dave, but I can\'t do that: {}'.format(repr(ex))) print(ex)
Tatsächlich können Sie push_notification bereits über die Django-Shell aufrufen und versuchen, zu starten.
In diesem Code wäre es schön, die Antwort mit dem Status 410 abzufangen. Eine solche Antwort besagt, dass das Abonnement gekündigt wurde, und es wäre schön, solche Abonnements aus der Datenbank zu löschen.
Abschließend
Tatsächlich gibt es eine weitere großartige
Django-Webpush-Bibliothek . Vielleicht sollten diejenigen, die mit Django arbeiten, damit beginnen.
PS Glücklicher Programmiertag!