# Le webhook de publication qui n’arrivait jamais : déboguer un rebuild manquant

> Un article publié un vendredi soir n'a jamais déclenché de rebuild : un plugin de cache interceptait silencieusement le webhook sortant. Méthode de diagnostic.

- Auteur : Clément Hadrot
- Publié le : 2025-07-30
- Mis à jour le : 2025-07-30
- Catégorie : Headless &amp; API
- URL : https://wpmoderne.dev.wordpress-developpement.fr/headless/webhook-publication-jamais-arrive-deboguer-rebuild-manquant/

## L’essentiel

- Un plugin de cache peut intercepter et servir une réponse mise en cache à la place d'exécuter réellement le hook de publication
- Un endpoint de test dédié permet de vérifier qu'un webhook part réellement de WordPress sans dépendre de la plateforme de build
- Journaliser chaque tentative d'envoi de webhook côté WordPress évite de devoir deviner après coup ce qui s'est passé

Le lundi matin, une community manager d'un site d'actualité locale a signalé un problème en apparence anodin : l'article publié le vendredi soir sur un événement du week-end n'apparaissait toujours pas sur le site public, alors qu'il s'affichait bien dans l'aperçu WordPress. Le site fonctionnait en génération statique via Next.js, avec un webhook censé déclencher un rebuild à chaque publication d'article.

Le réflexe naturel a été de vérifier le tableau de bord de la plateforme d'hébergement du front pour y trouver le déploiement correspondant. Il n'y en avait aucun depuis le jeudi précédent, alors que plusieurs articles avaient été publiés entre-temps. Le webhook, censé partir automatiquement à chaque publication, ne partait tout simplement plus depuis plusieurs jours, sans qu'aucune erreur ne soit visible où que ce soit.

## Symptôme : un silence total, sans erreur

Ce qui rendait ce cas particulièrement difficile à diagnostiquer, c'est l'absence de toute trace d'erreur exploitable. Le tableau de bord WordPress ne signalait rien d'anormal à la publication. La plateforme de build ne recevait tout simplement aucune requête, ce qui, de son point de vue, est indiscernable d'un webhook jamais configuré du tout. Impossible de savoir, sans creuser plus loin, si le problème venait de WordPress, du réseau, ou de la plateforme de destination.

## Diagnostic étape par étape

### Étape 1 : vérifier que le hook WordPress se déclenche bien

Un log temporaire a été ajouté directement dans la fonction accrochée à `transition_post_status`, pour confirmer que le code WordPress censé envoyer le webhook s'exécutait bien à chaque publication :

```
add_action('transition_post_status', function ($new, $old, $post) {
    if ($new === 'publish' && $old !== 'publish') {
        error_log('[webhook-rebuild] Déclenchement pour post ' . $post->ID);
        wp_remote_post(REBUILD_WEBHOOK_URL, [
            'body' => wp_json_encode(['post_id' => $post->ID]),
            'timeout' => 5,
        ]);
    }
}, 10, 3);
```

Les journaux du serveur WordPress confirmaient bien l'exécution de cette fonction à chaque publication. Le code partait donc bel et bien du bon endroit : le problème se situait entre l'appel `wp_remote_post` et la réception effective par la plateforme de build.

> L'essentiel à retenir : Un plugin de cache peut intercepter et servir une réponse mise en cache à la place d'exécuter réellement le hook de publication ; Un endpoint de test dédié permet de vérifier qu'un webhook part réellement de WordPress sans dépendre de la plateforme de build ; Journaliser chaque tentative d'envoi de webhook côté WordPress évite de devoir deviner après coup ce qui s'est passé

### Étape 2 : un endpoint de test indépendant de la plateforme de build

Pour isoler si le problème venait du réseau sortant de WordPress ou de la plateforme cible elle-même, un endpoint de test minimal a été déployé temporairement sur un service tiers gratuit (un simple relais qui journalise et affiche toute requête reçue), et l'URL du webhook a été temporairement dupliquée vers ce relais en plus de la cible réelle. Les requêtes arrivaient bien sur ce relais de test, dans un délai de moins d'une seconde après publication. Le webhook partait donc bien de WordPress, et le réseau sortant fonctionnait normalement : le problème résidait forcément du côté de la plateforme de build ou d'un intermédiaire entre les deux.

### Étape 3 : l'intermédiaire oublié

La vérification suivante portait sur les plugins actifs susceptibles d'intercepter des requêtes sortantes. Un plugin de cache de page, installé quelques semaines plus tôt pour réduire la charge sur un endpoint REST fréquemment appelé, s'est révélé être la cause réelle : ce plugin, mal configuré, mettait en cache non seulement les réponses des requêtes entrantes GET, mais interceptait également, à cause d'un filtre trop large sur `pre_http_request` ajouté par une extension complémentaire du même plugin, certaines requêtes sortantes générées par `wp_remote_post`, en leur substituant une réponse simulée en cache issue d'un test effectué lors de l'installation du plugin plusieurs semaines auparavant.

```
// Extrait retrouvé dans le plugin fautif
add_filter('pre_http_request', function ($preempt, $args, $url) {
    if (str_contains($url, 'rebuild-webhook')) {
        return $reponse_test_en_cache; // jamais invalidée depuis l'installation
    }
    return $preempt;
}, 10, 3);
```

Cette fonction, ajoutée à l'origine pour un test ponctuel par le prestataire ayant installé le plugin, n'avait jamais été retirée, et interceptait silencieusement toute requête vers une URL contenant la chaîne `rebuild-webhook`, en renvoyant une fausse réponse de succès sans jamais transmettre réellement la requête au réseau.

## Le correctif et la prévention

- Suppression immédiate du filtre fautif et désinstallation complète du plugin de cache concerné, remplacé par une solution de cache plus ciblée sur les seuls endpoints en lecture.
- Ajout d'une journalisation permanente, mais discrète, de chaque tentative d'envoi de webhook côté WordPress, avec le code de statut HTTP retourné, conservée pendant trente jours dans une table dédiée.
- Mise en place d'une vérification automatisée quotidienne, exécutée par une tâche planifiée WP-Cron, qui envoie un webhook de test vers un endpoint factice et alerte l'équipe si la réponse attendue n'est pas reçue dans les dix secondes.

```
wp cron event schedule verifier_webhook_rebuild now daily
```

> Un webhook silencieux qui ne génère aucune erreur est plus dangereux qu'un webhook qui échoue bruyamment : sans surveillance active, le décalage entre publication et mise en ligne peut durer des jours avant d'être repéré par quelqu'un.

## Prévention pour l'avenir

Ce cas rappelle qu'un plugin installé pour une raison précise, un test, une optimisation ponctuelle, laisse parfois un filtre actif bien après que sa raison d'être a disparu. La leçon retenue par l'équipe a été d'ajouter une revue systématique des filtres accrochés sur `pre_http_request` et `http_request_args` à chaque audit de sécurité et de performance, ces points d'extension étant rarement surveillés alors qu'ils peuvent silencieusement casser des intégrations critiques comme un webhook de rebuild.
