Getting post id from wp_insert_post_data function?

In the following, ’10’ is the priority that my_func gets called and ‘2’ is the number of arguments that my_func accepts. The latter is important, since the add_filter function defines the default as 1, but the wp_insert_post_data filter hook sends two arguments. If you don’t set this as 2 you won’t get the second argument.

add_filter("wp_insert_post_data", "my_func", 10, 2);

Now make your function…

function my_func($data, $postarr){
    //at this point, if it's not a new post, $postarr["ID"] should be set
    //do your stuff...
    return $data;
}

EDIT— based on your added code above

If you don’t need to modify the post’s $data before the post is saved then you’re using the wrong hook.

Use the save_post action hook instead. This gets called after the post is saved and all the taxonomies are saved. So you don’t have to worry about whether new tags have been added. It sends two arguments to your function: the ID of the post and the post itself as an object.

add_action("save_post", "my_save_post");
function my_save_post($post_id, $post){
    if ("publish" != $post->post_status) return;
    $tags = get_the_tags($post_id); //an array of tag objects
    //call your email func etc...
 }