Nudges¶
Nudges is a demo implementation of a paid SMS relay platform. It allows businesses ("clients") to send SMS announcements to their subscribers, with subscription management and payment processing via Stripe.
This repository serves as a proof-of-concept demonstrating a modern, event-driven microservices architecture using .NET, GraphQL, Kafka, and React.
Quick Start¶
Prerequisites¶
- Docker and Docker Compose
- .NET SDK (for dev-certs)
- Stripe account (free)
- ngrok account (free)
- PowerShell
1. Setup ngrok¶
Create ngrok/ngrok.yml:
version: "2"
authtoken: <your_auth_token>
tunnels:
webhooks:
proto: http
addr: host.docker.internal:7071
domain: <your_domain>
2. Setup Stripe Webhooks¶
In Stripe Dashboard > Developers > Webhooks, add endpoint:
- URL:
https://<your_domain>/api/StripeWebhookHandler?code=<your_api_key> - Events:
product.created - Copy the Signing secret
3. Configure Environment¶
Create .env.external at repo root:
STRIPE_API_KEY=<your_stripe_api_key>
STRIPE_WEBHOOKS_SECRET=<your_signing_secret>
WEBHOOKS_API_KEY=<your_api_key> # must match URL above
# Optional (not needed for demo)
TWILIO_ACCOUNT_SID=xxx
TWILIO_AUTH_TOKEN=xxx
TWILIO_MESSAGE_SERVICE_SID=xxx
4. Start the System¶
# Generate certificates
dotnet dev-certs https -ep ./certs/aspnetapp.pfx
./certs/generate-certs.ps1
# Start all services
./start-dev.ps1
First run takes ~20 minutes to build. Once ready, open https://localhost:5050.
Login: +15555555555 / pass
Architecture Overview¶
flowchart TB
subgraph Clients
Web[React UI]
end
subgraph Gateway
GQL[GraphQL Gateway]
end
subgraph APIs
UserApi
ProductApi
PaymentApi
end
subgraph Events
Kafka
KafkaConsumer[Kafka Consumers]
end
subgraph External
Stripe
Twilio
end
subgraph Data
PostgreSQL
Redis
end
Web --> GQL
GQL --> UserApi
GQL --> ProductApi
GQL --> PaymentApi
APIs --> Kafka
Kafka --> KafkaConsumer
KafkaConsumer --> Stripe
KafkaConsumer --> Twilio
Stripe --> Webhooks
Twilio --> Webhooks
Webhooks --> Kafka
APIs --> PostgreSQL
APIs --> Redis
How It Works¶
When a user creates a plan in the UI:
sequenceDiagram
participant UI as React UI
participant Gateway as GraphQL Gateway
participant API as ProductApi
participant Kafka
participant Consumer as KafkaConsumer
participant Stripe
participant Webhooks
UI->>Gateway: CreatePlan mutation
Gateway->>API: createPlan
API->>API: Save to DB
API->>Kafka: PlanCreatedEvent
API-->>UI: Plan created
Kafka->>Consumer: Consume event
Consumer->>Stripe: Create Product
Stripe->>Webhooks: product.created webhook
Webhooks->>Kafka: StripeProductCreatedEvent
Kafka->>Consumer: Consume sync event
Consumer->>API: PatchPlan (add Stripe ID)
API-->>UI: onPlanUpdated subscription
Repository Structure¶
| Directory | Contents |
|---|---|
dotnet/ |
All .NET services and libraries |
web/ |
React applications (admin UI, signup) |
db/ |
Database scripts and migrations |
terraform/ |
AWS infrastructure as code |
mkdocs/ |
This documentation |
.github/ |
CI/CD workflows |
Key Technologies¶
- Backend: .NET 10, ASP.NET Core, HotChocolate (GraphQL)
- Frontend: React, Relay, TypeScript
- Messaging: Apache Kafka
- Database: PostgreSQL, Redis
- Auth: Keycloak (OIDC/OAuth2)
- Payments: Stripe
- SMS: Twilio
- Infrastructure: AWS (ECS, RDS, ElastiCache), Terraform