{"id":15147038,"url":"https://github.com/monal-im/fpush","last_synced_at":"2025-10-24T01:31:21.244Z","repository":{"id":104183480,"uuid":"549105717","full_name":"monal-im/fpush","owner":"monal-im","description":"Scalable push server for XMPP","archived":false,"fork":false,"pushed_at":"2024-09-01T11:01:26.000Z","size":172,"stargazers_count":24,"open_issues_count":1,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-09-26T12:21:50.734Z","etag":null,"topics":["android","ios","jabber","macos","push","xmpp"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monal-im.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["tmolitor-stud-tu"],"liberapay":"tmolitor"}},"created_at":"2022-10-10T17:24:30.000Z","updated_at":"2024-09-06T19:29:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"b538058d-2ce8-49f6-a5ff-c26a08e0f925","html_url":"https://github.com/monal-im/fpush","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monal-im%2Ffpush","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monal-im%2Ffpush/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monal-im%2Ffpush/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monal-im%2Ffpush/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monal-im","download_url":"https://codeload.github.com/monal-im/fpush/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219867198,"owners_count":16555821,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","ios","jabber","macos","push","xmpp"],"created_at":"2024-09-26T12:21:35.504Z","updated_at":"2025-10-24T01:31:20.744Z","avatar_url":"https://github.com/monal-im.png","language":"Rust","funding_links":["https://github.com/sponsors/tmolitor-stud-tu","https://liberapay.com/tmolitor"],"categories":[],"sub_categories":[],"readme":"# Fpush\n\n`fpush` is a scalable push server for XMPP implemeting[XEP-0357](https://xmpp.org/extensions/xep-0357.html).\n`fpush` can be connected to any XMPP server as a XMPP component using [XEP-0114](https://xmpp.org/extensions/xep-0114.html).\n\n\n## Table of contents\n\n- [Features](#features)\n- [Usage](#usage)\n- [XMPP API](#xmpp-api)\n- [Configuration](#configuration)\n- [Structure](#structure)\n- [Clustering](#clustering)\n- [Compilation](#compilation)\n- [Compilation Flags](#compilation-flags)\n- [Expandability](#expandability)\n- [Systemd](#systemd)\n\n\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n## Features\n\n* Supported push platforms\n  * Apple APNS\n  * Google FCM\n* Multi app / platform support on a single XMPP domain/JID\n* Configurable token ratelimiting\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n## Usage\n\n```\n./fpush settings.json\n```\n\n\u003ca name=\"xmpp-api\"\u003e\u003c/a\u003e\n## XMPP API\n\nThis appserver implements [XEP-0357](https://xmpp.org/extensions/xep-0357.html) commands for sending actual push notifications.\n`fpush` does not require devices to register for push before usage like other appserver implementations.\n\n`fpush` expects each push IQ to include the push token of the device to be woken up, as well as the info to which push module the token applies.\nHence, push messages can be enabled by a client at their XMPP server as follows:\n```XML\n\u003ciq type='set' id='x43'\u003e\n  \u003cenable xmlns='urn:xmpp:push:0' jid='###pushServerComponentJid###' node='###DevicePushToken###'\u003e\n    \u003cx xmlns='jabber:x:data' type='submit'\u003e\n      \u003cfield var='FORM_TYPE'\u003e\u003cvalue\u003ehttp://jabber.org/protocol/pubsub#publish-options\u003c/value\u003e\u003c/field\u003e\n      \u003cfield var='pushModule'\u003e\u003cvalue\u003e##pushModuleName###\u003c/value\u003e\u003c/field\u003e\n    \u003c/x\u003e\n  \u003c/enable\u003e\n\u003c/iq\u003e\n```\n\nIf the `pushModule` identifier is missing in the publish-options, `fpush` will instead selected the default push module as configured.\n\n\u003ca name=\"configuration\"\u003e\u003c/a\u003e\n### Configuration\n\n```json\n{\n    \"component\": {\n        \"componentHostname\": \"\u003cComponentJid\u003e\",\n        \"componentKey\": \"ARandomComponentKeySetInsideTheXMPPServer\",\n        \"serverHostname\": \"\u003cXMPP-Server\u003e\",\n        \"serverPort\": \u003cXMPP-Server Component Port\u003e\n    },\n    \"pushModules\": { // map of configured push modules\n        \"monalProdiOS\": { // push module identifier that is later set inside the push iqs as \"pushModule\"\n            \"type\": \"apple\", // push module type\n            \"is_default_module\": true, // Use this push module in case no pushModule was defined in a push iq msg\n            \"apns\": {\n                \"certFilePath\": \"\u003cPath to p12 file\u003e\",\n                \"certPassword\": \"\u003ccert password\u003e\",\n                \"topic\": \"\u003capp bundle id\u003e\"\n            },\n            \"ratelimit\": {\n                \"ratelimitTime\": \"20s\", // minimal duration between two pushes\n                \"ratelimitCleanupInterval\": \"300s\", // time how long old and unseen tokens should be keept inside the ratelimit cache before removal\n                \"enabled\": true // optionally disable ratelimit. Not advised for apple apns\n            }\n        },\n        \"someAndroidApp\": {\n            \"type\": \"google\",\n            \"is_default_module\": false,\n            \"fcm\": {\n                \"fcmSecretPath\": \"\u003cPath to json from google\u003e\"\n            }\n        },\n    },\n    \"timeout\": {\n        \"xmppconnectionError\": \"20s\" // time to wait after XMPP component connection failed before reconnecting\n    }\n}\n```\n\nThe configuration file consists of three sections.\nXMPP component settings (`component`) the push module configurations (`pushModules`) and a timeout config for the xmpp connection (`timeout`).\n\n### `component`\n\nThis section describes all config parameters for the XMPP component connection to the XMPP server handling all S2S connections.\n\n#### `componentHostname`\n\nJID of the pushserver.\nMust match the component JID configured on the XMPP server.\n\n#### `componentKey`\n\nThe component handshake element as configured on the XMPP server\n\n#### `serverHostname`\n\nHostname or IP address of the XMPP component endpoint (Usually the XMPP server that handles all S2S connections)\n\n#### `serverPort`\n\nPort of the XMPP component endpoint configured on the XMPP server.\n\n### `pushModules`\n\nMap of all push modules that should be loaded on start.\nEach push module can either be for apple APNS or for googles FCM.\nEach push module is identified by the key specified in the map.\nThis identifier is later used by clients to specifiy which of the configured push modules should be selected when an XMPP IQ is received by `fpush`.\n\nEach push module consists of a `type` element.\nCurrently `apple` and `google` are supported.\n\n#### `is_default_module`\n\nIf set to true, this push modules is used if an XMPP IQ was received that does not include any push module identifier.\nOnly one push module can be configured as the default module.\n\n#### `ratelimit`\n\nRatelimits for push tokens can be configured per push module.\n\n##### `enabled`\n\nEnable or disable ratelimiting for tokens\nIt is not advised to disable the ratelimiting\n\n##### `ratelimitTime`\n\nMinimal time between pushes for each push token.\nIf two push IQs are received for the same token within less time, the latter one is queued.\nIf more push request arrive for a token, while one push request is already queued, all further requests are ignored and an wait IQ is replied until the configured `ratelimitTime` is over.\n\n##### `ratelimitCleanupInterval`\n\n`fpush` caches the last timestamp when an push messages was sent for an token per push module to implement the ratelimit.\nThis cache is cleaned every 300 seconds.\nOn each cleaning run, tokens that were send more than `ratelimitCleanupInterval` ago are removed to free up memory space.\n\n#### `apns`\n\nThis section describes all apns related push options.\n\n##### `certFilePath``\n\nPath to the p12 certificate that should be used to connect to the APNS API.\n\n##### `certPassword`\n\nPasswort of the p12 certificate.\n\n##### `topic`\n\nBundle ID of the main app.\n\n##### `environment`\n\nAPNS environment to use. Supports `production` and `sandbox`. Default: `production`\n\n#### `fcm`\n\nThis section describes all fcm related push options.\n\n##### `fcmSecretPath`\n\nPath to the fcm json file created by google.\n\n### `timeout`\n\n#### `xmppconnectionError`\n\nTime to wait after XMPP component connection failed before reconnecting\n\n\u003ca name=\"structure\"\u003e\u003c/a\u003e\n## Structure\n\nFpush connects to a single XMPP server, that handles all S2S connections, as a XMPP component using an unencrypted connection.\nWe thus recommend to either place `fpush` on the same system as the XMPP server or securing the connection between the systems using `IPsec` or `wireguard`.\n\nIf the XMPP server is unreachable `fpush` will automatically try to reconnect after the configured time.\n\n\u003ca name=\"clustering\"\u003e\u003c/a\u003e\n## Clustering\n\n`fpush` can be clustered by simply running multiple servers on the same XMPP domain.\nUsing SRV records S2S traffic can be steered between the servers.\n\n`fpush` currently does not exchange ratelimit information betweeen cluster nodes.\nInstead each node manages its own independent ratelimit.\nHence, devices that are registered on more than on XMPP server may, receive push notifications via more than one cluster more frequent than expected.\n\n\u003ca name=\"compilation\"\u003e\u003c/a\u003e\n## Compilation\n\n`fpush` is written in Rust. (https://www.rust-lang.org/tools/install)\n\n### Debug build\n```bash\ncargo build\n```\n\n### Release build\n```bash\ncargo build --release\n```\n\n\u003ca name=\"compilation-flags\"\u003e\u003c/a\u003e\n### Compilation Flags\n\n`fpush` supports several features that can be activated while building using the `--features \u003cFlag1\u003e,\u003cFlag2\u003e` flag.\n\n#### Default features\n\nCurrently the following features are enabled by default.\n* `random_delay_before_push`\n* `enable_apns_support`\n* `enable_fcm_support`\n\nThe default features can be disabled using `--no-default-features`.\n\n#### Logging\n\n##### release_max_level_warn\n\nRemove all log messages lower than \"WARN\" from binary to increase speed.\n\n##### release_max_level_info\n\nRemove all log messages lower than \"INFO\" from binary to increase speed.\n\n#### Push module support\n\nPush modules support for different push vendors can be enabled during compilation.\nFor improved performance it is adviced to only enable/compile the needed push modules types (e.g. only apns).\n\n##### enable_fcm_support\n\nEnable google fcm support for android devices.\n\n##### enable_apns_support\n\nEnable apple apns support for iOS, iPadOS and macOS devices.\n\n##### enable_demo_support\n\nEnable a simple demo push endpoint used during development.\n\n##### random_delay_before_push\n\nImprove ratelimit acurracy by waiting a random delay before handling each push message.\n\nFor each incomming push event fpush spawns a new tokio thread.\nWithin each thread fpush checks if the supplied token is blocked or if the token is ratelimited.\nAfter a push message was sent for a token, fpush ratelimits the token (if configured) for a configured time to reduce the battery consumption of the remote device.\nDue to the multi thread design, two directly consecutive push events for the same token may not be correctly ratelimited.\nHence, adding a random async delay helps to improve the accuracy while keeping memory and cpu consumption low.\n\n\u003ca name=\"expandability\"\u003e\u003c/a\u003e\n### Expandability\n\nFpush can easily be expanded to support further push platforms by creating a new crate implementing the ```PushTrait```.\n\n\u003ca name=\"systemd\"\u003e\u003c/a\u003e\n### Systemd\n\nWe recommend running `fpush` as a seperate user without root permissions.\n\n```\n[Unit]\nDescription=Fpush\nAfter=network.target\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=10\nUser=fpush\nGroup=fpush\nLimitNOFILE=131072\nWorkingDirectory=/opt/fpush/\nEnvironment=RUST_LOG=info\nExecStart=/opt/fpush/fpush settings.json\n\n[Install]\nWantedBy=multi-user.target\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonal-im%2Ffpush","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonal-im%2Ffpush","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonal-im%2Ffpush/lists"}