Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Web Push + PWA, for background notifications #346

Closed
Mikaela opened this issue Jun 28, 2022 · 17 comments · Fixed by #751
Closed

Support Web Push + PWA, for background notifications #346

Mikaela opened this issue Jun 28, 2022 · 17 comments · Fixed by #751
Labels
enhancement New feature or request web-app Web app things

Comments

@Mikaela
Copy link

Mikaela commented Jun 28, 2022

I am not sure what running as progressive web app requires, but I understand they should be able to support receiving notifications in the background even without the tab/app open as long as browser is running.

I think currently at least webapp manifest is missing.

Somewhat unrelatedly, iOS is also receiving support for web push sometime next year, https://webventures.rejh.nl/blog/2022/06/25/the-biggest-thing-from-wwdc22/

Update 2023-04-02: iOS 16.4 supports web push when the PWA has been added to the homescreen.

@wunter8
Copy link
Contributor

wunter8 commented Jun 29, 2022

I've thought about trying to make this work. I think it might solve #199, too

@binwiederhier binwiederhier added enhancement New feature or request web-app Web app things labels Jul 1, 2022
@WebKenth
Copy link

Just thought i would leave my 2 cents

You can create a shortcut with chrome and have it opened as a separate window
image
image

This will give it a sorta PWA like feel, although it is still a chrome instance just running in a separate window

image

@MaximilianGaedig
Copy link

The browser asks me if I want to receive notifications, it works in the foreground but after closing the page it does not work anymore. Service workers need to be implemented.

@liamstojanovic
Copy link

Made progress in making the react web app fulfill install-ability requirements on the pwa-background-push branch of my forked repo.

No custom service workers are hooked up yet, nor have I managed to successfully install the PWA version so far.

Next steps...

  • Request permission,
  • Generate notification,
  • Push.

Lighthouse PWA report

@gedw99
Copy link

gedw99 commented Nov 11, 2022

Made progress in making the react web app fulfill install-ability requirements on the pwa-background-push branch of my forked repo.

No custom service workers are hooked up yet, nor have I managed to successfully install the PWA version so far.

Next steps...

  • Request permission,
  • Generate notification,
  • Push.

Lighthouse PWA report

Nice work !!

@BuckarooBanzay
Copy link

Made progress in making the react web app fulfill install-ability requirements on the pwa-background-push branch of my forked repo.

Where are you planning to store the subscriptions from the client? Those have to be somewhere on the backend side 🤔

@liamstojanovic
Copy link

I've hit a blocker with this endeavor.

I've made the web app install-able, and added appropriate views / preferences for enabling background notifications, but am lost when it comes to actually delivering notifications from the service worker itself, or how to go about listening for events that trigger a notification.

None of the classes in the app/ directory can be imported into the service worker. Additionally, all of the examples I have seen online for enabling push notifications to be delivered from the service worker seem to leverage PushManager / web push protocol. I do not know how to configure / incorporate this server logic into the existing web app code; plus, all the class instances in app/ will cease to run once the PWA is closed.

@binwiederhier
Copy link
Owner

So I know nothing about PWA, but I looked at web push and the service worker stuff for a while (not sure if that's the same thing), and the more I looked, the more confused I got.

It's been a while, so my memory is fuzzy, but luckily I can ping some experts, that can hopefully shed some light :-D

Pretty please, @p1gp1g @karmanyaahm (sorry for pinging you on two tickets :-))

@BuckarooBanzay
Copy link

BuckarooBanzay commented Nov 16, 2022

It's been a while, so my memory is fuzzy, but luckily I can ping some experts, that can hopefully shed some light :-D

(background: i've done this before and switched from my own webpush-spaghetty-app to ntfy, it is an awesome tool btw 😉 )

For webpush to work you need to generate a keypair, the public key is for the frontend and the private key is backend-only.
You also need to save the subscriptions from the frontend in the backend (somewhere in a database usually)
A subscription can be obtained by the pushManager in the browser.

This is a rough overview how a subscription is obtained on the frontend/browser side:

if (navigator.serviceWorker){
	// service-worker registration (snippet below)
	navigator.serviceWorker.register('service-worker.js');

	// ready event
	navigator.serviceWorker.ready
	.then(function(registration){
		return registration.pushManager.getSubscription()
		.then(function(subscription){
			if (subscription)
				// already subscribed
				return subscription;

			// new subscription
			// public key from the backend
			return fetch("api/push/pubkey")
			.then(function(res){ return res.text(); })
			.then(function(vapidPublicKey){
				return registration.pushManager.subscribe({
					userVisibleOnly: true,
					applicationServerKey: vapidPublicKey
				});
			});
		});
	})
	.then(function(subscription){
		// TODO: store subscription object in the backend for later notification
	});

} else {
	//no push
}

A subscription looks like this:

{
 "endpoint": "https://browser-dependent-url.com/xy",
 "keys": {
    "auth": "abcde--",
    "p256dh": "efgh=="
}

For the sending part in the backend you should really use a library, i can suggest this: https://www.npmjs.com/package/web-push EDIT: sorry i was somewhere else my my head https://github.com/SherClockHolmes/webpush-go

Sent notifications arrive in the service-worker.js and get dispatched to the user here:

self.addEventListener('push', function(event){
	var payload = event.data ? event.data.text() : null;
	if (!payload)
		return;

	var data = JSON.parse(payload);
	event.waitUntil(
		self.registration.showNotification(data.label, {
			body: data.text
		})
	);
});

Side-note: pwa != webpush, both can be developed independently

@gedw99
Copy link

gedw99 commented Nov 16, 2022

Made progress in making the react web app fulfill install-ability requirements on the pwa-background-push branch of my forked repo.

Where are you planning to store the subscriptions from the client? Those have to be somewhere on the backend side 🤔

for storage I would suggest nats.

you can embed nats or run it as a separate service.

Nats is 100% golang.

@karmanyaahm
Copy link
Contributor

karmanyaahm commented Nov 17, 2022

hopefully shed some light

PWAs and WebPush are related but separate. One does not require the other.
I agree with @BuckarooBanzay's comment. The frontend is simple, an extra JS file that handles push, notifies, and stores it into the indexed DB.

The backend could get complicated, however. First, you need a way to register. Perhaps POST ntfy.sh/mytopic,topic2/push with the subscription:

{"endpoint": "https://browser-dependent-url.com/xy", "keys": {"auth": "abcde==","p256dh": "efgh=="}}

Then, ntfy needs to store mytopic:subscription, topic2:subscription in the database.

Just like there's a sendToFirebase function, there will have to be a sendToPush function. On every message, sendToPush will look up the subscriptions associated with that topic, and then run the WebPush library on each of those.

The library encrypts the payload and POSTs it to the endpoint.

Details:

  1. I'd recommend allowing ignoring encryption when keys is null (POST raw notification to the server).
  2. The ntfy server will have to generate VAPID keys. It can be saved to the DB on the first run. (https://pkg.go.dev/github.com/AbdullahDiaa/govapid#GenerateVAPID). The client needs to know the public VAPID key.
  3. There needs to be a config option for the email of the server host or something similar (for VAPID).
  4. Make sure the endpoint cannot point to the ntfy server itself, preventing loops.
  5. Subscriptions should expire, perhaps weekly, to prevent dead clients. Clients that are still notifying should reregister every few days.

Feel free to ping me if you need more info about any of this.

@binwiederhier binwiederhier pinned this issue May 30, 2023
@binwiederhier binwiederhier changed the title ntfy.sh/app feature request: support running as a PWA and getting notifications in background Support Web Push + PWA, for background notifications Jun 1, 2023
@binwiederhier binwiederhier unpinned this issue Jun 24, 2023
@pinpox
Copy link

pinpox commented Jun 26, 2023

Any plans for when this will be released?

@gedw99
Copy link

gedw99 commented Jun 26, 2023

would be good with a example as setting this all up can be complex.

@binwiederhier
Copy link
Owner

binwiederhier commented Jun 26, 2023

@gedw99 @pinpox You can help test it. It's deployed on https://staging.ntfy.sh https://staging.ntfy.sh/app -- Docs are here: https://docs.ntfy.sh/subscribe/pwa/

We found some small issues, but nothing major. It's almost ready for prime time. The code is already in the main branch.

@nimbleghost
Copy link
Contributor

specifically here: https://staging.ntfy.sh/app :D

and the self-hosting config docs are here: https://docs.ntfy.sh/config/#web-push

@binwiederhier
Copy link
Owner

📢 Request for testing:

The next ntfy server release will contain a progressive web app (PWA) with Web Push support, which means you'll be able to install the ntfy web app on your desktop or phone similar to a native app (even iOS! 🥳), and get basic push notification support (without any battery drain).

Installing the PWA gives ntfy web its own launcher (e.g. shortcut on Windows, app on macOS, launcher shortcut on Linux, home screen icon on iOS, and launcher icon on Android), a standalone window, push notifications, and an app badge with the unread notification count.

The (hopefully) production ready version of the PWA is currently deployed on https://staging.ntfy.sh/app -- Install instructions with screenshots can be found in the docs (https://docs.ntfy.sh/subscribe/pwa/).

Please report bugs or issues on Discord/Matrix/Lemmy. PLEASE HELP TEST

Huuuuge thanks goes to @nimbleghost for developing this entire feature top to bottom. If you throw donations my way, I'll share them with him. He certainly deserves it for all this great work. 👏

@gedw99
Copy link

gedw99 commented Jun 27, 2023

📢 Request for testing:

The next ntfy server release will contain a progressive web app (PWA) with Web Push support, which means you'll be able to install the ntfy web app on your desktop or phone similar to a native app (even iOS! 🥳), and get basic push notification support (without any battery drain).

Installing the PWA gives ntfy web its own launcher (e.g. shortcut on Windows, app on macOS, launcher shortcut on Linux, home screen icon on iOS, and launcher icon on Android), a standalone window, push notifications, and an app badge with the unread notification count.

The (hopefully) production ready version of the PWA is currently deployed on https://staging.ntfy.sh/app -- Install instructions with screenshots can be found in the docs (https://docs.ntfy.sh/subscribe/pwa/).

Please report bugs or issues on Discord/Matrix/Lemmy. PLEASE HELP TEST

Huuuuge thanks goes to @nimbleghost for developing this entire feature top to bottom. If you throw donations my way, I'll share them with him. He certainly deserves it for all this great work. 👏

Thanks. It works on iOS safari

Just had to A2HS and then grant notifications in the menu of the app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request web-app Web app things
Projects
None yet
Development

Successfully merging a pull request may close this issue.