A modern, full-featured SMS campaign management system built with Laravel 12 and React 19. WindSMS enables businesses to create, schedule, and manage SMS marketing campaigns with subscription-based billing and comprehensive analytics.
- Bulk SMS Campaigns: Send SMS to thousands of contacts simultaneously
- Smart Scheduling: Schedule campaigns with enforcement of sending hours (8am - 8pm WAT)
- Recurring Campaigns: Set up daily, weekly, monthly, or custom recurring campaigns
- Spintax Support: Create message variations with AI-powered spintax generation
- Multiple Recipient Types: Send to all contacts, specific tags, or manual phone number lists
- Campaign Analytics: Track sent, failed, and pending messages in real-time
- Contact Database: Store and organize contacts with metadata
- Tag System: Categorize subscribers using tags for targeted campaigns
- Bulk Import: Import contacts via CSV files
- Search & Filter: Quickly find and manage subscribers
- Flexible Plans: Multiple subscription tiers with different SMS allowances
- Paystack Integration: Secure payment processing with automatic webhooks
- Extra SMS Units: Purchase additional SMS credits as needed
- Usage Tracking: Real-time balance monitoring and transaction history
- Auto-renewal: Automatic subscription renewal support
- Custom Sender IDs: Request custom sender IDs for brand recognition
- Admin Approval System: Built-in approval workflow for sender ID requests
- Multiple Sender IDs: Use different sender IDs for different campaigns
- Two-Factor Authentication: Enhanced account security with 2FA
- Queue System: Background processing for large campaigns
- Email Verification: Secure user registration with email verification
- Real-time Logging: Monitor application logs with Laravel Pail
- Dark Mode: User preference-based theme switching
- Responsive Design: Mobile-friendly interface built with Tailwind CSS
- Laravel 12: Modern PHP framework
- Laravel Fortify: Authentication & security
- Laravel Wayfinder: Type-safe routing
- Laravel Soulbscription: Subscription management
- OpenAI PHP: AI-powered message generation
- League CSV: CSV import/export
- SQLite/MySQL: Database support
- React 19: Latest React with React Compiler
- Inertia.js: Modern monolithic SPA architecture
- TypeScript: Type-safe JavaScript
- Tailwind CSS 4: Utility-first CSS framework
- Radix UI: Accessible component primitives
- Lucide Icons: Beautiful icon library
- Recharts: Data visualization
- Vite 7: Lightning-fast build tool
- Laravel Pail: Real-time log monitoring
- Laravel Pint: Opinionated PHP code formatter
- ESLint: JavaScript/React linting
- Prettier: Code formatting
- Concurrently: Run multiple processes simultaneously
- PHP 8.2 or higher
- Composer
- Node.js 18 or higher
- NPM or Yarn
- SQLite or MySQL database
The easiest way to set up the project is using the automated setup script:
composer run setupThis will:
- Install PHP dependencies
- Create
.envfile from.env.example - Generate application key
- Run database migrations
- Install Node dependencies
- Build frontend assets
If you prefer manual setup:
-
Clone the repository
git clone <repository-url> cd windsms
-
Install PHP dependencies
composer install
-
Environment configuration
cp .env.example .env php artisan key:generate
-
Configure database
For SQLite (default):
touch database/database.sqlite
For MySQL, update
.env:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=windsms DB_USERNAME=root DB_PASSWORD=
-
Run migrations
php artisan migrate
-
Seed the database (optional)
php artisan db:seed
This creates a test user:
- Email: test@example.com
- Password: password
-
Install Node dependencies
npm install
-
Build frontend assets
npm run build
The application includes a convenient development script that runs all necessary services:
composer run devThis starts:
- Laravel server on http://127.0.0.1:8000
- Queue worker for background jobs
- Laravel Pail for real-time logs
- Vite dev server with HMR on http://localhost:5173
You can also run services individually:
# Laravel server
php artisan serve
# Queue worker (required for campaigns)
php artisan queue:work --tries=3
# Watch logs
php artisan pail
# Vite dev server
npm run dev# Build assets for production
npm run build
# Serve with production server
php artisan serveFor SSR support:
composer run dev:ssrConfigure your SMS provider in .env:
# Add your SMS provider credentials
# Example for SMS Live247
SMSLIVE247_API_TOKEN=your_token_here
SMSLIVE247_SENDER_ID=YourBrandPAYSTACK_PUBLIC_KEY=your_public_key
PAYSTACK_SECRET_KEY=your_secret_key
PAYSTACK_PAYMENT_URL=https://api.paystack.co
PAYSTACK_MERCHANT_EMAIL=your@email.comOPENAI_API_KEY=your_openai_api_keyMAIL_MAILER=smtp
MAIL_HOST=your_smtp_host
MAIL_PORT=587
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_FROM_ADDRESS=noreply@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"For production, use a more robust queue driver:
QUEUE_CONNECTION=redis
# or
QUEUE_CONNECTION=database- Creation: User creates campaign with recipients and message
- Validation: System checks SMS balance and subscription status
- Scheduling: Campaign scheduled for immediate or future dispatch
- Processing: Queue workers send SMS in batches
- Tracking: Real-time updates on delivery status
- Completion: Final stats recorded with success/failure counts
The system automatically calculates SMS units:
- Standard SMS: 160 characters = 1 unit
- Extended SMS: 161-306 chars = 2 units, 307-459 chars = 3 units, etc.
- Unicode (with special characters): 70 chars = 1 unit
The application uses feature-based subscriptions:
- Each plan includes SMS units
- Units are consumed when campaigns are sent
- Users can purchase extra units
- Expired subscriptions prevent campaign sending
# Run PHPUnit tests
composer run test
# Or directly
php artisan test# Format PHP code
./vendor/bin/pint# Lint and fix
npm run lint
# Format code
npm run format
# Check formatting
npm run format:checkwindsms/
βββ app/
β βββ Http/
β β βββ Controllers/ # Request handlers
β β βββ Middleware/ # HTTP middleware
β β βββ Requests/ # Form request validation
β βββ Jobs/ # Queue jobs
β βββ Models/ # Eloquent models
β βββ Services/ # Business logic
β βββ Shared/
β βββ Enums/ # Application enums
βββ database/
β βββ migrations/ # Database migrations
β βββ seeders/ # Database seeders
βββ resources/
β βββ css/ # Stylesheets
β βββ js/
β βββ components/ # React components
β βββ layouts/ # Page layouts
β βββ pages/ # Inertia pages
β βββ routes/ # Wayfinder routes
βββ routes/
β βββ web.php # Web routes
β βββ settings.php # Settings routes
βββ public/ # Public assets
The application includes scheduled commands for:
# Process recurring campaigns
php artisan campaigns:recurring
# Reprocess pending SMS
php artisan sms:reprocess-pendingAdd to your crontab:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
If you encounter process timeout errors with the queue worker:
# Use queue:work instead of queue:listen
php artisan queue:work --timeout=300 --tries=3Or increase the timeout in your configuration.
If you see errors about missing TypeScript route files, regenerate them:
npm run devThe Wayfinder plugin will automatically generate route definitions.
For SQLite, ensure the database file exists:
touch database/database.sqlite
chmod 664 database/database.sqlite- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open-sourced software licensed under the MIT license.
- Laravel - The PHP Framework
- React - JavaScript Library
- Inertia.js - Modern Monolith
- Tailwind CSS - CSS Framework
- Radix UI - UI Components
- Shadcn/ui - Component Design
For support, email dlktimothy@gmail.com or open an issue in the repository.
- Documentation - Coming soon
- API Documentation - Coming soon
- Changelog - Coming soon
Built with β€οΈ Timadey