8000 GitHub - radeva/notification-system
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

radeva/notification-system

Repository files navigation

Notification System

This project implements a notification system having the following requirements:

  • The system needs to be able to send notifications via several different channels (email, sms, slack) and be easily extensible to support more channels in the future.
  • The system needs to be horizontally scalable.
  • The system must guarantee an "at least once" SLA for sending the message.
  • The interface for accepting notifications to be sent is an HTTP API.

System Architecture

Notification System

Main Components

  • API server handles the notification requests, validates them and sends the corresponding messages to the RabbitMQ
  • Worker reads messages from the queues and processes them according the requested message provider
  • Status Database - both API Server and Worker save notification's current status and the number of attempts tried to send the message
  • Rabbit MQ receives the messages from the API Server and sends unacknowledged messages to the corresponding DLQ (dead letter queue)

Usage

The system supports two endpoints

  • POST /notifications for sending a notification
// Send sms
curl --location '<api_url>/notifications' \
--header 'Content-Type: application/json' \
--data '{
  "channel": "sms",
  "recipient": "+359888888888",
  "message": "Hello from the notification system!",
}'

// Send a slack message
curl --location '<api-url>/notifications' \
--header 'Content-Type: application/json' \
--data '{
  "channel": "slack",
  "recipient": "C08NKAKQ4N3", // channel ID
  "message": "Hello from the notification system!",
}'

// Send an email

curl --location '<api-url>/notifications' \
--header 'Content-Type: application/json' \
--data-raw '{
  "channel": "email",
  "recipient": "email@example.com",
  "message": "Hello from the notification system!",
  "metadata": {"email_subject": "My subject"}
}'

  • GET /notification/:id/status for getting notification status
curl --location '<api-url>/notifications/<notification-id>/status'

This is a Postman collection to which you can also refer.

Prerequisites

  • Go 1.24.1
  • Docker
  • Ginkgo ( go install github.com/onsi/ginkgo/v2/ginkgo)

Configuration

.env

Create a .env file in the root directory based on .env.example and make sure to fill in the proper values there.

RabbitMQ

To configure RabbitMQ you need a running instance of RabbitMQ to fill in the needed configuration values.

SMS

The system uses Twilio for sending sms messages. Follow the steps provided by Twilio to create an account and an active number. For test accounts you need to add the numbers that will receive the notifications as verified caller IDs.

Slack

For Slack notifications, the system uses a Slack app with registered Slack bot token. The app should be added to a Slack workspace and invited to the channel where the notifications will be sent.

Email (SendGrid)

The system uses Twilio SendGrid to send emails. You need to provide Twilio Sendgrid API key in .env for the notifications to work properly.

Database (PostgreSQL)

The database is used to save the current status of each message. It can be checked anytime using the GET /notifications/:id/status endpoint.

You can use DBeaver or similar tool to review database.

How to run locally?

  1. Set up your environment:

    cp .env.example .env
    # Edit .env with your configuration as described in the previous section
  2. Destroy tests containers (if any)

    docker-compose --env-file .env.test -f docker-compose.yml -f docker-compose.test.yml down
  3. Start the required services:

    docker-compose up -d
  4. Run the API service:

    go run cmd/api/main.go
  5. Run the worker service (in a separate terminal):

    go run cmd/worker/main.go

The API will be available at http://localhost:8080 RabbitMQ Web UI will be available at http://localhost:15672/

Run unit tests

ginkgo -v pkg/validation

Run integration tests

Integration tests use real instances of RabbitMQ and PostgreSQL and mocked notification providers for sms, slack and email.

To run the integration tests, execute the following commands :

  • docker compose down
  • cp .env.test.example .env.test
  • docker-compose --env-file .env.test -f docker-compose.yml -f docker-compose.test.yml up -d
  • DB_HOST=localhost RABBITMQ_HOST=localhost go test -v ./tests

How to run in production?

For production deployment:

  1. Set up a production-grade PostgreSQL database

  2. Configure a production RabbitMQ instance

  3. Configure SSL/TLS for secure communication

  4. Set up proper environment variables in your deployment environment

  5. Build and deploy the API and worker services:

    # Build the services
    go build -o api cmd/api/main.go
    go build -o worker cmd/worker/main.go
    
    # Deploy the binaries to your production environment
  6. Consider using a process manager like systemd or supervisor to keep the services running

  7. Consider using a load balancer like nginx ro route requests to multiple instances of the API server

  8. Consider running multiple workers for better scalability

  9. Set up proper monitoring and logging

  10. Automate infrastructure and deployment using Ansible, Terraform or any other Infrastructure as Code (IaC) tooling

Future Improvements

  • Protect the API with API keys
  • Protect the API with rate limiting - both general and per user
  • Write more tests to ensure quality
  • Support rich formatting of the messages
  • Add Slack channel validation for existence and permissions to send messages to that channel
  • Document the API with Swagger or similar tool

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

0