Send Webhook when post-status is publish or trash

The sample code

function jon_save_post_webhook($post_id, $post)
{
    // Check to see if autosaving etc., if so ignore
    if ($post->post_status !== 'publish') {
        return;
    }
    if ($post->post_status !== 'trash') {
        return;
    }

/// rest of code

Will always return early because while $post->post_status can be “trash” or “publish”, it can never be both at the same time.

So if the post_status would be “publish”, it would return early on the second if- statement, because it’s not “draft”.

if it would be “draft”, it would return early on the first, because it’s not “publish”

What you need to do is check if the post_status is neither “publish” nor “draft”.

You could do something like this:

// If post_status is not draft and post_status is not publish, return early.
if ( $post->post_status !== 'draft' && $post->post_status !== 'publish' ) {
  return;
}

EDIT: So sorry. I misread “trash” for “draft” for some reason.

Following the suggestion by Pat J,
here’s my updated suggestion on how to handle it (although we’ll be using the trashed_post hook instead of trash_post, because trash_post is triggered before the post status is actually changed.

The two hooks we’ll use (save_post and trashed_post) are both passing the post_id, but trashed_post doesn’t pass a second argument (post), so in order to use the same callback for both, we’ll need to account for that.

Essentially, by setting $post = false in the function argument list, we’re making it optional. If the second argument is not passed, it will be assigned the fallback value of false.

function jon_save_post_webhook( $post_id, $post = false )
{
    // If $post is false, we're being called from trash_post, and must get the post object manually.
    if ( ! $post ) {
       $post = get_post( $post_id );
    }

    // Check to see if autosaving etc., if so ignore
    if ( $post->post_status !== 'publish' && $post->post_status !== 'trash' ) {
        return;
    }
/// rest of the function
add_action( 'save_post', 'jon_save_post_webhook', 10, 2 );
add_action( 'trashed_post', 'jon_save_post_webhook' );

Be aware that with this logic, your function is going to trigger when posts are trashed regardless of what status the post had before it was trashed.

If you only wish to trigger this webhook when posts that were published are trashed, you could use the old_status_to_new_status hook.

This hook passes $post as first parameter though, so in order to avoid losing the semantic value of your input parameters, for this example, I’ve added another function to serve as intermediary.

function jon_save_post_webhook( $post_id, $post )
{
    // Check to see if autosaving etc., if so ignore
    if ( $post->post_status !== 'publish' && $post->post_status !== 'trash' ) {
        return;
    }
/// rest of the function
}

function jon_trash_post_webhook( $post ) {
   jon_save_post_webhook( $post->ID, $post );
}
add_action( 'save_post', 'jon_save_post_webhook', 10, 2 );
add_action( 'publish_to_trash', 'jon_trash_post_webhook' );

Update #2:
Your new approach doesn’t need the trashed hook at all.
You can safely remove

function jon_trash_post_webhook($post)
{
    jon_save_post_webhook($post->ID, $post);
}
add_action('publish_to_trash', 'jon_trash_post_webhook');

and just fix the argument in jon_get_wordcount (you’re not passing the post ID, you’re passing the post- object) here:

/**
 * Get the post/page, remove any unnecessary tags and then perform the word count
 * 
 * @param \WP_Post $post
 * @return int
 */
function jon_get_wordcount( $post ) {
    $jon_wordcount = str_word_count( strip_tags( strip_shortcodes( $post->post_content ) ) );

    return $jon_wordcount;
}