push-relay
push-relay copied to clipboard
Relay service for Threema Web push notifications.
Push Relay
This server accepts push requests via HTTP and relays those requests to the appropriate push backends.
Supported backends:
- Google FCM
- Apple APNs
- Huawei HMS
Request Format
- POST request to
/push - Request body must use
application/x-www-form-urlencodedencoding
Request keys:
type: Eitherfcm,hmsorapnstoken: The device push tokensession: SHA256 hash of public permanent key of the initiatorversion: Threema Web protocol versionaffiliation(optional): An identifier for affiliating consecutive pushesttl(optional): The lifespan of a push message, defaults to 90 secondscollapse_key: (optional) A parameter identifying a group of push messages that can be collapsed.bundleid(APNs only): The bundle id to useendpoint(APNs only): Eitherp(production) ors(sandbox)appid(HMS only): Can be used to differentiate between multiple configs
Examples:
curl -X POST -H "Origin: https://localhost" localhost:3000/push \
-d "type=fcm&token=asdf&session=123deadbeef&version=3"
curl -X POST -H "Origin: https://localhost" localhost:3000/push \
-d "type=apns&token=asdf&session=123deadbeef&version=3&bundleid=com.example.app&endpoint=s"
curl -X POST -H "Origin: https://localhost" localhost:3000/push \
-d "type=hms&appid=123456&token=asdf&session=123deadbeef&version=3"
Possible response codes:
HTTP 204 (No Content): Request was processed successfullyHTTP 400 (Bad Request): Invalid or missing POST parameters (including expired push tokens)HTTP 500 (Internal Server Error): Processing of push request failed on the Push Relay serverHTTP 502 (Bad Gateway): Processing of push request failed on the FCM, HMS or APNs server
Push Payload
The payload format looks like this:
wcs: Webclient session (sha256 hash of the public permanent key of the initiator),stringwca: An optional identifier for affiliating consecutive pushes,stringornullwct: Unix epoch timestamp of the request in seconds,i64wcv: Protocol version,u16
FCM / HMS
The FCM and HMS messages contain the payload data as specified above.
APNs
The APNs message contains a key "3mw" containing the payload data as specified above.
Running
You need the Rust compiler. First, create a config.toml file that looks like this:
[fcm]
api_key = "your-api-key"
[apns]
keyfile = "your-keyfile.p8"
key_id = "AB123456XY"
team_id = "CD987654YZ"
To support HMS as well, you need to add one or more named HMS config sections. The name should correspond to the App ID (and currently matches the Client ID).
[hms.app-id-1]
client_id = "your-client-id"
client_secret = "your-client-secret"
[hms.app-id-2]
client_id = "your-client-id"
client_secret = "your-client-secret"
If you want to log the pushes to InfluxDB, add the following section:
[influxdb]
connection_string = "http://127.0.0.1:8086"
user = "foo"
pass = "bar"
db = "baz"
Then simply run
export RUST_LOG=push_relay=debug,hyper=info,a2=info
cargo run
...to build and start the server in debug mode.
Deployment
- Always create a build in release mode:
cargo build --release - Use a reverse proxy with proper TLS termination (e.g. Nginx)
- Set
RUST_LOG=infoenv variable
Testing
To run tests:
cargo test
Linting
To run lints:
$ rustup component add clippy
$ cargo clean && cargo clippy --all-targets
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.