Skip to content

Post0HQ/notification-service

Repository files navigation

📧 Post0 Notification Service

A TypeScript + Bun powered notification service that sends templated emails using Nodemailer and schedules them with BullMQ + Valkey.
The service is exposed via a REST API (Hono) with internal authentication.


✨ Features

  • ✅ Templated email rendering (welcome, pre_post, post_success, post_error)
  • ✅ Queue-based job handling using BullMQ + Valkey
  • ✅ Scheduled emails (using delay in BullMQ)
  • ✅ Secure API with internal service authentication (INTERNAL_API_TOKEN)
  • ✅ Centralized environment config loader with type safety
  • ✅ Health check endpoint

📂 Project Structure

src/
├── api/
│ ├── server.ts # REST API routes (Hono)
│ └── notify.ts # Notification route
├── core/
│ ├── queue.ts # BullMQ queues
│ ├── mailer.ts # Nodemailer wrapper
│ ├── templates.ts # Email templates + schema
│ └── auth.ts # Internal API auth middleware
├── utils/
│ ├── schemas.ts # NotificationSchema (Zod)
│ ├── logger.ts # Logger
│ └── config.ts # env loader (dotenv)
├── worker.ts # BullMQ worker (processes jobs)
└── index.ts # API server entrypoint


⚙️ Environment Variables

All variables are loaded and type-validated through src/utils/config.ts.

Variable Required Description
SMTP_HOST SMTP server host
SMTP_PORT SMTP server port (default: 587)
SMTP_USER SMTP username
SMTP_PASS SMTP password
QUEUE_HOST Valkey/Redis host
QUEUE_PORT Valkey/Redis port (default: 6379)
QUEUE_DB Redis DB index (default: 0)
QUEUE_PASSWORD Redis password (if set)
INTERNAL_API_TOKEN Secret token for internal API authentication
VALID_SERVICES Comma-separated list of allowed service names (e.g. post_service,analytics_service)
NODE_ENV Node environment (development, production)

Example .env:

SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=587
SMTP_USER=my_smtp_user
SMTP_PASS=my_smtp_pass

QUEUE_HOST=127.0.0.1
QUEUE_PORT=6379
QUEUE_DB=0
QUEUE_PASSWORD=

INTERNAL_API_TOKEN=supersecret
VALID_SERVICES=post_service,analytics_service

NODE_ENV=development

🚀 Running the Service

1. Install dependencies

bun install

2. Run API server + worker together

bun run dev

📡 API Endpoints

Health Check

GET /

Response:

{
  "status": "ok",
  "timestamp": "2025-08-24T10:00:00.000Z",
  "uptime": "120 seconds"
}

Queue Email

POST /api/v1/notify
x-service-key: <INTERNAL_API_TOKEN>
x-service-name: <SERVICE_NAME>
Content-Type: application/json

Example payloads:

Welcome email

{
  "to": "user@example.com",
  "type": "welcome",
  "data": { "user": "Priyanshu" },
  "sendAt": "2025-08-25T10:00:00.000Z"
}

Post error email

{
  "to": "user@example.com",
  "type": "post_error",
  "data": {
    "user": "Priyanshu",
    "postTitle": "10 Tips for LinkedIn Growth",
    "error": "LinkedIn API returned 500"
  }
}

Response:

{ "status": "queued", "queueId": "bull:jobid123" }

🐳 Docker

Build and run with Docker:

docker build -t notification-service .
docker run --env-file .env -p 3000:3000 notification-service

🛠️ Development Notes

  • The worker and server can run in the same process for simplicity, but in production you’ll typically scale workers separately.

  • For hosting:

    • Server can run on Vercel (API only).
    • Worker must run on a persistent container (Docker, Fly.io, Railway, etc.), since Vercel functions cannot run background jobs.

About

A notification service

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors