Create a notification sending system:
- 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 can be chosen on your own discretion.
The system supports sending notifications through different channels. A single notification can be sent to a single channel. It has a http handler for accepting notifications. It uses kafka for processing them.
- API
POST /notifications
Content-Type: application/json
{
"channel": "slack",
"message": "message"
}
Kafka message value structure:
{
"channel": "email",
"message": "email message"
"retry_count": 0
}
On failure the notification is sent to a retry-topic, depending on max_retries
from the config. When max_retries
has been exceeded the system sends the notification to a dead-letter-topic where it can be investigated and handled manually.
The system expects a yaml config file, the path can be specified by running it with a flag --config path/to/config.yaml
, by default it looks for a config.yaml in the root directory. See ./config_example.yaml
. Desired channels can be specified in the config.
The system supports adding new channels.
- Create a new Slack App
- Give your bot/app the following OAuth permission scopes:
chat:write
,chat:write.public
- Copy your Bot User OAuth Access Token and desired Channel ID and add them to the config
The email channel uses smtp.
Channel that can be used for testing purposes. It writes the received messages to os.Stdout
.
Requires Docker
docker-compose
- Create a
config.yaml
by copyingconfig_example.yaml
cp config_example.yaml config.yaml
- Fill in desired channel config, by default only the Log channel is enabled.
- Run
docker-compose up --build
- You can now use the API to send a notification
curl --request POST \
--url http://localhost:8090/notifications \
--header 'Content-Type: application/json' \
--data '{
"channel": "log",
"message": "Some message."
}'
If you send via channel log (and it is enabled), you will be able to see the message inside the docker-compose
log
app_1 | received message: Some message.
- Create a
/test/config.yaml
by copying/test/config_example.yaml
cp test/config_example.yaml test/config.yaml
- Run the app as described above.
- Run
docker compose exec app go test ./... -v