Automattic\WooCommerce\Internal\PushNotifications\Dispatchers
WpcomNotificationDispatcher{} │ WC 10.7.0 Sends a notification to WPCOM via the Jetpack connection.
Called directly by the NotificationProcessor. Combines the notification payload with formatted push tokens and sends to the WPCOM push endpoint. Returns a result array indicating success/failure and an optional retry-after value.
No Hooks.
Usage
$WpcomNotificationDispatcher = new WpcomNotificationDispatcher();
// use class methods
Methods
public dispatch( Notification $notification, array $tokens )
private make_request( int $site_id, array $payload, array $tokens )
Changelog
WpcomNotificationDispatcher{} WpcomNotificationDispatcher{} code
WC 10.7.0
class WpcomNotificationDispatcher {
/**
* WPCOM API version.
*/
const WPCOM_API_VERSION = '2';
/**
* WPCOM endpoint path (appended after /sites/{id}/).
*/
const SEND_ENDPOINT = 'push-notifications';
/**
* HTTP request timeout in seconds.
*/
const REQUEST_TIMEOUT = 15;
/**
* Dispatches a notification with push tokens to WPCOM.
*
* @param Notification $notification The notification to send.
* @param PushToken[] $tokens The push tokens to send to.
* @return array{success: bool, retry_after: int|null}
*
* @since 10.7.0
*/
public function dispatch( Notification $notification, array $tokens ): array {
$site_id = class_exists( Jetpack_Options::class ) ? Jetpack_Options::get_option( 'id' ) : null;
if ( empty( $site_id ) ) {
wc_get_logger()->error(
'Cannot send push notifications: Jetpack site ID unavailable.',
array( 'source' => PushNotifications::FEATURE_NAME )
);
return array(
'success' => false,
'retry_after' => null,
);
}
$payload = $notification->to_payload();
if ( null === $payload ) {
wc_get_logger()->error(
sprintf(
'Cannot send push notification: resource no longer exists (type=%s, resource_id=%d).',
$notification->get_type(),
$notification->get_resource_id()
),
array( 'source' => PushNotifications::FEATURE_NAME )
);
return array(
'success' => false,
'retry_after' => null,
);
}
$response = $this->make_request( $site_id, $payload, $tokens );
if ( is_wp_error( $response ) ) {
wc_get_logger()->error(
sprintf(
'Push notification request failed: %s',
$response->get_error_message()
),
array( 'source' => PushNotifications::FEATURE_NAME )
);
return array(
'success' => false,
'retry_after' => null,
);
}
$status_code = (int) wp_remote_retrieve_response_code( $response );
if ( WP_Http::OK === $status_code ) {
return array(
'success' => true,
'retry_after' => null,
);
}
$retry_after = wp_remote_retrieve_header( $response, 'retry-after' );
wc_get_logger()->error(
sprintf(
'Push notification request returned HTTP %d.',
$status_code
),
array( 'source' => PushNotifications::FEATURE_NAME )
);
return array(
'success' => false,
'retry_after' => '' !== $retry_after ? (int) $retry_after : null,
);
}
/**
* Makes the WPCOM API request via the Jetpack connection.
*
* @param int $site_id The Jetpack site ID.
* @param array $payload The notification payload.
* @param PushToken[] $tokens The push tokens.
* @return array|WP_Error
*
* @since 10.7.0
*
* @phpstan-ignore return.unusedType (Jetpack stubs lack array return type.)
*/
private function make_request( int $site_id, array $payload, array $tokens ) {
$body = wp_json_encode(
array_merge(
$payload,
array(
'tokens' => array_map(
fn ( PushToken $token ) => $token->to_wpcom_format(),
$tokens
),
)
)
);
if ( false === $body ) {
return new WP_Error( 'json_encode_failed', 'Failed to encode push notification payload.' );
}
// @phpstan-ignore return.type
return Jetpack_Connection_Client::wpcom_json_api_request_as_blog(
sprintf( '/sites/%d/%s', $site_id, self::SEND_ENDPOINT ),
self::WPCOM_API_VERSION,
array(
'headers' => array( 'Content-Type' => 'application/json' ),
'method' => 'POST',
'timeout' => self::REQUEST_TIMEOUT,
),
$body,
'wpcom'
);
}
}