Wordpress - add action only on post publish - not update

Like @milo pointed out in the comment, checking if the post meta exists is the easiest way to achieve what you want - like this:

add_action('publish_post', 'wpse120996_add_custom_field_automatically');
function wpse120996_add_custom_field_automatically($post_id) {
    global $wpdb;
    $votes_count = get_post_meta($post_id, 'votes_count', true);
    if( empty( $votes_count ) && ! wp_is_post_revision( $post_id ) ) {
        update_post_meta($post_id, 'votes_count', '0');
    }
}




→ On creation/publish not on updates

I'm keeping this, because it fits the matter of doing things on publish and not on update. But auto-draftpublish only works on first publishing a post and only if a post gets published directly. There might be the need to cover more cases, for example draftpublish or pendingpublish.

You could try:

//it's specific because you specify the hook like this {$old_status}_to_{$new_status}
add_action( 'auto-draft_to_publish', 'wpse120996_specific_post_status_transition' );
function wpse120996_specific_post_status_transition() { 
        //your code
}

instead of using new_to_publish.

→ Take a look at Post Status Transitions for additional information.

Or you could work with the generic hook transition_post_status like this:

//it's generic because you specify post statuses inside the function not via the hook
add_action( 'transition_post_status', 'wpse120996_generic_post_status_transition', 10, 3 );
function wpse120996_generic_post_status_transition( $new_status, $old_status, $post ) { 
    if ( $new_status == 'publish' && $old_status == 'auto-draft' ) {
        //your code
    }
}


Another neat method doing things on publish or to be exact first creation and not on updates would be going like shown below. I opted for using the save_post hook, but this could be done with the publish_post hook too.

add_action('save_post', 'wpse120996_on_creation_not_update');
function wpse120996_on_creation_not_update($post_id) {
    //get_post( $post_id ) == null checks if the post is not yet in the database
    if( get_post( $post_id ) == null ) {
        //your code
    }
}

This should work best:

add_action( 'publish_post' , 'my_func' , 10 , 2 );
function my_func( $ID , $post )
{
  if ( $post->post_date != $post->post_modified )
  {
    //THIS IS AN UPDATE
  }
  else
  {
    //POST JUST GOT PUBLISHED
  }
}