Hooks and Filters – WP Webhook Framework
Control webhook behavior, payloads, and delivery using WordPress hooks and filters.
Actions
Section titled “Actions”wpwf_register_webhooks
Section titled “wpwf_register_webhooks”Register custom webhooks with the framework registry.
Parameters:
$registry(Webhook_Registry) - The registry instance
add_action( 'wpwf_register_webhooks', function ( Webhook_Registry $registry ): void { $registry->register( new My_Custom_Webhook() );} );See Custom Webhooks for detailed webhook creation.
wpwf_webhook_success
Section titled “wpwf_webhook_success”Fired when a webhook is successfully delivered.
Parameters:
$url(string) - The webhook URL$payload(array<string,mixed>) - The webhook payload$response(array|WP_Error) - The HTTP response$webhook(Webhook) - The webhook instance
add_action( 'wpwf_webhook_success', function ( string $url, array $payload, array $response, Webhook $webhook ): void { error_log( "Webhook '{$webhook->get_name()}' delivered: {$url}" );}, 10, 4 );wpwf_webhook_failed
Section titled “wpwf_webhook_failed”Fired when a webhook fails after all retries are exhausted, before blocking decision.
Parameters:
$url(string) - The webhook URL$response(array|WP_Error) - The response from wp_remote_post$failure_count(int) - Current consecutive failure count$max_failures(int) - Maximum failures before blocking$webhook(Webhook) - The webhook instance
add_action( 'wpwf_webhook_failed', function ( string $url, array $response, int $failure_count, int $max_failures, Webhook $webhook ): void { error_log( "Webhook '{$webhook->get_name()}' failed ({$failure_count}/{$max_failures}): {$url}" );}, 10, 5 );wpwf_webhook_blocked
Section titled “wpwf_webhook_blocked”Fired when a webhook URL is blocked due to reaching the consecutive failure threshold.
Parameters:
$url(string) - The webhook URL$response(array|WP_Error) - The response from wp_remote_post$max_failures(int) - Maximum failures threshold$webhook(Webhook) - The webhook instance
add_action( 'wpwf_webhook_blocked', function ( string $url, array $response, int $max_failures, Webhook $webhook ): void { // Send Slack notification wp_remote_post( 'https://hooks.slack.com/services/...', array( 'body' => wp_json_encode( array( 'text' => "Webhook blocked: {$url}" ) ), ) );}, 10, 4 );See Notifications for built-in notification handlers.
Filters
Section titled “Filters”wpwf_payload
Section titled “wpwf_payload”Filter webhook payloads before scheduling. Payloads contain event-time fields only; derived fields are added at delivery. Return false to prevent webhook scheduling.
Parameters:
$payload(array<string,mixed>) - The webhook payload data$entity(string) - The entity type (post, term, user, meta)$id(int|string) - The entity ID
Returns: array<string,mixed>|false
// Prevent delete webhooksadd_filter( 'wpwf_payload', function ( array $payload, string $entity, int|string $id ): array { if ( 'delete' === $payload['action'] ) { return false; } return $payload;}, 10, 3 );
// Enrich user webhooksadd_filter( 'wpwf_payload', function ( array $payload, string $entity, int|string $id ): array { if ( 'user' !== $entity ) { return $payload; } $user = get_userdata( (int) $id ); if ( $user ) { $payload['email'] = $user->user_email; } return $payload;}, 10, 3 );wpwf_request_body
Section titled “wpwf_request_body”Filter the webhook request body right before sending.
The framework already enriches rest_url at delivery time when possible. Use this filter to override or append additional fields.
Parameters:
$body(array<string,mixed>) - The full webhook body$action(string) - The action type$entity(string) - The entity type (post, term, user, meta)$id(int|string) - The entity ID$payload(array<string,mixed>) - The scheduled payload data$webhook(Webhook) - The webhook instance
Returns: array<string,mixed>
add_filter( 'wpwf_request_body', function ( array $body, string $action, string $entity, int|string $id ): array { if ( isset( $body['rest_url'] ) ) { return $body; }
if ( 'post' !== $entity ) { return $body; }
$post_type = get_post_type( (int) $id ); if ( false === $post_type || '' === $post_type ) { return $body; }
$post_type_object = get_post_type_object( $post_type ); if ( ! $post_type_object || true !== $post_type_object->show_in_rest ) { return $body; }
$rest_base = $post_type_object->rest_base ?: $post_type; $rest_namespace = $post_type_object->rest_namespace ?: 'wp/v2'; $body['rest_url'] = rest_url( "{$rest_namespace}/{$rest_base}/{$id}" );
return $body;}, 10, 4 );wpwf_url
Section titled “wpwf_url”Filter the webhook URL before scheduling.
Parameters:
$url(string) - The webhook URL$entity(string) - The entity type$id(int|string) - The entity ID
Returns: string
// Route by entity typeadd_filter( 'wpwf_url', function ( string $url, string $entity, int|string $id ): string { return match ( $entity ) { 'post' => 'https://api.example.com/webhooks/posts', 'user' => 'https://api.example.com/webhooks/users', default => $url, };}, 10, 3 );wpwf_headers
Section titled “wpwf_headers”Filter HTTP headers before sending webhook requests.
Parameters:
$headers(array<string,string>) - The HTTP headers$entity(string) - The entity type$id(int|string) - The entity ID$webhook(Webhook) - The webhook instance
Returns: array<string,string>
// Add authenticationadd_filter( 'wpwf_headers', function ( array $headers, string $entity, int|string $id, Webhook $webhook ): array { $token = get_option( 'api_token' ); if ( is_string( $token ) && '' !== $token ) { $headers['Authorization'] = 'Bearer ' . $token; } return $headers;}, 10, 4 );wpwf_excluded_meta
Section titled “wpwf_excluded_meta”Exclude specific meta keys from triggering webhooks.
Parameters:
$excluded(bool) - Whether the current key should be excluded$meta_key(string) - The current meta key$meta_type(string) - The meta type (post, term, user)$object_id(int) - The object ID
Returns: bool
Default excluded: _edit_lock, _edit_last, session_tokens, and any meta key starting with _
add_filter( 'wpwf_excluded_meta', function ( bool $excluded, string $meta_key, string $meta_type, int $object_id ): bool { if ( '_my_internal_field' === $meta_key ) { return true; }
return $excluded;}, 10, 4 );wpwf_blocked_notification_email
Section titled “wpwf_blocked_notification_email”Filter blocked notification email data. Return false to prevent email.
Parameters:
$email_data(array{recipient: string, subject: string, message: string, headers: array, url: string, error_message: string, response: mixed})$url(string) - The webhook URL that failed$response(mixed) - The response from wp_remote_post
Returns: array|false
// Custom recipient add_filter( 'wpwf_blocked_notification_email', function ( array $email_data, string $url, mixed $response ): array { $email_data['recipient'] = 'webhooks@example.com'; return $email_data;}, 10, 3 );
// Disable email notifications add_filter( 'wpwf_blocked_notification_email', fn() => false );wpwf_max_consecutive_failures
Section titled “wpwf_max_consecutive_failures”Filter the maximum consecutive failures threshold before URL blocking.
Parameters:
$max_failures(int) - The threshold$webhook_name(string) - The webhook name
Returns: int
add_filter( 'wpwf_max_consecutive_failures', function ( int $max_failures, string $webhook_name ): int { return 'critical_webhook' === $webhook_name ? 3 : $max_failures;}, 10, 2 );wpwf_timeout
Section titled “wpwf_timeout”Filter webhook request timeout in seconds.
Parameters:
$timeout(int) - The timeout (1-300)$webhook_name(string) - The webhook name
Returns: int
add_filter( 'wpwf_timeout', function ( int $timeout, string $webhook_name ): int { return 'bulk_sync_webhook' === $webhook_name ? 120 : $timeout;}, 10, 2 );wpwf_delivery_mode
Section titled “wpwf_delivery_mode”Filter the webhook delivery mode.
Parameters:
$delivery_mode(string) - The configured mode value (scheduledorimmediate)$webhook_name(string) - The webhook name
Returns: string
use juvo\WP_Webhook_Framework\Delivery_Mode;
add_filter( 'wpwf_delivery_mode', function ( string $delivery_mode, string $webhook_name ): string { if ( 'critical_webhook' !== $webhook_name ) { return $delivery_mode; }
return Delivery_Mode::IMMEDIATE->value;}, 10, 2 );wpwf_retry_base_time
Section titled “wpwf_retry_base_time”Filter the base time (seconds) for exponential backoff. Default: 60.
Parameters:
$base_time(int) - Base time in seconds$webhook_name(string) - The webhook name$retry_count(int) - Current retry attempt
Returns: int
wpwf_retry_delay
Section titled “wpwf_retry_delay”Filter the final calculated retry delay.
Parameters:
$delay(int) - Calculated delay in seconds$retry_count(int) - Current retry attempt$webhook_name(string) - The webhook name
Returns: int
// Static 5-minute delayadd_filter( 'wpwf_retry_delay', fn() => 300 );Payload Structure
Section titled “Payload Structure”Example payload (post):
{ "action": "create|update|delete", "entity": "post|term|user|meta", "id": 123, "post_type": "post"}Persisted fields (event-time):
- Meta:
meta_type,meta_key - Meta:
acf_field_key,acf_field_name(if ACF field)
Derived fields (when available at send time):
- Post:
post_type - Term:
taxonomy - User:
roles(array) rest_url
Filter Priority
Section titled “Filter Priority”Filters are applied in this order:
wpwf_delivery_mode- Resolve scheduled vs immediate modewpwf_url- Customize webhook URLwpwf_payload- Modify or prevent payloadwpwf_request_body- Modify final request body before sendwpwf_headers- Customize HTTP headerswpwf_excluded_meta- Filter meta keys (meta webhooks only)