Skip to content

ruby-native/pingrb

Repository files navigation

pingrb

A tiny push notification app to get alerts on anything.

pingrb turns webhook events into clean push notifications. Stripe paid, deploy failed, agent finished. Anything that can POST lands as a push on your phone.

Live at pingrb.com. iOS app on the App Store. Android coming soon.

Built with Ruby Native. One Rails app, both platforms, no Xcode.

Sources

Each source has its own webhook URL or CLI token. Parsers are self-describing: WebhooksController doesn't case-switch on parser type, each parser handles its own auth and parsing.

  • Stripe (HMAC): payments, subscriptions, refunds, disputes
  • Cal.com (HMAC): bookings, reschedules, cancellations
  • GitHub (HMAC): opened issues, new comments, failed workflow runs
  • Hatchbox (token-in-URL): failed deploys
  • StatusCake (token-in-URL): site down, recovered
  • Custom (token-in-URL): any {title, body, url} JSON payload
  • CLI (token-in-URL): a Go binary (brew install ruby-native/tap/pingrb) for agents and scripts

How it works

  1. Sign up.
  2. Add a source.
  3. Paste the webhook URL into the source's destination, or install the CLI.
  4. Get pinged on every event, parsed into a one-liner.

Stack

  • Rails 8.1 on Ruby 4.0
  • SQLite (multi-database: primary, cache, queue, cable)
  • Solid Queue / Solid Cache / Solid Cable
  • Hotwire (Turbo + Stimulus) with morph-refresh broadcasts
  • Tailwind CSS v4 (IBM Plex Mono throughout)
  • iOS and Android apps via Ruby Native (ruby_native gem)
  • Push delivery via action_push_native to APNs and FCM
  • Postmark for mail

Local development

bin/setup        # bundle install + db setup + seed
bin/dev          # Tailwind watcher + Rails server on :3010
bin/rails test

The dev seed creates a user@example.com / password account with sources and notifications. The sign-in form auto-fills these in development.

For real webhook testing, the named Cloudflare tunnel at pingrb.rubynative.com points to localhost:3010. The public_webhook_url helper reads tmp/public_host so source pages display the public URL to paste into Stripe, Cal.com, etc.

Adding a new source

See CLAUDE.md for the full pattern. Short version:

  1. app/parsers/<name>_parser.rb inheriting from Parser
  2. Add to Source::PARSER_TYPES and (usually) Source::CREATABLE_PARSER_TYPES
  3. Setup and test partials at app/views/sources/_setup_<name>.html.erb and _test_<name>.html.erb
  4. Tests at test/parsers/<name>_parser_test.rb
  5. Seed fixtures at db/seeds/webhooks/<name>/*.{json,txt}

Deploy

Hatchbox auto-deploys main on push. Solid Queue must run inside Puma in production, gated on SOLID_QUEUE_IN_PUMA=true. Without that env var, push delivery jobs enqueue but never execute.

The iOS app builds via bundle exec ruby_native deploy. The build pulls the latest v* tag from ruby-native/native, so iOS-side changes require tagging a release on the native repo.

License

Private.

About

A tiny push notification app to get alerts on anything.

Resources

Stars

Watchers

Forks

Contributors