Notification click rules¶
Clicking a message popup opens the conversation in BlueFerry. Popups from other iPhone apps (shown with All iPhone Notifications) do nothing when clicked, unless you add a click rule for that app.
A click rule maps one iPhone app, identified by its exact bundle ID, to one fixed target:
- an
http/httpsaddress, opened in your default browser, or - a desktop entry ID (for example
org.mozilla.Thunderbird.desktop), launched like any installed app.
| iPhone app (bundle ID) | Example target |
|---|---|
com.apple.mobilemail |
org.mozilla.Thunderbird.desktop |
net.whatsapp.WhatsApp |
https://web.whatsapp.com |
com.tinyspeck.chatlyio |
com.slack.Slack.desktop |
com.google.calendar |
https://calendar.google.com/ |
What happens on a click¶
sequenceDiagram
participant iPhone
participant Daemon as BlueFerry daemon
participant Desktop as Notification server
participant Helper as Launch helper
iPhone->>Daemon: ANCS notification (app bundle ID)
Daemon->>Desktop: Popup with an "Open" action (only if a rule exists)
Desktop->>Daemon: Popup clicked (+ activation token)
Daemon->>Daemon: Look up the current rule for this app
Daemon->>Helper: Start helper with the configured target only
Helper->>Desktop: Open URL / launch app (outside the service sandbox)
The rule is looked up again at click time, so removing a rule also disables popups that are already on screen. A popup opens its target once. Clicks on popups for the same target within one second open it only once; the other popup stays clickable.
Some notification shells, such as Omarchy's, run a command stored in the popup instead of reporting the click. BlueFerry gives those popups a command that contains only a random ID for that popup. The command hands the ID back to the daemon, which then follows exactly the same steps as above. These shells dismiss the popup as soon as they run the command, so the ID stays valid for ten seconds after you dismiss a popup. After that, after a popup expired on its own, or after the service restarted, the ID is unknown and opens nothing.
Turn it on¶
Click rules only matter with All iPhone Notifications selected. There is no other switch: with no rules (the default), popups behave exactly as before.
Command line¶
blueferry notifications open-map set com.apple.mobilemail org.mozilla.Thunderbird.desktop
blueferry notifications open-map set net.whatsapp.WhatsApp https://web.whatsapp.com
blueferry notifications open-map list
blueferry notifications open-map remove net.whatsapp.WhatsApp
blueferry notifications open-map without a subcommand lists the rules.
Qt client¶
Under Desktop Notifications, an editor for click rules appears while All iPhone Notifications is selected. Add, change and remove rules there. Changes made with the CLI show up in the editor and the other way round.
Terminal client¶
Press l in blueferry-tui to open the click-rule panel. It lists the
rules; Enter on a rule copies it into the form, Save adds or changes a
rule, and Remove deletes the highlighted one. If the panel says rules
don't apply, select All iPhone Notifications in the settings of a
graphical client.
Rules take effect immediately; no service restart is needed.
Finding IDs¶
- Bundle ID: watch the log while the app sends a notification. BlueFerry logs each app once, without content:
journalctl --user -u blueferry -f | grep "ANCS app observed"
- Desktop entry ID: the file name of the app's
.desktopfile:
ls /usr/share/applications ~/.local/share/applications \
/var/lib/flatpak/exports/share/applications
Limits¶
- Bundle IDs are matched exactly and case-sensitively. Apple Messages
(
com.apple.MobileSMS) can't be mapped; it keeps opening the conversation. - URLs must be plain
http/httpsaddresses without credentials, spaces, quotes or other characters that need escaping, at most 2048 characters.javascript:,file:,data:and custom app schemes such asslack://are rejected. - Desktop entries must be bare IDs ending in
.desktop: no paths, arguments or commands. The CLI warns if the entry isn't installed; a missing entry does nothing when clicked. - At most 64 rules.
- The GTK and Quickshell clients have no editor; use the CLI, the Qt client or the terminal client.
- With systemd, the target is started in its own transient user unit
(
app-blueferry-open-*.service), because the BlueFerry service sandbox would break a browser. Without systemd (for example OpenRC), it is launched directly.
Privacy¶
- Nothing from the notification (title, text, sender) is added to the target or passed to the app. Only the app's bundle ID is used, to find the rule. No shell is involved.
- Rules are stored with the other popup preferences in
~/.config/blueferry/settings.json. That file is readable only by you but not encrypted, so don't put secret tokens (for example a private calendar URL) into a rule if that matters to you. - Logs never contain bundle IDs, URLs or desktop IDs.
- Rules are readable over D-Bus only through an authenticated, rate-limited method. No signal carries them, and neither do the popups: the notification server only sees the fixed "Open" action and, for shells that run a command, a random per-popup ID.
- While a target is being opened, its URL or desktop ID is briefly visible in the process list and in the transient unit, which reveals that a notification from that app was clicked.