This server accepts push requests via HTTP and relays those requests to the appropriate push backends.
Supported backends:
- Apple APNs
- Google FCM
- Huawei HMS
- Threema Gateway
- POST request to
/push - Request body must use
application/x-www-form-urlencodedencoding
Request keys:
type:apns,fcm,hmsorthreema-gatewaytoken: The device push token (not provided when using Threema Gateway)- for FCM: The token itself as received from the OS
- for iOS: The hex encoded token (without bundle id or encryption key appended)
session: 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 configsidentity(Threema Gateway only): The Threema ID of the user.public_key(Threema Gateway only): Public key associated to the Threema ID of the user.
Examples:
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=fcm&token=asdf&session=123deadbeef&version=3"
curl -X POST -H "Origin: https://localhost" localhost:3000/push \
-d "type=hms&appid=123456&token=asdf&session=123deadbeef&version=3"
curl -X POST -H "Origin: https://localhost" localhost:3000/push \
-d "type=threema-gateway&session=123deadbeef&version=3&identity=ECHOECHO&public_key=0000000000000000000000000000000000000000000000000000000000000000"
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 APNs, FCM, HMS or Threema Gateway server
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
The APNs message contains a key "3mw" containing the payload data as specified above.
The FCM, HMS and Threema Gateway messages contain the payload data as specified above.
You need the Rust compiler. First, create an empty config.toml file.
To support FCM, you need to add the fcm config section that should look like this:
[fcm]
service_account_key_base64 = "aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQo="
project_id = 12345654321
max_retries = 6
# Optional, default is 60 s
timeout_secs = 60
To support APNS, add the apns section and a keyfile:
[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"
To support Threema Gateway, the following config sections need to be added.
Note: The apps only support messages sent from *3MAPUSH.
[threema_gateway]
base_url = "https://msgapi.threema.ch"
identity = "*3MAPUSH"
secret = "secret-for-*3MAPUSH"
private_key_file = "private-key-file-for-*3MAPUSH"
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,tower=debug
cargo run
...to build and start the server in debug mode.
- 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
To run tests:
cargo test
To run lints:
$ rustup component add clippy
$ cargo clean && cargo clippy --all-targets
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.