Skip to content

Hooks and Filters – WP Webhook Framework

Control webhook behavior, payloads, and delivery using WordPress hooks and filters.

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.

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 );

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 );

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.

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 webhooks
add_filter( 'wpwf_payload', function ( array $payload, string $entity, int|string $id ): array {
if ( 'delete' === $payload['action'] ) {
return false;
}
return $payload;
}, 10, 3 );
// Enrich user webhooks
add_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 );

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 );

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 type
add_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 );

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 authentication
add_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 );

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 );

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 );

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 );

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 );

Filter the webhook delivery mode.

Parameters:

  • $delivery_mode (string) - The configured mode value (scheduled or immediate)
  • $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 );

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

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 delay
add_filter( 'wpwf_retry_delay', fn() => 300 );

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

Filters are applied in this order:

  1. wpwf_delivery_mode - Resolve scheduled vs immediate mode
  2. wpwf_url - Customize webhook URL
  3. wpwf_payload - Modify or prevent payload
  4. wpwf_request_body - Modify final request body before send
  5. wpwf_headers - Customize HTTP headers
  6. wpwf_excluded_meta - Filter meta keys (meta webhooks only)
  • PHP100%