Catalogue d'événements push — Plugins
Liste exhaustive des events que les plugins poussent vers StormeoOS, organisés par type.
Pour les webhooks émis par StormeoOS vers les souscripteurs externes (clients API), voir ../webhooks/public-api-webhooks.md.
Format d'un event
Tous les events suivent la structure :
{
"type": "<event_type>",
"siteUrl": "https://acme.fr",
"platform": "wordpress", // ou "prestashop"
"occurredAt": "2026-04-27T10:00:00.000Z",
"data": { ... } // payload spécifique au type
}Envoyés via POST /api/plugin/v2/security-event ou POST /api/plugin/sync-content selon la nature.
Headers requis : X-Stormeo-API-Key, X-Stormeo-Signature, X-Stormeo-Timestamp (HMAC obligatoire >= seuils).
Events de contenu
content.post.saved
Émis sur save_post WP / actionObjectCMSPageAddAfter PS.
{
"type": "content.post.saved",
"data": {
"postId": 42,
"postType": "post",
"title": "Nouveau billet",
"status": "publish",
"modifiedBy": 1,
"permalink": "https://acme.fr/blog/nouveau-billet"
}
}content.post.deleted
Émis sur delete_post WP.
{
"type": "content.post.deleted",
"data": { "postId": 42, "postType": "post" }
}content.media.added
Émis sur attachment_added WP / upload PS.
{
"type": "content.media.added",
"data": {
"attachmentId": 123,
"filename": "photo.jpg",
"mime": "image/jpeg",
"sizeBytes": 245760
}
}content.comment.posted
Émis sur comment_post WP.
{
"type": "content.comment.posted",
"data": {
"commentId": 99,
"postId": 42,
"approved": false,
"ipAddress": "1.2.3.4",
"userAgent": "..."
}
}Les emails commenters sont hashés SHA-256 avant push (RGPD).
Events e-commerce (WooCommerce / PrestaShop)
wc.order.created / ps.order.created
{
"type": "wc.order.created",
"data": {
"orderId": 1042,
"orderNumber": "WC-1042",
"total": "129.00",
"currency": "EUR",
"status": "pending",
"customerEmailHash": "sha256:..."
}
}wc.order.status_changed
{
"type": "wc.order.status_changed",
"data": {
"orderId": 1042,
"fromStatus": "pending",
"toStatus": "processing"
}
}wc.product.stock_changed
{
"type": "wc.product.stock_changed",
"data": {
"productId": 88,
"sku": "ACME-001",
"previousStock": 12,
"newStock": 11
}
}wc.product.created / wc.product.updated
{
"type": "wc.product.updated",
"data": {
"productId": 88,
"name": "T-shirt logo",
"price": "29.00",
"status": "publish"
}
}Events de sécurité
security.login.failed
Émis sur wp_login_failed WP / hook back-office PS.
{
"type": "security.login.failed",
"data": {
"userLogin": "admin",
"ipAddress": "1.2.3.4",
"userAgent": "...",
"reason": "incorrect_password"
}
}security.login.success
{
"type": "security.login.success",
"data": {
"userId": 1,
"userLogin": "admin",
"ipAddress": "1.2.3.4"
}
}security.user.created / security.user.role_changed
{
"type": "security.user.role_changed",
"data": {
"userId": 5,
"fromRole": "subscriber",
"toRole": "administrator",
"changedBy": 1
}
}security.file.modified
Émis quand un fichier core change de hash (différent du baseline).
{
"type": "security.file.modified",
"data": {
"path": "wp-includes/class-wp.php",
"previousHash": "sha256:abc...",
"currentHash": "sha256:def...",
"lastSeenAt": "2026-04-27T09:00:00.000Z"
}
}security.brute_force.detected
Émis si > 5 login_failed sur une IP en < 1 min (logique côté plugin).
{
"type": "security.brute_force.detected",
"data": {
"ipAddress": "1.2.3.4",
"attemptCount": 7,
"windowSec": 60
}
}Events métriques (push périodique cron)
metrics.disk_usage (/api/plugin/v2/disk-usage)
{
"type": "metrics.disk_usage",
"data": {
"uploadsBytes": 524288000,
"dbDumpBytes": 104857600,
"totalBytes": 1073741824,
"freeBytes": 5368709120
}
}metrics.file_integrity (/api/plugin/v2/file-integrity)
{
"type": "metrics.file_integrity",
"data": {
"scannedFiles": 1842,
"modifiedFiles": 3,
"modifiedList": [
{ "path": "wp-config.php", "hash": "sha256:..." }
]
}
}metrics.time_credit (/api/plugin/v2/time-credit)
Tracking des temps consommés par les commandes asynchrones (utile pour facturation).
{
"type": "metrics.time_credit",
"data": {
"commandId": 123,
"type": "wp.update_plugin",
"durationMs": 4200
}
}Events GDPR
gdpr.user.deletion_requested
Émis quand le mécanisme RGPD natif du CMS est déclenché.
{
"type": "gdpr.user.deletion_requested",
"data": {
"userId": 42,
"emailHash": "sha256:...",
"anonymizedFields": ["firstname", "lastname", "email", "phone"]
}
}Comportement côté StormeoOS
À réception, les events sont :
- Loggés dans
stormeo_sync_logs(audit) - Re-broadcast aux souscripteurs webhook public-api de l'agence si l'event mappe à un event public-api (rare, via mapping interne)
- Affichés dans l'UI agence (
SitePilot → Site → Live Feed) - Agrégés pour les dashboards (charts contenu, sécurité, etc.)
Idempotence et dédup
Le plugin doit envoyer un eventUuid (UUID v4) dans chaque event pour permettre la dédup côté serveur (en cas de retry réseau) :
{
"eventUuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "content.post.saved",
"data": { ... }
}Le serveur stocke les eventUuid reçus et ignore les doublons sur 24h.
Retry policy côté plugin
Si l'event fail (timeout, 5xx, signature rejetée) :
- Stocker dans une queue locale (option WP
stormeo_pending_events/ table PSps_stormeo_pending_events) - Retry exponential backoff : 1min, 5min, 30min, 2h, 12h
- Abandon après 5 tentatives → log local + alerte UI plugin
Pour les events critiques (security.*), recommandé de NE PAS abandonner — accumuler en queue jusqu'à reconnect.