Booper: Product spec

Booper is the easiest way to send push notifications via API.

What am I building?

A mobile app where users can subscribe to public and private channels to receive notifications programmatically via API.

Developers can create "apps" within the app to handle sending private notifications to their app users.

Why am I building it?

I wanted to build an alternative to Twilio, where I could programmatically trigger notifications to my phone as easily as possible without relying on SMS.

I wanted an app dedicated to receiving ad-hoc notifications. I don't want to have to rely on messenger apps like Slack, Discord, Telegram, etc. This feels like overkill for read-only notification messages.

What is new or different about it?

The main difference is the support for private "apps" within the product.

For example, I have a web app that handles sending Global Entry appointment schedule alerts to users via SMS. I would prefer to be able to set up a "Global Entry Alerts" app within Booper that allows users to subscribe to the channels for locations they'd like to receive alerts from (e.g. JFK, SFO). This has the tradeoff of requiring users to download a new app, but my hope is that users would be willing to do that for a lower price point.

Because I want to support custom private "apps", another difference is that I'll have to build a dashboard that allows developers to manage their apps and subscribers.

Who is the competition?

As far as I can tell, the main competition is ntfy.sh, an open source push notification app build in Golang.

Goals

  • Users can install the mobile app on both iOS and Android
  • Users do not need to login to use the app
  • Users can subscribe to public channels and receive notifications via API
  • Users can subscribe to private app channels via invite codes and receive notifications via API
  • Developers can create apps and send notifications to their subscribed users

Non-goals

  • No features will be paywalled in the initial version
  • I'm not going to worry about any advanced features like snoozing notifications, "remind me", or callback action buttons in notification messages

Milestones

This product will require four milestones to be finished in order to launch:

  1. Implementing public channel notifications
  2. Implementing private app channel notifications
  3. API rate limiting, retry logic, and error handling
  4. Publishing on the App Store

And a few post-launch follow-up milestones:

  1. Polish mobile app with offline mode, dark mode
  2. Open source API and add instructions for self-hosting

M1: Notifying public channel topics

The simplest use case I'd like to handle is allowing users to subscribe to channel topics on their mobile device, and receive push notifications for messages that are sent to that channel.

[M1.1] Device, channel, and notification APIs

  • Devices can be registered with a push token
    • POST /api/devices, or POST /api/identify
  • Devices can be subscribed to channels
    • POST /api/channels/[name]/subscribe
  • Devices can unsubscribe from a channel
    • POST /api/channels/[name]/unsubscribe
  • Notification messages can be created within channels
    • POST /api/channels/[name]/notify
  • When a device is subscribed to a channel, it should be alerted when a notification is created in that channel
  • Notification receipts are stored so we know which were sent successfully and which failed

[M1.2] Setting up the mobile app

  • User can be identified via device push token
  • User can subscribe to channel topics
  • User can unsubscribe from channels
  • User receives notification when subscribed channel is notified via API
  • App can be installed via TestFlight

M2: Notifying private app channels

Once users can subscribe to public channels, I'd like to make it possible for developers to set up their own "private apps" on Booper. This will allow developers to control who has access to their notifications.

[M2.1] Support for private app channel APIs

  • Developers can create/read/update/delete apps via the API to manage private notification channels
    • GET/POST /api/apps with JWT
    • GET/POST /api/apps/[id] with JWT
  • Apps have a name, optional description, optional logo, and a secret API key that can be used to invite users to their channels and send notifications
  • Developers can generate temporary access codes via the API to invite users to subscribe to their app channels
    • POST /api/access_codes with API key to generate
    • POST /api/access_codes/[code]/redeem to redeem
  • Developers can trigger notifications to their app channels
    • POST /api/channels/[name]/notify with API key to identify app

[M2.2] Mobile support for private app channels

  • Users have a tab where they can subscribe to private apps
  • Users subscribe to apps by entering the access code generated by the developer via the API above
  • After a user enters a valid access code, they are automatically subscribed to the channel(s) associated with the access code
  • If a user is subscribed to a private app channel, their device will receive notifications when a new message is created by the developer

[M2.3] Simple developer dashboard

  • Developers can create an account to access the dashboard
  • Developers can create apps from the dashboard UI
  • Developers can view all their apps in the dashboard
  • The app details page includes:
    • App name, description, logo
    • API key
    • App channels
    • API docs for managing subscribers and notifications
  • The app channel details page includes:
    • Channel name
    • Notification messages ordered by most recent
    • Channel subscribers, and when they subscribed

M3: API rate limiting and notification error handling

I'll need to handle potentially malicious users, as well as notifications that are not successfully sent the first time.

[M3.1] Rate limiting

  • Implement rate limiting for the public channel API endpoints
  • Implement rate limiting for the private app channel API endpoints
    • This can probably be a bit less strict than the public API rate limiting

[M3.2] Retrying failed notifications

  • The notification API should be processed asynchronously
  • Notification receipts should be tracked, and failed notifications should be retried if the error message indicates this is possible
  • Notification receipt error logs should be visible in the dashboard

[M3.2] Logging unexpected errors with Sentry

  • Set up Sentry to capture unhandled or unexpected errors
  • (Dogfooding opportunity: push Sentry errors to private app channel!)

[M3.3] Deleting stale notifications

  • Public notifications will be automatically deleted after 7 days
  • Private app notifications will be automatically deleted after 30 days

M4: Publish mobile app

In order for people to start using it, the mobile app will need to be published on the App Store and Play Store.

[M4.1] Submit to Apple App Store

  • Set up app logo and splash screen
  • Set up app privacy policy
  • Set up app contact form
  • Set up iOS screenshots

[M4.2] Submit to Google Play Store

  • Set up Android screenshots
  • Prepare app for closed testing (min 20 users, min 14 days)

M5: Mobile app polish

None of these are necessarily launch-blocking, but would be nice to have.

[M5.1] Polish realtime functionality

  • Use websockets to notify users as soon as new notification messages are created

[M5.2] Support offline mode

  • Users should be able to view all their notification messages even if they're offline

[M5.3] Dark mode

  • If a user's system settings are set to dark mode, display the app in dark mode

M6: Open sourcing and support for self-hosting

For a product like this, I imagine a lot of developers would be interested in self-hosting the API themselves. It would be nice to provide this as an option.

[M6.1] Make API repository public on GitHub

  • Remove any hardcoded API keys, or PII from code
  • Move repo from private to public

[M6.2] Add documentation for self-hosting

  • Use Fly.io for deployment
  • Update repo README with instructions for deploying to Fly.io

Launch plan

The launch will happen in 3 phases.

Phase 1: ~4 weeks

I'd love to get the first 4 milestones done in 4 weeks. I anticipate that it will take much longer to get the mobile app published to the Google Play Store due to new restrictions, so I won't block launching for that.

As soon as the app is published in the Apple App Store and the first three milestones are done, I plan on starting to share the project on smaller channels like Reddit, IndieHackers, and Bookface.

Phase 2: ~2 weeks

If the initial feedback is good, I'll push forward with the Android app release, and then launch on Product Hunt and Hacker News.

Phase 3: ~1 week

Depending on how that goes, I'll launch again with the open source self-hosted version.

Success criteria

After one month post-launching, I'd like to have at least 5 active apps, 100 active users, and 1000 notifications successfully sent.

If I can validate that there's growth, particularly around private app channels, I may start charging developers after a certain amount of usage on private app channels, since it doesn't make sense for me to run this project 100% for free.