-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathWebhookHandler.php
More file actions
121 lines (105 loc) · 4.29 KB
/
Copy pathWebhookHandler.php
File metadata and controls
121 lines (105 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
namespace WPGraphQL\Webhooks\Handlers;
use WPGraphQL\Webhooks\Entity\Webhook;
use WPGraphQL\Webhooks\Handlers\Interfaces\Handler;
/**
* Class WebhookHandler
*
* Sends the webhook to the configured URL when an event is triggered.
*/
class WebhookHandler implements Handler {
/**
* Handle the event payload for a specific webhook.
*
* @param Webhook $webhook The Webhook entity instance.
* @param array $payload The event payload data.
*
* @return void
*/
public function handle( Webhook $webhook, array $payload ): void {
// Log webhook dispatch initiation
$dispatch_timestamp = current_time( 'mysql' );
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "\n========== WEBHOOK DISPATCH ==========" );
error_log( "Timestamp: {$dispatch_timestamp}" );
error_log( "Webhook: {$webhook->name} (ID: {$webhook->id})" );
error_log( "Event: {$webhook->event}" );
error_log( "Target URL: {$webhook->url}" );
error_log( "Method: {$webhook->method}" );
}
$args = [
'headers' => $webhook->headers ?: [ 'Content-Type' => 'application/json' ],
'timeout' => apply_filters( 'graphql_webhooks_timeout', 15 ), // Configurable timeout with a default of 15 seconds
'blocking' => false,
'sslverify' => apply_filters( 'graphql_webhooks_sslverify', true, $webhook ),
'user-agent' => 'WPGraphQL-Webhooks/' . ( defined( 'WPGRAPHQL_WEBHOOKS_VERSION' ) ? WPGRAPHQL_WEBHOOKS_VERSION : '1.0.0' ),
];
// Apply payload filter
$payload = apply_filters( 'graphql_webhooks_payload', $payload, $webhook );
// Add webhook metadata to payload
$payload['_webhook_meta'] = [
'sent_at' => $dispatch_timestamp,
'webhook_id' => $webhook->id,
'webhook_name' => $webhook->name,
'event_type' => $webhook->event,
];
// Handle different HTTP methods
if ( strtoupper( $webhook->method ) === 'GET' ) {
$url = add_query_arg( $payload, $webhook->url );
$args['method'] = 'GET';
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Payload (GET query params): " . wp_json_encode( $payload ) );
}
} else {
$url = $webhook->url;
$args['method'] = strtoupper( $webhook->method );
$args['body'] = wp_json_encode( $payload );
// Ensure Content-Type header is set for non-GET requests
if ( empty( $args['headers']['Content-Type'] ) ) {
$args['headers']['Content-Type'] = 'application/json';
}
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Payload ({$args['method']} body): " . $args['body'] );
error_log( "Payload size: " . strlen( $args['body'] ) . " bytes" );
}
}
// Log headers
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Headers: " . wp_json_encode( $args['headers'] ) );
}
// For test mode or debugging, optionally use blocking mode
if ( apply_filters( 'graphql_webhooks_test_mode', false, $webhook ) ) {
$args['blocking'] = true;
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Test mode enabled - using blocking request" );
}
}
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "====================================\n" );
}
// Send the webhook
$start_time = microtime( true );
$response = wp_remote_request( $url, $args );
$end_time = microtime( true );
$duration = round( ( $end_time - $start_time ) * 1000, 2 );
// Log response if in blocking mode
if ( $args['blocking'] && defined( 'WP_DEBUG' ) && WP_DEBUG ) {
if ( is_wp_error( $response ) ) {
error_log( "\n========== WEBHOOK ERROR ==========" );
error_log( "❌ ERROR: " . $response->get_error_message() );
error_log( "Duration: {$duration}ms" );
error_log( "==================================\n" );
} else {
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
error_log( "\n========== WEBHOOK RESPONSE ==========" );
error_log( ( $response_code >= 200 && $response_code < 300 ? "✅" : "⚠️" ) . " Response Code: {$response_code}" );
error_log( "Duration: {$duration}ms" );
error_log( "Response Body: " . ( strlen( $response_body ) > 500 ? substr( $response_body, 0, 500 ) . '...' : $response_body ) );
error_log( "====================================\n" );
}
}
// Trigger action after webhook is sent
do_action( 'graphql_webhooks_sent', $webhook, $payload, $response );
}
}