Benachrichtigungen: Web Push und E-Mail als Kanaele der Automatiken
Neuer BenachrichtigungTransport hinter der Aktor-URL "Benachrichtigung": push schickt an alle angemeldeten Geraete (homeMesh.push_abos), mail ueber den SMTP-Zugang aus der config.ini. Ein Abo, das der Push-Dienst mit 404 oder 410 ablehnt, wird geloescht statt weiter angeschrieben. Daneben hoert der Runner auf benachrichtigung/# - darueber schickt die Probe aus den Einstellungen, ohne dass die Weboberflaeche verschluesseln muesste. Zugestellt wird im Haupttakt, nicht im MQTT-Faden. pywebpush, py_vapid und http_ece liegen wie die uebrigen Fremdpakete im Ordner, nicht in site-packages; transports.py haengt ihn an den Suchpfad. Das Schluesselpaar erzeugt vapid_erzeugen.py und bleibt ausserhalb des Git. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
Metadata-Version: 2.4
|
||||
Name: pywebpush
|
||||
Version: 2.1.2
|
||||
Summary: WebPush publication library
|
||||
Author-email: JR Conlin <src+webpusher@jrconlin.com>
|
||||
License: MPL-2.0
|
||||
Project-URL: Homepage, https://github.com/web-push-libs/pywebpush
|
||||
Keywords: webpush,vapid,notification
|
||||
Classifier: Topic :: Internet :: WWW/HTTP
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Description-Content-Type: text/markdown
|
||||
License-File: LICENSE
|
||||
Requires-Dist: aiohttp
|
||||
Requires-Dist: cryptography>=2.6.1
|
||||
Requires-Dist: http-ece>=1.1.0
|
||||
Requires-Dist: requests>=2.21.0
|
||||
Requires-Dist: six>=1.15.0
|
||||
Requires-Dist: py-vapid>=1.7.0
|
||||
Provides-Extra: dev
|
||||
Requires-Dist: black; extra == "dev"
|
||||
Requires-Dist: mock; extra == "dev"
|
||||
Requires-Dist: pytest; extra == "dev"
|
||||
Dynamic: license-file
|
||||
|
||||
# Webpush Data encryption library for Python
|
||||
|
||||
[](https://travis-ci.org/web-push-libs/pywebpush)
|
||||
[](https://requires.io/github/web-push-libs/pywebpush/requirements/?branch=main)
|
||||
|
||||
This library is available on [pypi as pywebpush](https://pypi.python.org/pypi/pywebpush).
|
||||
Source is available on [github](https://github.com/mozilla-services/pywebpush).
|
||||
Please note: This library was designated as a `Critical Project` by PyPi, it is currently
|
||||
maintained by [a single person](https://xkcd.com/2347/). I still accept PRs and Issues, but
|
||||
make of that what you will.
|
||||
|
||||
## Installation
|
||||
|
||||
To work with this repo locally, you'll need to run `python -m venv venv`.
|
||||
Then `venv/bin/pip install --editable .`
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
In the browser, the promise handler for
|
||||
[registration.pushManager.subscribe()](https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe)
|
||||
returns a
|
||||
[PushSubscription](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription)
|
||||
object. This object has a .toJSON() method that will return a JSON object that contains all the info we need to encrypt
|
||||
and push data.
|
||||
|
||||
As illustration, a `subscription_info` object may look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoint": "https://updates.push.services.mozilla.com/push/v1/gAA...",
|
||||
"keys": { "auth": "k8J...", "p256dh": "BOr..." }
|
||||
}
|
||||
```
|
||||
|
||||
How you send the PushSubscription data to your backend, store it
|
||||
referenced to the user who requested it, and recall it when there's
|
||||
a new push subscription update is left as an exercise for the
|
||||
reader.
|
||||
|
||||
### Sending Data using `webpush()` One Call
|
||||
|
||||
In many cases, your code will be sending a single message to many
|
||||
recipients. There's a "One Call" function which will make things
|
||||
easier.
|
||||
|
||||
```python
|
||||
from pywebpush import webpush
|
||||
|
||||
webpush(subscription_info,
|
||||
data,
|
||||
vapid_private_key="Private Key or File Path[1]",
|
||||
vapid_claims={"sub": "mailto:YourEmailAddress"})
|
||||
```
|
||||
|
||||
This will encode `data`, add the appropriate VAPID auth headers if required and send it to the push server identified
|
||||
in the `subscription_info` block.
|
||||
|
||||
##### Parameters
|
||||
|
||||
_subscription_info_ - The `dict` of the subscription info (described above).
|
||||
|
||||
_data_ - can be any serial content (string, bit array, serialized JSON, etc), but be sure that your receiving
|
||||
application is able to parse and understand it. (e.g. `data = "Mary had a little lamb."`)
|
||||
|
||||
_content_type_ - specifies the form of Encryption to use, either `'aes128gcm'` or the deprecated `'aesgcm'`. NOTE that
|
||||
not all User Agents can decrypt `'aesgcm'`, so the library defaults to the RFC 8188 standard form.
|
||||
|
||||
_vapid_claims_ - a `dict` containing the VAPID claims required for authorization (See
|
||||
[py_vapid](https://github.com/web-push-libs/vapid/tree/master/python) for more details). If `aud` is not specified,
|
||||
pywebpush will attempt to auto-fill from the `endpoint`. If `exp` is not specified or set in the past, it will be set
|
||||
to 12 hours from now. In both cases, the passed `dict` **will be mutated** after the call.
|
||||
|
||||
_vapid_private_key_ - Either a path to a VAPID EC2 private key PEM file, or a string containing the DER representation.
|
||||
(See [py_vapid](https://github.com/web-push-libs/vapid/tree/master/python) for more details.) The `private_key` may be
|
||||
a base64 encoded DER formatted private key, or the path to an OpenSSL exported private key file.
|
||||
|
||||
e.g. the output of:
|
||||
|
||||
```bash
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
```python
|
||||
from pywebpush import webpush, WebPushException
|
||||
|
||||
try:
|
||||
webpush(
|
||||
subscription_info={
|
||||
"endpoint": "https://push.example.com/v1/12345",
|
||||
"keys": {
|
||||
"p256dh": "0123abcde...",
|
||||
"auth": "abc123..."
|
||||
}},
|
||||
data="Mary had a little lamb, with a nice mint jelly",
|
||||
vapid_private_key="path/to/vapid_private.pem",
|
||||
vapid_claims={
|
||||
"sub": "mailto:YourNameHere@example.org",
|
||||
}
|
||||
)
|
||||
except WebPushException as ex:
|
||||
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
|
||||
# Mozilla returns additional information in the body of the response.
|
||||
if ex.response is not None and ex.response.json():
|
||||
extra = ex.response.json()
|
||||
print("Remote service replied with a {}:{}, {}",
|
||||
extra.code,
|
||||
extra.errno,
|
||||
extra.message
|
||||
)
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
If you expect to resend to the same recipient, or have more needs than just sending data quickly, you
|
||||
can pass just `wp = WebPusher(subscription_info)`. This will return a `WebPusher` object.
|
||||
|
||||
The following methods are available:
|
||||
|
||||
#### `.send(data, headers={}, ttl=0, gcm_key="", reg_id="", content_encoding="aes128gcm", curl=False, timeout=None)`
|
||||
|
||||
Send the data using additional parameters. On error, returns a `WebPushException`
|
||||
|
||||
##### Parameters
|
||||
|
||||
_data_ Binary string of data to send
|
||||
|
||||
_headers_ A `dict` containing any additional headers to send
|
||||
|
||||
_ttl_ Message Time To Live on Push Server waiting for the client to reconnect (in seconds)
|
||||
|
||||
_gcm_key_ Google Cloud Messaging key (if using the older GCM push system) This is the API key obtained from the Google
|
||||
Developer Console.
|
||||
|
||||
_reg_id_ Google Cloud Messaging registration ID (will be extracted from endpoint if not specified)
|
||||
|
||||
_content_encoding_ ECE content encoding type (defaults to "aes128gcm")
|
||||
|
||||
_curl_ Do not execute the POST, but return as a `curl` command. This will write the encrypted content to a local file
|
||||
named `encrpypted.data`. This command is meant to be used for debugging purposes.
|
||||
|
||||
_timeout_ timeout for requests POST query.
|
||||
See [requests documentation](http://docs.python-requests.org/en/master/user/quickstart/#timeouts).
|
||||
|
||||
##### Example
|
||||
|
||||
to send from Chrome using the old GCM mode:
|
||||
|
||||
```python
|
||||
WebPusher(subscription_info).send(data, headers, ttl, gcm_key)
|
||||
```
|
||||
|
||||
#### `.encode(data, content_encoding="aes128gcm")`
|
||||
|
||||
Encode the `data` for future use. On error, returns a `WebPushException`
|
||||
|
||||
##### Parameters
|
||||
|
||||
_data_ Binary string of data to send
|
||||
|
||||
_content_encoding_ ECE content encoding type (defaults to "aes128gcm")
|
||||
|
||||
*Note* This will return a `NoData` exception if the data is not present or empty. It is completely
|
||||
valid to send a WebPush notification with no data, but encoding is a no-op in that case. Best not
|
||||
to call it if you don't have data.
|
||||
|
||||
##### Example
|
||||
|
||||
```python
|
||||
encoded_data = WebPush(subscription_info).encode(data)
|
||||
```
|
||||
|
||||
## Stand Alone Webpush
|
||||
|
||||
If you're not really into coding your own solution, there's also a "stand-alone" `pywebpush` command in the
|
||||
./bin directory.
|
||||
|
||||
This uses two files:
|
||||
|
||||
- the _data_ file, which contains the message to send, in whatever form you like.
|
||||
- the _subscription info_ file, which contains the subscription information as JSON encoded data. This is usually returned by the Push `subscribe` method and looks something like:
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoint": "https://push...",
|
||||
"keys": {
|
||||
"auth": "ab01...",
|
||||
"p256dh": "aa02..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you're interested in just testing your applications WebPush interface, you could use the Command Line:
|
||||
|
||||
```bash
|
||||
./bin/pywebpush --data stuff_to_send.data --info subscription.info
|
||||
```
|
||||
|
||||
which will encrypt and send the contents of `stuff_to_send.data`.
|
||||
|
||||
See `./bin/pywebpush --help` for available commands and options.
|
||||
Reference in New Issue
Block a user