wp_schedule_single_event : voilà la fonction qui règle ce problème en une ligne, à condition de bien calculer son horodatage. Un artisan plaquiste avec qui je travaille éditait ses devis dans une extension maison, mais aucune relance n’était envoyée avant l’expiration. Résultat : des devis qui tombaient dans l’oubli du client, alors qu’une simple piqûre de rappel aurait suffi à déclencher la signature.
La solution ne nécessite ni service tiers ni file d’attente complexe : un événement cron unique, programmé au moment de l’enregistrement du devis, qui se déclenche exactement trois jours avant la date de validité renseignée. Voici comment je l’ai construit pour un devis stocké comme type de contenu personnalisé devis avec un champ de date d’expiration.
Calculer et programmer l’événement à l’enregistrement
Chaque devis possède un champ personnalisé date_expiration au format Y-m-d. Dès qu’il est renseigné ou modifié, on recalcule la date de rappel et on programme un événement unique avec wp_schedule_single_event, après avoir pris soin d’annuler tout événement existant pour éviter les doublons.
add_action( 'save_post_devis', function ( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
$expiration = get_post_meta( $post_id, 'date_expiration', true );
if ( ! $expiration ) {
return;
}
$timestamp_rappel = strtotime( $expiration . ' 09:00:00' ) - ( 3 * DAY_IN_SECONDS );
wp_clear_scheduled_hook( 'ch_rappel_expiration_devis', array( $post_id ) );
if ( $timestamp_rappel > time() ) {
wp_schedule_single_event( $timestamp_rappel, 'ch_rappel_expiration_devis', array( $post_id ) );
}
} );
Envoyer l’e-mail au moment du déclenchement
L’action programmée récupère le devis, vérifie qu’il n’a pas déjà été accepté entre-temps, puis envoie le message via wp_mail. Cette vérification est essentielle : sans elle, un client qui a déjà signé recevrait quand même une relance, ce qui donne une impression de désorganisation contraire à l’effet recherché.
add_action( 'ch_rappel_expiration_devis', function ( $post_id ) {
$statut = get_post_meta( $post_id, 'statut_devis', true );
if ( 'accepte' === $statut ) {
return;
}
$email_client = get_post_meta( $post_id, 'email_client', true );
if ( ! is_email( $email_client ) ) {
return;
}
$sujet = sprintf( 'Votre devis n°%d expire dans 3 jours', $post_id );
$corps = sprintf(
"Bonjour,\n\nVotre devis expire le %s. Contactez-nous si vous souhaitez le valider ou en discuter.\n\nCordialement.",
get_post_meta( $post_id, 'date_expiration', true )
);
wp_mail( $email_client, $sujet, $corps );
} );

Pourquoi un événement unique plutôt qu’une tâche récurrente
Une tâche récurrente vérifiant chaque jour tous les devis en cours fonctionnerait aussi, mais elle multiplie les requêtes et complique la logique de désactivation. Un événement unique par devis, programmé une fois pour toutes à la date exacte, est plus simple à raisonner : chaque devis porte sa propre échéance, indépendamment des autres.
Ce choix a une limite à connaître : si le site reste inactif au moment prévu, l’action ne se déclenche qu’à la prochaine visite, puisque le planificateur de WordPress repose sur les requêtes entrantes. Sur un site à trafic faible comme celui d’un artisan, j’ajoute un déclencheur externe pour garantir la ponctualité :
- Une tâche système appelant
wp-cron.phptoutes les quinze minutes, avecDISABLE_WP_CRONdéfini àtruedanswp-config.php. - Une vérification via WP-CLI, avec la commande
wp cron event list, pour confirmer que l’événement est bien enregistré après la sauvegarde d’un devis. - Un test manuel avec
wp cron event run ch_rappel_expiration_devisavant la mise en production, pour valider le contenu de l’e-mail.
Annuler proprement quand le devis est accepté
Dès que le statut passe à accepte, il est plus propre d’annuler directement l’événement plutôt que de compter uniquement sur la vérification au moment de l’envoi. Cela évite un événement fantôme qui traînerait dans la table des options.
add_action( 'ch_devis_accepte', function ( $post_id ) {
wp_clear_scheduled_hook( 'ch_rappel_expiration_devis', array( $post_id ) );
} );
Cette approche ne traite volontairement pas la relance téléphonique, qui reste un canal complémentaire géré par l’artisan lui-même : l’automatisation couvre l’e-mail, pas le suivi commercial humain qui doit continuer à exister en parallèle.
Une relance automatique n’a de valeur que si elle s’annule aussi automatiquement : un rappel envoyé après signature ruine la confiance plus vite qu’il ne la construit.
Notre verdict
Trois lignes de calcul d’horodatage et une action programmée suffisent à couvrir un cas d’usage qui, sans cela, dépend entièrement de la mémoire humaine. Le coût de mise en œuvre est minime comparé au nombre de devis qui, dans mon expérience, finissent par être signés simplement parce qu’un rappel est arrivé au bon moment plutôt que jamais.