0

I'm currently trying to work with webhooks without using any plugins, and I'd like to avoid them if possible.

The webhook should be triggered when a change is made to the Custom Post Type "event." So far, so good.

Now, I want to differentiate between:

  1. a brand-new post
  2. a modified already-existing post

And here's where it gets complicated!

When a new post is published, the function is triggered 3 times with the following statuses:

[10-Oct-2023 19:18:43 UTC] New Status: auto-draft [10-Oct-2023 19:18:43 UTC] Old Status: new [10-Oct-2023 19:19:04 UTC] New Status: publish [10-Oct-2023 19:19:04 UTC] Old Status: auto-draft [10-Oct-2023 19:19:06 UTC] New Status: publish [10-Oct-2023 19:19:06 UTC] Old Status: publish 

When an existing post is modified, the function is triggered twice:

[10-Oct-2023 19:23:04 UTC] New Status: publish [10-Oct-2023 19:23:04 UTC] Old Status: publish [10-Oct-2023 19:23:05 UTC] New Status: publish [10-Oct-2023 19:23:05 UTC] Old Status: publish 

I can certainly ensure in the receiving program that things are not processed twice. However, I simply cannot find a criterion to differentiate between a new post and an existing one.

At the moment I try to get it with the function "transition_post_status".

I also tried the function "save_post", but on save_post the update boolean is always 1. Regardless if I create a new post or modify an existing.

Happy for any hint!

functions.php:

// Add a custom REST API endpoint for the webhook function custom_webhook_endpoint() { register_rest_route('custom-webhooks/v1', '/trigger', array( 'methods' => 'POST', 'callback' => 'custom_webhook_callback', )); } // Callback function to handle incoming webhook requests function custom_webhook_callback($request) { // Process the webhook data and trigger your Python script or other actions // Example: $data = $request->get_json_params(); // Implement your logic here // Return a response if needed return rest_ensure_response(array('message' => 'Webhook received successfully')); } add_action('rest_api_init', 'custom_webhook_endpoint'); function trigger_webhook_on_new_event($new_status, $old_status, $post) { // Check if the post type is 'event' error_log('New Status: ' . $new_status); error_log('Old Status: ' . $old_status); if ($post->post_type === 'event') { // Check if the post is being published (new or update) if ($post->post_type === 'event' && $new_status === 'publish' && $old_status !== 'publish') { // This is a new post // Set up the URL for your Python web handler for new posts $webhook_base = 'http://localhost:5000/webhook/add'; } elseif ($new_status === 'publish') { // This is an update that changes the post_status to publish // Set up the URL for your Python web handler for updates that publish $webhook_base = 'http://localhost:5000/webhook/modify'; } // Get post meta data $all_post_meta = get_post_meta($post->ID); $start = isset($all_post_meta['start'][0]) ? $all_post_meta['start'][0] : ''; // Define the data you want to send in the POST request $data = array( 'id' => $post->ID, 'description' => $post->post_content, 'excerpt' => $post->post_excerpt, 'title' => $post->post_title, 'url' => get_permalink($post->ID), 'start' => $start, ); // Send a POST request to your Python web handler $response = wp_safe_remote_post($webhook_base, array( 'body' => json_encode($data), 'headers' => array('Content-Type' => 'application/json'), )); // Check for errors in the response, if needed if (is_wp_error($response)) { // Handle errors here error_log('Webhook error: ' . $response->get_error_message()); } } } add_action('transition_post_status', 'trigger_webhook_on_new_event', 10, 3); function trigger_webhook_on_new_event($new_status, $old_status, $post) { // Check if the post type is 'event' error_log('New Status: ' . $new_status); error_log('Old Status: ' . $old_status); if ($post->post_type === 'event') { // Check if the post is being published (new or update) if ($post->post_type === 'event' && $new_status === 'publish' && $old_status !== 'publish') { // This is a new post // Set up the URL for your Python web handler for new posts $webhook_base = 'http://localhost:5000/webhook/add'; } elseif ($new_status === 'publish') { // This is an update that changes the post_status to publish // Set up the URL for your Python web handler for updates that publish $webhook_base = 'http://localhost:5000/webhook/modify'; } // Get post meta data $all_post_meta = get_post_meta($post->ID); $start = isset($all_post_meta['start'][0]) ? $all_post_meta['start'][0] : ''; // Define the data you want to send in the POST request $data = array( 'id' => $post->ID, 'description' => $post->post_content, 'excerpt' => $post->post_excerpt, 'title' => $post->post_title, 'url' => get_permalink($post->ID), 'start' => $start, ); // Send a POST request to your Python web handler $response = wp_safe_remote_post($webhook_base, array( 'body' => json_encode($data), 'headers' => array('Content-Type' => 'application/json'), )); // Check for errors in the response, if needed if (is_wp_error($response)) { // Handle errors here error_log('Webhook error: ' . $response->get_error_message()); } } } add_action('transition_post_status', 'trigger_webhook_on_new_event', 10, 3); 

webhandler.py:

from flask import Flask, request app = Flask(__name__) # Import the google_maps class here from google_maps import google_maps # Create an instance of the google_maps class google_maps_instance = google_maps() # Create variables to track the last post ID for modify and add webhooks # WordPress call save post twice. I don't know why. last_modify_post_id = None last_add_post_id = None @app.route('/webhook/modify', methods=['POST']) def receive_webhook_modify(): global last_modify_post_id # Get the JSON data from the incoming webhook request data = request.json # Check if the received post ID is the same as the last one for modify if data['id'] == last_modify_post_id: print("Webhook already processed for modify with post ID:", last_modify_post_id) return "Webhook already processed" # If it's a new post ID, process the webhook for modify last_modify_post_id = data['id'] print("Received Webhook on modify:") print(data) # You can add your custom logic here to process the webhook data for modify return "Webhook received successfully" @app.route('/webhook/add', methods=['POST']) def receive_webhook_add(): global last_add_post_id # Get the JSON data from the incoming webhook request data = request.json # Check if the received post ID is the same as the last one for add if data['id'] == last_add_post_id: print("Webhook already processed for add with post ID:", last_add_post_id) return "Webhook already processed" # If it's a new post ID, process the webhook for add last_add_post_id = data['id'] print("Received Webhook on add:") print(data) # You can add your custom logic here to process the webhook data for add google_maps_instance.create_event(data) return "Webhook received successfully" if __name__ == '__main__': app.run(port=5000) 

1 Answer 1

0

I found a workaround, in this forum - This did the trick:

[https://wordpress.stackexchange.com/questions/225760/update-is-always-true-in-save-post][1]

It's still hit multiple times, but it's working.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.