continuwuity/docs/guides/push.mdx
stratself c66fb684f0
docs: Add guide for push notifications (#2244)
Adds a page for push notifications under /guides. The main thing it covers are how push works in Matrix, UnifiedPush usage and selfhosting, and some troubleshooting of common push issues.

I took the liberty to include various aspects of push not pertaining to the server itself, because it was commonly asked in our chatrooms and are quite important for all matrix users. Kind of like livekit.

Closes #2136

Reviewed-on: continuwuation/continuwuity#2244
Reviewed-by: Jade Ellis <jade@ellis.link>
Reviewed-by: Henry-Hiles <henry@henryhiles.com>
Reviewed-by: lveneris <tyler@kludgecs.com>
2026-10-12 09:23:45 +00:00

215 lines
12 KiB
Text

import { Tab, Tabs } from '@rspress/core/theme';
# Push notifications
Matrix clients receive notifications in the following ways:
- **In-band notifications**, which are shown when the client actively syncs with the server.
- **Push notifications**, which are posted to the client by the server through an external push service. This is typically used to send out-of-band notifications to mobile devices, and it is the focus of this page.
Generally, your mobile device is preconfigured for push notifications out of the box. The details below are for advanced use cases, such as using an alternative push backend (like UnifiedPush) or hosting your own.
## Overview
Continuwuity supports two push methods: the legacy **Matrix Push Gateway** and the new **Web Push** protocol. The former is currently supported by more clients, but the latter enables end-to-end-encrypted push notifications. They work as follows:
<Tabs groupId="push-ops">
<Tab label="Registration">
<img src="./push-registration.webp"
alt="Diagram showing the push registration flow, described in the text below."
style= {{"max-height":300,display:"flex",margin:"1rem auto","border-radius":"5px"}}
/>
1. A client app obtains a _push key_ from the push app that it hooks up to.
2. Then, it registers a _pusher_ with Continuwuity, bringing along the _push key_ and the following additional information:
- For the Push Gateway method: The _push gateway_ URL, which is [provided by the client](#unifiedpush-and-push-gateways).
- For the Web Push method: Some _encryption details_ generated by the client, so the server knows how to encrypt its push payloads.
</Tab>
<Tab label="Operation (Push Gateway)">
<img src="./push-operation-gateway.webp"
alt="Diagram showing the push operation with the Push Gateway method, described in the text below."
style={{"max-height":300,display:"flex",margin:"1rem auto","border-radius":"5px"}}
/>
1. Continuwuity pushes messages to the push gateway
2. The push gateway converts the messages to a suitable format and forwards them to the push provider server.
3. The push provider server passes them along to the push app.
4. The push app wakes the client, prompting it to fetch new messages from Continuwuity.
5. Finally, the client calculates against a set of _push rules_ to determine whether the fetched message(s) should be notified to users.
</Tab>
<Tab label="Operation (Web Push)">
<img src="./push-operation-webpush.webp"
alt="Diagram showing the push operation with the Web Push method, described in the text below."
style={{"max-height":300,display:"flex",margin:"1rem auto","border-radius":"5px"}}
/>
1. Continuwuity pushes encrypted messages to the push provider server.
2. The push provider server passes them along to the push app.
3. The push app wakes the client, which decrypts the payload, and if needed, fetches new messages from Continuwuity.
4. Finally, the client calculates against a set of _push rules_ to determine whether the pushed message(s) should be notified to users.
Note that this mechanism does not require a push gateway component.
[MSC4174]: https://github.com/matrix-org/matrix-spec-proposals/pull/4174
</Tab>
</Tabs>
_([excalidraw file of the diagrams](/guides/push-notifications.excalidraw))_
Therefore, Continuwuity's role within this system is to keep track of client-registered _pushers_ and send relevant payloads to them. To view and manage these pushers, use the [`!admin query pusher`](../reference/admin/query.md#admin-query-pusher) set of commands.
## UnifiedPush
[UnifiedPush][unifiedpush] is an open and self-hostable notifications system that is supported by many Matrix clients on Android and Linux. It is compatible with both the Web Push and Push Gateway mechanisms, and therefore requires no additional setup from the homeserver.
:::info Debugging UnifiedPush
To debug and test your UnifiedPush installation, use the [UP-Example] app for Android and the [UnifiedPush Troubleshooter] app for Linux distributions.
:::
[unifiedpush]: https://unifiedpush.org
[UP-Example]: https://codeberg.org/UnifiedPush/android-example
[UnifiedPush Troubleshooter]: https://flathub.org/en/apps/org.unifiedpush.Troubleshooter
### UnifiedPush and push gateways
The push gateway URL is usually pre-configured by the client app. However, some clients (such as Element X) implement UnifiedPush's [Gateway Discovery] mechanism, and attempt to detect a push gateway _on the same domain as the push provider_, before falling back to a hardcoded one.
Per the [spec][spec-push-gateway-api], these push gateways must be available on the `/_matrix/push/v1/notify` path of said domain. To test that a push gateway is accessible to the homeserver, make a request for it from the homeserver's IP:
```txt
curl https://push.example.com/_matrix/push/v1/notify
{"unifiedpush":{"gateway":"matrix"}}
```
[Gateway Discovery]: https://unifiedpush.org/users/gateway/#discovery--hosting
### ntfy
[ntfy][ntfy] is a widely supported UnifiedPush implementation, with an easy-to-install push app and plenty of publicly available instances. Its server includes an embedded Matrix push gateway and can be self-hosted.
Some tutorials on self-hosting ntfy can be found below:
- [Official ntfy self-hosting tutorial][official-ntfy-selfhosting]
- [Element's tutorial on Unified Push and ntfy][element-ntfy]
:::warning Avoid ntfy.sh
Avoid using the `https://ntfy.sh` push server, which is configured as the default in the ntfy app. This server is known to ratelimit requests aggressively.
:::
[ntfy]: https://ntfy.sh
[element-ntfy]: https://docs.element.io/latest/element-support/element-androidios-client-settings/using-unified-push-and-ntfy-for-push-notifications/
[official-ntfy-selfhosting]: https://docs.ntfy.sh/install/
### Other UnifiedPush distributors
To find a list of other UnifiedPush distributors, visit this [page][unifiedpush-distributors].
[unifiedpush-distributors]: https://unifiedpush.org/users/distributors/
Community tutorials for selfhosting some of these stacks are listed below. Unless stated otherwise, they are all tested against Element X Android and the push gateway mechanism, but they should work with Web Push as well.
- [Self-hosting Sunup for Matrix and UnifiedPush][kimiblock-selfhosting-sunup], by Kimiblock.
- Push gateway: [common-proxies]
- Push server: [autopush-rs]
- Push app: [Sunup][sunup]
- [Matrix notifications on Android, powered by XMPP][stratself-xmpp], by stratself.
- Push gateway: [common-proxies]
- Push server: [ejabberd's mod_unified_push]
- Push app: [Conversations] (and forks)
- [Element X push notifications via Conversations][alfredolin-xmpp], by Alfredo Lin.
- Push gateway: [common-proxies]
- Push server: [Prosody's mod_unified_push]
- Push app: [Conversations]
- Nextcloud's NextPush flow, which uses the following stack:
- Push server + push gateway: [uppush] (selfhosting tutorial included)
- Push app: [NextPush Android]
[kimiblock-selfhosting-sunup]: https://blog.kimiblock.top/2025/09/11/selfhosting-sunup/
[stratself-xmpp]: https://muoi.me/~stratself/articles/matrix-notifs-xmpp
[alfredolin-xmpp]: https://alfredolin.eu/blog/2026/07/24/element-x-push-notifications-via-conversations/
[common-proxies]: https://codeberg.org/UnifiedPush/common-proxies/
[sunup]: https://codeberg.org/Sunup/android
[autopush-rs]: https://github.com/mozilla-services/autopush-rs
[ejabberd's mod_unified_push]: https://github.com/processone/ejabberd-contrib/tree/master/mod_unified_push
[Prosody's mod_unified_push]: https://modules.prosody.im/mod_unified_push
[Conversations]: https://conversations.im
[uppush]: https://codeberg.org/NextPush/uppush
[NextPush Android]: https://codeberg.org/NextPush/nextpush-android
## Troubleshooting
Issues with push notifications can arise from the components of the system beyond your homeserver (for example, if the connection fails between the gateway and the push server). Make sure you check the logs of these components for debugging as well.
### Locally hosted push gateways / push providers
Outbound requests, including push notifications, follows the `ip_range_denylist` config option which refuses loopback and private-range destinations by default. This would break against push components that are self-hosted on a LAN address, and will result in these log entries at push creation time:
```txt
WARN conduwuit_service::pusher: Pusher URL is a forbidden remote address url=https://push.example.com/_matrix/push/v1/notify
```
To fix this, remove your push gateway or push server's address from `ip_range_denylist`, and restart Continuwuity to apply the changes.
### Push notifications not audible/not displaying
This is likely an issue with your account's _push rules_, which determines which events are shown to to the user as notifications. Check these push rules in the client's notifications settings and tweak accordingly. Continuwuity also provides an [`!admin users reset-push-rules`](../reference/admin/users#admin-users-reset-push-rules) command, which restores the rules to the default of notifying for every message.
Another reason may be that push background services are frequently being terminated by your operating system, which is a [well-known problem][dontkillmyapp] with many Android-based systems. To fix this, follow your operating system's instructions to exempt your push app from background restrictions.
Otherwise, if you find Continuwuity not sending push notifications according to the spec, feel free to discuss in our [support room][support-room] or open an issue.
[dontkillmyapp]: https://dontkillmyapp.com
[support-room]: https://matrix.to/#/#continuwuity:continuwuity.org?via=continuwuity.org&via=ellis.link&via=explodie.org&via=matrix.org
### Various "Could not send request to pusher" log entries
If you find spurious log entries like this in your Continuwuity deployment:
```txt
WARN push{user_id="@user:example.com" pushkey="very-long-string-of-letters" events=1}:send_push_notice:send_notice:send_request: conduwuit_service::pusher: Could not send request to pusher https//push.example.com: error sending request for url (https://push.example.com/_matrix/push/v1/notify)
```
Then, your server is most likely sending push requests to too many invalid targets. This could be due to one of the following reasons:
#### Connection issues between the server and the push gateway
Verify that the connection to the push gateway is working correctly. This includes checking firewall rules, DNS, and that the push gateway is online. The section on [locally-hosted gateways/push providers](#locally-hosted-push-gateways--push-providers) may also apply to you.
#### Expired push endpoints
Active Matrix clients periodically renew their pushkeys as the old ones expire, and consequently register them against Continuwuity. As these pushers build up over time, the homeserver will keep sending more requests to an increasing number of "dead" push endpoints. This results in the errors seen above, and can heavily impact performance if not mitigated.
To work around this issue, the following actions can be taken:
- Delete all of a user's pushers with the [`!admin query pusher delete-all-user`](../reference/admin/query##admin-query-pusher-delete-all-user) command. This command is not typically disruptive, as active clients will re-register new pushers the next time they log on.
- Alternatively, delete one's own pushers from a client that supports doing so. Currently this only includes FluffyChat and Element Classic/SchildiChat Legacy.
While clients are supposed to automatically delete old pushers under their own control, this behaviour has been inconsistent. A further discussion of this issue can be found in [#2242][issue-2242].
[issue-2242]: https://forgejo.ellis.link/continuwuation/continuwuity/issues/2242
## Related Documentation
Specifications:
- [Matrix specification for the Push Gateway API][spec-push-gateway-api]
- [Matrix Client-Server API for push notifications][spec-c-s-push-notifications]
- [UnifiedPush specifications][unifiedpush-spec]
- [MSC4174: Web push][MSC4174]
- [Web Push RFCs][webpush-rfcs]
Other:
- [Matrix Push Rules and Notifications][clokep-push] - blogpost on push rules in Matrix
[webpush-rfcs]: https://datatracker.ietf.org/wg/webpush/documents/
[spec-push-gateway-api]: https://spec.matrix.org/latest/push-gateway-api/
[spec-c-s-push-notifications]: https://spec.matrix.org/latest/client-server-api/#push-notifications
[unifiedpush-spec]: https://unifiedpush.org/developers/spec/definitions/
[clokep-push]: https://patrick.cloke.us/posts/2023/05/08/matrix-push-rules-notifications/