This application manages Twitch widgets for streamers. It specifically supports the creation of "Charity Stream widgets," which include:
- Donation Bar Widget: Displays the progress of fundraising.
- Alert Widget: Shows alerts for donations and other stream interactions.
To run this application, you will need:
- PHP 8.3+
- MySQL
- Node.js (for frontend dependencies)
- Composer (for PHP dependencies)
First, clone the repository to your local machine or server:
git clone [repository-url]
cd twitch-widgetInstall PHP dependencies using Composer:
composer installInstall frontend dependencies using npm: require node >22.12
npm installCopy the example environment file and then edit it with your specific configurations:
cp .env.example .env
nano .envIn the .env file, ensure you update the following settings:
Database connection details API keys if applicable Any other environment-specific variables
To set up your database, execute the SQL migrations provided:
php migrations/run.phpnpm run buildOnce you have configured your environment, start your PHP server from public folder to run the application:
php -S localhost:8000Access the application through your web browser:
http://localhost:8000To secure your local development server with HTTPS, you can utilize ngrok. This tool provides a straightforward way to expose your localhost to the web while automatically equipping it with a valid SSL certificate. To start using ngrok and enable HTTPS, simply run the following command in your terminal:
ngrok http 8000This command will create a secure tunnel to your localhost server running on port 8000, allowing you to safely test your application's HTTPS functionality. Ensure that your application is running on port 8000 or adjust the port number in the command accordingly. Also update WEBSITE_DOMAIN from you env file
The project includes a PHPUnit test suite covering token management, widget rendering and dashboard display. Tests are fully isolated (SQLite in-memory, mocked dependencies) and require no running database or external API.
./vendor/bin/phpunit --testdoxtests/
├── bootstrap.php
└── Unit/
├── Services/
│ └── ApiWrapperTest.php # Token generation & refresh (OAuth)
├── Repositories/
│ └── AccessTokenRepositoryTest.php # Token storage & retrieval (SQLite)
└── Controllers/
├── AdminControllerTest.php # Dashboard display (admin / user roles)
└── WidgetControllerTest.php # Alert & donation widgets (render + JSON fetch)
| Suite | Tests | What is verified |
|---|---|---|
| Token generation | 6 | Valid token returned, generation when absent, regeneration when expired, API errors |
| Token refresh | 6 | Successful refresh, DB update, API errors, expired refresh token |
| Token storage | 10 | Insert, update, select by slug, null slug (global token), unknown org |
| Dashboard | 4 | Admin vs user template, flash messages forwarded, query isolation |
| Widget Alert | 8 | 200 render, 400/404/500 errors, JSON fetch, cache update |
| Widget Donation | 9 | 200 render, 400/404 errors, JSON fetch, cache update on amount change, multi-stream events |
Tests run automatically on every push via GitHub Actions, before deployment, on both environments:
| Workflow | Branch | Trigger |
|---|---|---|
php-sandbox.yml |
develop |
Push on develop |
php-prod.yml |
main |
Push on main |
A test failure blocks the pipeline immediately — the artifact is never built or deployed.
- Backend: PHP 8.3 with Slim Framework 4
- Frontend: Bootstrap 5.3, CountUp.js, Moment.js, Vite.js
- Database: MySQL
- Template Engine: Twig
- Dependency Injection: PHP-DI
- Cloud Storage: Azure Blob Storage
- Email Service: Mailchimp Transactional (Mandrill)
twitch-widget/
├── public/ # Web root directory
│ ├── dist/ # Compiled CSS and Javascript files
│ └── index.php # Application entry point
├── src/ # Application source code
│ ├── Assets/ # Assets folders (scss + js)
│ ├── Controllers/ # Request handlers
│ ├── Models/ # Data models
│ ├── Repositories/ # Data access layer
│ ├── Services/ # Business logic services
│ ├── Middlewares/ # Request/response middleware
│ └── views/ # Twig templates
├── migrations/ # Database migration files
└── vendor/ # Composer dependencies
└── node_modules/ # NPM dependencies
- HomeController: Handles public pages (home, password reset)
- LoginController: Manages authentication and OAuth flow
- AdminController: Admin panel functionality
- ApiController: API endpoints for external integrations
- WidgetController: Widget rendering and data endpoints
- User: User account management
- Stream: Stream configuration and data
- Event: Event management
- WidgetAlert/WidgetDonation: Widget-specific data models
- AccessToken/AuthorizationCode: OAuth token management
- UserRepository: User data operations
- StreamRepository: Stream data operations
- EventRepository: Event data operations
- WidgetRepository: Widget data operations
- FileManager: File upload/management via Azure Blob Storage
- ApiWrapper: External API integrations and OAuth handling
- AuthMiddleware: Session-based authentication
- AuthAdminMiddleware: Admin role verification
- AuthApiMiddleware: API authentication
The application provides two main widget types:
-
Alert Widget (
/widget-stream-alert/{id})- Displays real-time donation alerts
- Updates via AJAX polling
- Customizable styling and animations
-
Donation Bar Widget (
/widget-stream-donation/{id})- Shows fundraising progress
- Real-time goal tracking
- Animated progress bars
-
Card Widget (
/widget-stream-card/{id}//widget-event-card/{id})- Donation card with progress bar, amount and donor count
Les widgets se mettent à jour via un polling AJAX toutes les 10 secondes côté navigateur (appel aux endpoints /fetch).
Pour éviter de surcharger l'API HelloAsso, un cache serveur avec TTL est en place :
- Chaque widget stocke ses données en cache dans la colonne
cache_data(JSON) et un horodatagecache_updated_aten base de données. - Lors d'un appel
/fetch, le serveur vérifie d'abord si le cache est encore frais (âge < TTL). Si oui, les données en cache sont retournées directement sans aucun appel à l'API HelloAsso. - Si le cache est expiré, l'API HelloAsso est interrogée, puis le cache est mis à jour avec les nouvelles données et un nouveau timestamp.
Le TTL est configurable via la variable d'environnement WIDGET_CACHE_TTL (en secondes, défaut : 15 secondes).
Cela garantit qu'un seul appel API HelloAsso est effectué par widget et par période de TTL, quel que soit le nombre de visiteurs simultanés.
Database schema is managed through SQL migration files in the migrations/ directory:
00-init-db.sql: Initial database setup01-add-goal-widget-text.sql: Widget text configuration02-add-user-table.sql: User management03-update-widget-alert-box.sql: Alert widget improvements04-new-bar.sql: Donation bar widget05-manage-user-reset-pwd.sql: Password reset functionality06-manage-event.sql: Event management07-improve-user-rights.sql: User permissions
JavaScript and CSS files are organized in src/Assets/js/ and src/Assets/css/:
- admin.js: Admin panel functionality
- app.js: App module loader
- alert.js: Alert widget logic
- event.js: Event widget logic
- stream.js: Stream management
- main.scss: Global styles
Key environment variables include:
- Database connection (DBURL, DBPORT, DBNAME, DBUSER, DBPASSWORD)
- OAuth configuration (CLIENT_ID, CLIENT_SECRET, API_URL)
- Azure Blob Storage (BLOB_CONNECTION_STRING, BLOB_URL)
- Email service (MANDRILL_API)
- Application domain (WEBSITE_DOMAIN)
- Widget cache TTL in seconds (WIDGET_CACHE_TTL, default: 15)