Super simple and small Web Push and Notification service
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
John-Mark Gurney ca5f408077 update README, add CGI 1 month ago
src add support for passing in a non-default port.. 11 months ago
static add image, add testing for vapid key, and script to manually push 1 year ago
.gitignore inital work to make notifications work.. 1 year ago
LICENSE.txt inital work to make notifications work.. 1 year ago
Makefile update README, add CGI 1 month ago
README.md update README, add CGI 1 month ago
S1_vapid.py write out pem so pywebpush can use it, fixes push to chrome, fix private key write (trailing comma) 11 months ago
push.py update README, add CGI 1 month ago
pushnotify.sh write out pem so pywebpush can use it, fixes push to chrome, fix private key write (trailing comma) 11 months ago

README.md

Web Push Notifications (WPN)

This is designed to be a super simple (understandable) and small tool to push notifications to web browsers (e.g. your cell phone).

This code is partly copied from: https://gist.github.com/code-boxx/bc6aed37345ad1783cfb7d230f438120

But put into a repo w/ better install instructions, and turned into a usable bit of code.

The web browser Push API is fully encrypted and authenticated. This means that only your server and the client will be able to see the contents of the message.

There is also a limit of 4k for the entire message that is composed and sent to the server. This means that the usable space for your own contents is around 3k, which is more than enough.

Installation and Setup

There are two ways to install it, one is to use it via the Flask web server, or via a CGI.

Flask web server

git clone https://www.funkthat.com/gitea/jmg/wpn
cd wpn
make run EMAIL=myemail@example.com PORT=<someport>

Then you go to http://127.0.0.1:<someport>/, click the Request Notifications button. The sub info will be printed to the console, and a second later, a notification should appear, and it’ll be repeated every 10 seconds. To change this behavior, look at the donotify fucntion in src/S4_server.py.

CGI

First build the files needed:

git clone https://www.funkthat.com/gitea/jmg/wpn
cd wpn
make files EMAIL=myemail@example.com

Then copy the files in the directory static, the files template/S2_perm_sw.html and push.py to a directory on your webserver. In that directory, set push.py executable (chmod 755 push.py), and create a symlink to it from push: ln -s push.py push.

Configure your web server such that the push is a CGI, and that S2_perm_sw.html is the index file. This is how to do it via Apache:

<Directory "/location/on/webserver">
  Options +ExecCGI
  Order allow,deny
  Allow from all
  DirectoryIndex S2_perm_sw.html
  <FilesMatch "push$">
      SetHandler cgi-script
  </FilesMatch>
</Directory>

The push.py file is used to get the push notification subscription information from the browser and put it in /tmp/subinfo.txt.

Note: The push.py has a hand implemented version of form decoding because Python had deprecated the cgi module.

Pushing Notifications

Using the subscription information from the previous step, put it in a file for use as <filewsubjson> below.

The pywebpush program that is installed by the pywebpush module is used to send notifications:

jq --arg email myemail@example.com -n '{ "sub": ("mailto:" + $email) }' > claim.txt
jq --arg msg 'somemessage' --arg title notification -n '{ "title": $title, "body": $msg, "icon" : "static/i-ico.png", "image" : "static/i-banner.png" }' |
 pywebpush --data /dev/stdin --info <filewsubjson> --key keys/private_key.pem --claims claim.txt

As Python’s [venv](https://docs.python.org/3/library/venv.html#module-venv) is used, you can simply execute/link to the pywebpush program in venv/bin/ and not have to source the environment each time you need to run the program.

Compatibility

Currently Firefox for Android does not allow Push notifications. The nightly version does allow it.

cryptography

If you have troubles installing the cryptography dependency (due to rust or other compile issues), but can install pycryptodome, you can use the pycryptowrap instead. To use it:

python3 -m venv venv
(. ./venv/bin/activate && pip install git+https://www.funkthat.com/gitea/jmg/pycryptowrap )
(. ./venv/bin/activate && pip install flask ecdsa pywebpush )

Notes

If put behind a reverse proxy, make sure the url contains a trailing slash. If you want the path w/o the slash to work, add a redirect as well. Though if you use the CGI version, this is likely unneeded.

For Apache:

LoadModule proxy_module libexec/apache22/mod_proxy.so
LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so

ProxyPass "/wpn/" "http://internalwpn.example.com/"
ProxyPassReverse "/wpn/" "http://internalwpn.example.com/"
Redirect permanent /wpn https://www.example.com/wpn/

See the introduction section on message limits.

Yes, I probably should have used a better template language than sed, but this is simple and works. It also makes it easy to copy over to a static site more easily.