1. 45
  1. 10

    Eyyy, this is my project. :-) – Happy to answer any questions.

    1. 2

      This is a great project! Btw Albufeira is in Portugal. :-)

      1. 2

        This is the most random comment I have ever received. Thanks for that :-D – It took me a looooong time to figure out that you’re referring to the travel map on my blog. Hehe.

      2. 2

        Hi - this looks nice.

        What is the security story here? Is there a document that shows the flow from curl all the way to the notification on the phone?

        1. 2

          Hi. There’s no documentation page (yet) that describes architecture and flow, though just judging by how often I have ASCII-drawn it, there really should be one :-)

          From the very start, ntfy was designed as a convenience-first app (as simple as possible), which you can see by how simple the curl and POST/PUT requests are. That’s not an excuse, it’s just a conscious choice I made. Because of that, nothing is encrypted at rest (only transport encryption if TLS is used).

          Flow 1 (with Firebase):

          client (e.g. curl) ---[HTTP(S)]---> ntfy server [store in cache] ---> Firebase ---> Android app
          

          Flow 2 (without Firebase):

          client (e.g. curl) ---[HTTP(S)]---> ntfy server [store in cache] ---[HTTP(S) JSON/WS]--> Android app
          

          Flow 3 (iOS):

          client (e.g. curl) ---[HTTP(S)]---> ntfy server [store in cache] ---> Firebase ---> APNS ---> iOS
          

          Messages are stored in plaintext in a SQLite database on the server, unless the X-Cache: no header is passed. All messages are forwarded to Firebase, unless the X-Firebase: no header is passed.

          If you want private messages, you can either wait for the E2E feature (https://github.com/binwiederhier/ntfy/issues/69), which I have already begun developing, and which sadly destroy the ease of use.

          Or you can run your own selfhosted server and add basic auth and ACLs (https://ntfy.sh/docs/config/#access-control).

          1. 3

            For more complex cases, it’s worth looking at what Signal does. They basically treat the notification services as a 1bit signal that there is something pending (I think that they may also send occasional spurious ones to make traffic correlation harder). Once the app receives the notification, it wakes up and polls the real service.

            I couldn’t see anything about efficiency though. The reason most apps use a notification service is to allow a single background service that consumes a tiny amount of RAM to have a single network connection with a very long timeout and then wake up when a notification arrives and prod the system to either forward it to the running app or start the app and forward it if necessary. From the examples, it wasn’t clear how you achieve anything like this, it looked as if the apps were running in the foreground and received the notification directly. I guess you are doing this because. I believe, iOS doesn’t allow background apps to maintain persistent network connections.

            1. 1

              They basically treat the notification services as a 1bit signal that there is something pending

              This is what ntfy does for iOS for selfhosted servers: It sends a poll_request via APNS, and then the app will poll the original selfhosted server. There’s a description of this here: https://ntfy.sh/docs/config/#ios-instant-notifications – iOS is veeeeery limited in what you can do. Everything has to go through a central server, so selfhosted servers are technically not really possible at all. It’s quite sad.

              I couldn’t see anything about efficiency though.

              I responded a bit about this here: https://lobste.rs/s/41dq13/zero_cost_push_notifications_your_phone#c_b6qfnd – Bottom line is that for Android, it’s either Firebase (FCM) or a long-standing JSON stream or WebSocket connection. FCM consumes no battery, and the foreground service consumes 0-1% on my phone for the entire day. If used heavily obviously more

              1. 2

                I see. I was hoping that it was possible to use this stand alone, but I guess that’s just not permitted on iOS. It would be nice if there were an Android service that de-Google’d devices could use as a single thing maintaining a service and multiplex the waiting so that apps using an individual server can still exit and be restarted when a notification aimed at them arrives.

                1. 2

                  It would be nice if there were an Android service that de-Google’d devices could use as a single thing maintaining a service and multiplex the waiting so that apps using an individual server can still exit and be restarted when a notification aimed at them arrives.

                  I think you are talking about what https://unifiedpush.org/ is trying to be. ntfy is a distributor for UnifiedPush-enabled apps.

                  1. 2

                    Yes, exactly! Thank you!

        2. 2

          Great docs and cool concept. Well done!

          Not a question, but I assume you’re accepting compliments as well :)

          [edit]

          I actually have a suggestion for the mobile apps. Support deep links to reconfigure the notification server, e.g. https://ntfy.sh/configure?base_url=<NEW NTFY SERVER URL>. When accessed, the user is prompted to allow the app to be reconfigured with the new notify server URL. This would allow self-hosters to more easily roll out push notifications using self-hosted instances. Maybe not a priority for you as a fun open source project with no profit motive, but possibly worth considering.

          1. 1

            I always try to write the docs the way I’d want them from other projects: Lots of examples and pictures :D – Thank you for the kind words.

            [edit]

            Support deep links to reconfigure the notification server

            Surprisingly, this has been suggested recently (https://github.com/binwiederhier/ntfy/issues/440). It’s surprising to me, because I don’t quite understand the use case. If you have a self-hosted server, why would you need a shortcut to configure the app that way? Why not just go in the settings and configure it yourself. It’s a step you have to do only once, so it surely can’t be a huge hassle, right?

            I’m genuinely asking, because maybe I don’t quite understand the case. Feel free to answer or +1 the GitHub ticket.

            1. 2

              Cool, I’ll go ahead and follow up with details on the GH issue.

        3. 4

          One reason zulip sends push notifications through their server is apparently a security measure where the account key baked into the app is the only one that can send notifications.

          Ntfy gets around that by ignoring what Google wants and making the app ui specify where you will sub including host names.

          1. 4

            That looks pretty cool. How does the power consumption look like? Many years ago I checked how google was handling its notification, and it was pretty involved, with some help from the carriers to minimize the power consumption. Is it still a concern?

            1. 2

              If I may quote from the FAQ (https://ntfy.sh/docs/faq/#how-much-battery-does-the-android-app-use):

              If you use the ntfy.sh server, and you don’t use the instant delivery feature, the Android/iOS app uses no additional battery, since Firebase Cloud Messaging (FCM) is used. If you use your own server, or you use instant delivery (Android only), the app has to maintain a constant connection to the server, which consumes about 0-1% of battery in 17h of use (on my phone). There has been a ton of testing and improvement around this. I think it’s pretty decent now.

              Happy to answer other questions you have.

              1. 2

                Oh didn’t see the faq, thanks, that’s pretty good to see that. Even the version not using fcm is good.

            2. 2

              Is there a way to embed it in an application?

              1. 1

                Of course. It’s just an API to publish and subscribe messages. You can publish messages via HTTP PUT/POST (https://ntfy.sh/docs/publish/), and subscribe via WebSockets or JSON stream (https://ntfy.sh/docs/subscribe/api/). As for the Android app, you can integrate it via Android intents (https://ntfy.sh/docs/subscribe/phone/#automation-apps) or UnifiedPush (https://ntfy.sh/docs/subscribe/phone/#unifiedpush). You cannot embed the Android application yet, though I’d not be opposed to making that possible if somebody was willing to do the work for it.

              2. 1

                Late reply but I use a similar project that’s self-hostable: https://gotify.net/