Website visitors text a business; the business replies from its own phone.
Ping is a SaaS product made of three pieces:
- an embeddable contact widget that any website can add with one script tag
- an SMS relay that connects each visitor to the business through Twilio
- an admin dashboard where businesses manage widgets, contacts, conversations, billing and analytics
client.ping.buzz:
admin.ping.buzz:
- A business signs up, creates a widget in the dashboard and pastes the snippet into its site.
- A visitor opens the widget, leaves a name and phone number, and writes a message.
- Ping texts the message to the business from a Twilio number paired with that visitor. When the business replies to that number, the reply is routed back to the visitor's phone. Each side sees an ordinary text thread and neither has to install anything.
- Every message is stored as a conversation in the dashboard, alongside widget analytics and Stripe billing.
- Number-pairing SMS relay. Each (business, visitor) pair is assigned a proxy number, so replies can be routed without exposing either side's real number (
packages/core/src/sms,packages/core/src/messaging/router). - Functional, typed domain core. Every domain value (phone numbers with country, verified email addresses, person names, URLs, UUIDs, ...) is an
io-tscodec, and every use case returns anfp-tsEitherof typed errors instead of throwing (packages/core/src/values). - Ports and adapters. The core depends only on interfaces (
packages/core/src/interfaces). Twilio, Stripe, SendGrid, Firestore, HTTP and WebSocket adapters plug in at the edge (packages/api/src/adapters). - Framework-free embeddable widget. Plain DOM and CSS with no UI framework, so it loads fast on any host site, plus a small SDK for configuring it (
packages/client/src). - Complete SaaS loop:
- passwordless magic-link login (
packages/core/src/iam) - Stripe subscriptions with a self-serve billing portal (
packages/core/src/billing) - widget analytics, and a React dashboard covering all of it (
packages/admin)
- passwordless magic-link login (
- Email quality checks. Sign-ups are screened against lists of disposable and free-mail domains (
packages/core/src/values/email-address).
| Package | What it is |
|---|---|
core |
Domain model and use cases: accounts, authentication, widgets, contacts, conversations, SMS, billing, analytics |
api |
Node.js server wiring the core to Twilio, Stripe, SendGrid, Firestore, HTTP and WebSockets |
client |
Embeddable widget and SDK served from client.ping.buzz |
admin |
React dashboard served from admin.ping.buzz |
TypeScript (Node.js and React) in a Lerna monorepo; fp-ts and io-ts; Google Cloud Datastore/Firestore and Redis; Twilio, Stripe and SendGrid; Netlify for the client and admin, and a Google Cloud VM for the API.
- Install Node.js, npm and Redis.
- Run
npm run bootstrapin the project root. - Add
.envfiles inpackages/api,packages/clientandpackages/adminas described in each package's README.
- Start Redis.
- Run
npm startin the project root, or inside a single package.
api: deployed manually to the Google Cloud VM.clientandadmin: deployed automatically by Netlify on every push tomaster.