I Webhook Trasformano WordPress da CMS Passivo a Hub di Automazione
WordPress fa qualcosa (un post viene pubblicato, un ordine completato, un form inviato). Poi? Nulla. L’informazione resta lì, dentro WordPress, finché qualcuno non la va a cercare.
I webhook cambiano questo. Ogni volta che succede un evento su WordPress, il sistema invia automaticamente una notifica HTTP a un URL esterno. Slack, Zapier, un microservizio, un altro WordPress, il tuo CRM. Qualsiasi cosa che possa ricevere una richiesta HTTP.
Risultato: WordPress smette di essere un’isola e diventa un nodo in un ecosistema di automazione.
Come Funzionano i Webhook su WordPress
WordPress ha un sistema di hook (azioni e filtri) potente. I webhook sono semplicemente hook che, invece di eseguire codice locale, inviano una richiesta HTTP a un endpoint esterno.
Il flusso:
- Un evento accade su WordPress (es:
publish_post) - L’hook attiva una funzione che prepara un payload JSON
- La funzione invia il payload via
wp_remote_post()a un URL configurato - Il servizio esterno riceve il payload e agisce
Esempio base: notifica Slack quando un post viene pubblicato
add_action('publish_post', function(int $post_id, WP_Post $post) {
$webhook_url = 'https://hooks.slack.com/services/T.../B.../xxx';
$payload = [
'text' => sprintf(
"📝 Nuovo articolo pubblicato: *%s*\n%s\nAutore: %s",
$post->post_title,
get_permalink($post_id),
get_the_author_meta('display_name', $post->post_author)
)
];
wp_remote_post($webhook_url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($payload),
'timeout' => 10
]);
}, 10, 2);
10 righe. Ogni post pubblicato appare su Slack in tempo reale. Nessun plugin.
5 Automazioni Webhook Pratiche per Agenzie
1. Alert sicurezza su Telegram
Quando un utente viene creato (potenziale backdoor) o un login admin avviene da un IP nuovo:
add_action('user_register', function(int $user_id) {
$user = get_userdata($user_id);
$telegram_token = TELEGRAM_BOT_TOKEN;
$chat_id = TELEGRAM_CHAT_ID;
$message = urlencode("🔔 Nuovo utente WordPress: {$user->user_login} ({$user->user_email})");
wp_remote_get(
"https://api.telegram.org/bot{$telegram_token}/sendMessage?chat_id={$chat_id}&text={$message}"
);
});
2. Sincronizzazione con CRM esterno
Quando un form di contatto viene compilato (Contact Form 7 o WPForms), invia i dati al CRM:
// Per Contact Form 7
add_action('wpcf7_mail_sent', function($contact_form) {
$submission = WPCF7_Submission::get_instance();
$data = $submission->get_posted_data();
wp_remote_post('https://api.tuocrm.com/leads', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . CRM_API_KEY
],
'body' => json_encode([
'name' => $data['your-name'] ?? '',
'email' => $data['your-email'] ?? '',
'message' => $data['your-message'] ?? '',
'source' => 'wordpress-contact-form',
'site' => home_url()
])
]);
});
3. Trigger AI analysis su nuovo contenuto
Quando un post viene pubblicato, lancia automaticamente un’analisi AI del contenuto:
add_action('publish_post', function(int $post_id) {
// Evita loop: non ri-analizzare se è un auto-save
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (get_post_meta($post_id, '_ai_analyzed', true)) return;
// Invia a un microservizio di analisi
wp_remote_post('https://api.tuoservizio.com/analyze', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'post_id' => $post_id,
'title' => get_the_title($post_id),
'url' => get_permalink($post_id),
'callback' => home_url('/wp-json/ai/v1/analysis-result')
]),
'timeout' => 5, // Non bloccare la pubblicazione
'blocking' => false // Fire and forget
]);
update_post_meta($post_id, '_ai_analyzed', true);
});
Il parametro 'blocking' => false è fondamentale: la richiesta parte ma WordPress non aspetta la risposta. L’utente non nota alcun rallentamento nella pubblicazione.
4. Webhook WooCommerce per logistica
WooCommerce ha webhook nativi (Impostazioni → Avanzate → Webhook). Ma puoi anche crearli via codice per più controllo:
add_action('woocommerce_order_status_completed', function(int $order_id) {
$order = wc_get_order($order_id);
$items = [];
foreach ($order->get_items() as $item) {
$items[] = [
'sku' => $item->get_product()->get_sku(),
'name' => $item->get_name(),
'quantity' => $item->get_quantity()
];
}
wp_remote_post('https://api.logistica.com/orders', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'order_id' => $order_id,
'customer' => $order->get_billing_email(),
'items' => $items,
'shipping' => $order->get_address('shipping'),
'total' => $order->get_total()
])
]);
});
5. GEO audit automatico post-deploy
Dopo ogni aggiornamento del sito, lancia un audit GEO Optimizer per verificare che il GEO score non sia sceso:
// Hook su upgrader_process_complete (dopo aggiornamento plugin/tema)
add_action('upgrader_process_complete', function() {
// Aspetta 60 secondi che il sito si stabilizzi
wp_schedule_single_event(time() + 60, 'run_geo_audit_post_deploy');
});
add_action('run_geo_audit_post_deploy', function() {
$site_url = home_url();
// Chiama un microservizio che esegue geo audit
$result = wp_remote_post('https://api.tuoservizio.com/geo-audit', [
'body' => json_encode(['url' => $site_url]),
'headers' => ['Content-Type' => 'application/json'],
'timeout' => 30
]);
if (!is_wp_error($result)) {
$data = json_decode(wp_remote_retrieve_body($result), true);
$score = $data['score'] ?? 0;
if ($score < 70) {
wp_mail(
get_option('admin_email'),
"⚠️ GEO Score sceso dopo deploy: {$score}/100",
"L'ultimo aggiornamento ha ridotto il GEO score di {$site_url}.\nScore attuale: {$score}/100\nVerifica robots.txt e schema."
);
}
}
});
Ricevere Webhook su WordPress
WordPress non è solo mittente. Può anche ricevere webhook da servizi esterni tramite la REST API:
add_action('rest_api_init', function() {
register_rest_route('webhooks/v1', '/incoming', [
'methods' => 'POST',
'callback' => function(WP_REST_Request $request) {
$payload = $request->get_json_params();
$source = $request->get_header('x-webhook-source');
// Log del webhook ricevuto
error_log("Webhook da {$source}: " . json_encode($payload));
// Verifica la firma (sicurezza!)
$signature = $request->get_header('x-webhook-signature');
$expected = hash_hmac('sha256', $request->get_body(), WEBHOOK_SECRET);
if (!hash_equals($expected, $signature)) {
return new WP_Error('invalid_signature', 'Firma non valida', ['status' => 401]);
}
// Processa in base al tipo
$event_type = $payload['event'] ?? 'unknown';
do_action("webhook_received_{$event_type}", $payload);
return ['status' => 'ok', 'received' => $event_type];
},
'permission_callback' => '__return_true' // Pubblico, ma verificato via firma
]);
});
La verifica della firma HMAC è obbligatoria. Senza, chiunque può inviare dati fasulli al tuo endpoint.
Plugin vs Codice Custom
| Approccio | Pro | Contro | Quando |
|---|---|---|---|
| WP Webhooks (plugin) | GUI, 100+ integrazioni, no-code | $149/anno pro, overhead | Se non sai programmare |
| AutomatorWP | Automazioni visive, gratis base | Limitato senza addon | Automazioni semplici |
| Codice custom | Zero overhead, massimo controllo | Richiede PHP | Agenzie con developer |
| Zapier/Make | 500+ integrazioni, no-code | $20-50/mese, dipendenza esterna | Integrazioni complesse multi-app |
Per un'agenzia con competenza PHP: codice custom. 20 righe di codice sostituiscono un plugin da $149/anno. Per chi non programma: WP Webhooks o Zapier.
FAQ
I webhook rallentano WordPress?
No, se usi 'blocking' => false in wp_remote_post(). La richiesta parte in background e WordPress continua senza aspettare la risposta. Se usi la modalità bloccante (default), il sito attende fino al timeout. Usa sempre non-bloccante per webhook non critici.
Come debuggo un webhook che non funziona?
Tre passi: 1) Logga il payload con error_log() prima dell'invio. 2) Usa webhook.site come URL di test per vedere esattamente cosa WordPress invia. 3) Controlla il response code con wp_remote_retrieve_response_code().
Posso usare i webhook con WordPress multisite?
Sì. Ogni sito nella rete ha i propri hook. Puoi configurare webhook diversi per ogni sito, oppure usare switch_to_blog() per gestirli centralmente dal sito principale.