Modular service for sending notifications via various communication channels in pure PHP 8.2+ without frameworks.
Notification Center is a production-ready service that accepts HTTP requests and sends notifications through different channels:
- π§ Email β via SMTP or mail() function
- π± SMS β via providers' REST API
- π¬ Telegram β via Bot API
- π Webhook β sending to arbitrary HTTP endpoints
- β Modular architecture with separation of concerns (SRP)
- β Task queue for asynchronous processing
- β Retry mechanism for all drivers (3 attempts)
- β Logging of all operations
- β Extensible driver system
- β
Full typing with
declare(strict_types=1) - β Docker environment for development and production
- β RESTful API
Request β Router β Controller β NotificationService β DriverManager β Drivers
Each driver implements the NotificationDriverInterface and can be easily extended.
project/
βββ public/ # Entry point
β βββ index.php
βββ src/
β βββ Controllers/ # Controllers
β βββ Services/ # Business logic
β βββ Drivers/ # Notification drivers
β βββ Core/ # Core (Router, Request, Response)
β βββ Models/ # Data models
β βββ Queue/ # Queue system
β βββ Database/ # Database operations
βββ config/ # Configuration files
βββ storage/ # Logs and files
βββ docker/ # Docker configuration
- PHP 8.2+
- Composer
- MySQL 5.7+ or 8.0+
- Docker and Docker Compose (optional)
- Clone the repository:
git clone <repository-url>
cd notification-service- Install dependencies:
composer install- Environment setup:
Create a .env file based on .env.example:
cp .env.example .envEdit .env and specify database connection parameters and driver settings.
- Create database:
# Create DB manually or use migrations
mysql -u root -p -e "CREATE DATABASE notification_service CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"- Run migrations:
composer migrateOr manually:
php -r "require 'vendor/autoload.php'; \NotificationService\Database\DB::migrate();"- Start built-in PHP server:
php -S localhost:8000 -t public- Start queue worker (in a separate terminal):
php src/Queue/Worker.phpOr via composer:
composer worker- Start all services:
docker-compose up -d- Run migrations:
docker-compose exec apache composer migrate- Check status:
docker-compose ps- View logs:
docker-compose logs -f worker
docker-compose logs -f apache- Stop:
docker-compose downThe service will be available at: http://localhost:8080
POST /send
{
"channel": "telegram",
"to": "123456789",
"message": "Hello, World!",
"subject": "Optional subject",
"payload": {
"parse_mode": "HTML"
}
}Response:
{
"status": "queued",
"request_id": 12
}GET /status/{id}
Response:
{
"id": 12,
"channel": "telegram",
"payload": {
"to": "123456789",
"message": "Hello, World!"
},
"status": "completed",
"created_at": "2024-01-15 10:30:00",
"updated_at": "2024-01-15 10:30:05"
}GET /logs/{id}
Response:
{
"request_id": 12,
"logs": [
{
"id": 1,
"driver": "telegram",
"success": true,
"response": {
"ok": true,
"result": {...}
},
"created_at": "2024-01-15 10:30:05"
}
]
}GET /health
Response:
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00+00:00",
"version": "1.0.0"
}{
"channel": "email",
"to": "[email protected]",
"subject": "Test Email",
"message": "This is a test message",
"payload": {
"html": "<p>HTML content</p>"
}
}{
"channel": "sms",
"to": "+1234567890",
"message": "Your verification code is 1234"
}{
"channel": "telegram",
"to": "123456789",
"message": "Hello from Notification Center!",
"payload": {
"parse_mode": "HTML"
}
}{
"channel": "webhook",
"payload": {
"url": "https://example.com/webhook",
"method": "POST",
"data": {
"event": "notification",
"message": "Test"
},
"headers": {
"X-Custom-Header": "value"
}
}
}Driver settings are located in config/drivers.php. Environment variables are configured in .env:
EMAIL_SMTP_HOSTβ SMTP serverEMAIL_SMTP_PORTβ SMTP portEMAIL_SMTP_USERβ SMTP userEMAIL_SMTP_PASSβ SMTP passwordSMS_API_URLβ API URL for SMSSMS_API_KEYβ API key for SMSTELEGRAM_BOT_TOKENβ Telegram bot tokenWEBHOOK_TIMEOUTβ Timeout for webhook requests
- Create a driver class implementing
NotificationDriverInterface:
<?php
declare(strict_types=1);
namespace NotificationService\Drivers;
class CustomDriver implements NotificationDriverInterface
{
public function send(array $payload): NotificationResult
{
// Your sending logic
return new NotificationResult(true, 'Success');
}
}- Add configuration to
config/drivers.php:
'custom' => [
'driver' => \NotificationService\Drivers\CustomDriver::class,
'config' => [
// Your settings
],
],- Done! Now you can use the
customchannel.
Tasks in the queue have the following structure:
idβ unique task identifierpayloadβ task data (JSON)statusβ status (pending, processing, completed, failed)attemptsβ number of attemptscreated_atβ creation time
Logs are saved in the storage/logs/ directory:
error-YYYY-MM-DD.logβ application errors- DB logs can be viewed via Docker:
docker-compose logs db
Examples of test requests via cURL:
# Send notification
curl -X POST http://localhost:8000/send \
-H "Content-Type: application/json" \
-d '{
"channel": "telegram",
"to": "123456789",
"message": "Test notification"
}'
# Check status
curl http://localhost:8000/status/1
# Get logs
curl http://localhost:8000/logs/1
# Health check
curl http://localhost:8000/health- All SQL queries use prepared statements
- Validation of all input data
- Exception handling at all levels
- Error logging without revealing sensitive information
This project was created for educational purposes.
Muhammad Ibrahimli
Suggestions and pull requests are welcome!
Version: 1.0.0
PHP: 8.2+
Status: Production Ready