Reputation: 21
I'm attempting to write some functionality to more intelligently control the way WooCommerce handles failed webhooks. Currently, it just disables the webhook after 5 failed tries. I'm trying to make it so that it makes attempts in progressively larger time intervals until it either succeeds, or finally fails after the time interval reaches one day (86400).
The problem is, I can't find a way to catch a failed webhook. I'm trying to grab the response code and webhook ID from the woocommerce_webhook_delivery
hook as defined in WC_Webhook::deliver()
in the WC source. The problem is... even though my test WC webhooks are firing and being delivered fine, I can't ever detect that this method is running, even though all of the methods responsible for delivering webhooks refer back to it. I tried XDebug, sticking error_logs in there in the event that they were running in the background. Still no dice. Therefore, my idea of catching the woocommerce_webhook_delivery
isn't working, and I don't really know of another, easier way.
Here's what little code I have so far on this, if I can detect the response code I can handle the rest....
WC_WebhookBackoff {
protected $webhook;
protected $webhook_id;
public function __construct() {
add_action('woocommerce_webhook_delivery', [$this, 'catch_webhook_failure'], 1, 5);
}
public function hooks() {
}
public function catch_webhook_failure($http_args, $response, $duration, $arg, $id) {
$failed_hooks = get_option( '_failed_wc_webhooks', true ) ? json_decode(get_option( '_wds_failed_wc_webhooks', true ) ) : [];
error_log("This should be called.");
if ( 200 !== $response ) {
$failed_hooks = [];
$this->update_failed_hooks();
}
}
[...snip...]
And yeah, this is definitely being instantiated and the hook is definitely being registered.
For reference, here's the hook I'm looking at:
do_action( 'woocommerce_webhook_delivery', $http_args, $response, $duration, $arg, $this->get_id() );
Any help is greatly appreciated.
Upvotes: 0
Views: 2925
Reputation: 10151
I wanted to do the same thing essentially (capturing information about the response to my webhooks). Here's how I did it.
add_action('woocommerce_webhook_delivery', function($http_args, $response, $duration, $arg, $webhook_id) {
// do whatever you want to here
..
}, 1, 5);
Please note that I've set priority to 1 instead of the default 10, because with 10 it didn't work (I don't have a complete understanding of WordPress hook priorities yet). 5 at the end means the hook receives 5 parameters. This way my callback gets invoked.
I had a hook setup to fire when I update products. I updated my products description and my callback function was invoked. Please note, that updating the webhook (changing the endpoint or whatever) didn't invoke the callback function (not sure why, because it sends a ping to delivery address).
For testing, I also used this filter.
apply_filters('woocommerce_webhook_deliver_async', function() {
return false;
});
This essentially bypasses WooCommerce's action scheduler, the webhook's payload will be delivered immediately instead of sitting in a queue until it gets dispatched.
Upvotes: 3