Relay service for Threema Web push notifications.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.circleci
src
.gitignore
.rustfmt.toml
Cargo.lock
Cargo.toml
LICENSE-APACHE
LICENSE-MIT
README.md
RELEASING.md

README.md

GCM/APNs Push Relay

CircleCI License

This server accepts push requests via HTTP and notifies the Google GCM / Apple APNs push services.

Request Format

  • POST request to /push
  • Request body must use application/x-www-form-urlencoded encoding

Request keys:

  • type: Either gcm or apns
  • token: The device push token
  • session: SHA256 hash of public permanent key of the initiator
  • version: Threema Web protocol version
  • bundleid (APNs only): The bundle id to use
  • endpoint (APNs only): Either p (production) or s (sandbox)

Examples:

curl -X POST -H "Origin: https://localhost" localhost:3000/push \
    -d "type=gcm&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"

Possible response codes:

  • HTTP 204 (No Content): Request was processed successfully
  • HTTP 400 (Bad Request): Invalid or missing POST parameters (including expired push tokens)
  • HTTP 502 (Bad Gateway): Processing of push request failed

Push Payload

The payload format looks like this:

  • wcs: Webclient session (sha256 hash of the public permanent key of the initiator), string
  • wct: Unix epoch timestamp of the request in seconds, i64
  • wcv: Protocol version, u16

GCM

The GCM message contains the payload data as specified above.

The TTL of the message is currently hardcoded to 90 seconds.

APNs

The APNs message contains a key "3mw" containing the payload data as specified above.

Running

You need the Rust compiler (current stable). First, create a config.ini file that looks like this:

[gcm]
api_key = "your-api-key"

[apns]
keyfile = "your-keyfile.p8"
key_id = "AB123456XY"
team_id = "CD987654YZ"

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=push_relay=info,hyper=info,a2=info env variable

Testing

To run tests:

cargo test

Linting

Install rustfmt on your nightly toolchain:

rustup component add rustfmt-preview --toolchain nightly

Then reformat your code:

cargo +nightly fmt

License

Licensed under either of

at your option.