Multiple instances of the shortcode on the same page

I’d expect that the final

return do_shortcode($return); 

is the problem as it tries to process a shortcode named the entire content you are about to return and return a value. I expect that this is not what you are intending there.

Try changing that to:

return $return;

If that does not fix things, then I’d recommend starting out by adjusting your code a bit to echo information for each shortcode:

function fm_requestebook ($atts) {
    $atts = shortcode_atts(array(
        'cf7'           =>  null,
        'filename'      =>  null,
        'event'         =>  null,
        'testo'         =>  "Scarica eBook"
         ), $atts);

    echo "<p>Attributes Received:</p><pre>" . print_r($atts, true) . "</pre>";

    $contact_form = do_shortcode("[contact-form-7 id=".$atts['cf7']."]");
    $hf="<input type="hidden" name="_FM_ebook" value="" . $atts["filename"]. '" /></form>';
    $contact_form = str_replace("</form>", $hf, $contact_form);
    $return='<a onclick="ga(\'send\',\'event\', \'Download\', \'ebook\', \''.$atts["event"].'\');" class="fancybox" href="#ebook" target="_blank" rel="nofollow"><span class="red-button">'.$atts["testo"].'</span></a><div class="fancybox-hidden" style="display: none;"><div id="ebook" class="hentry">'.$contact_form.'</div></div>';

    echo "<p>About to return:</p><pre>" . htmlspecialchars( $return ) . "</pre>";
    $return = do_shortcode($return);
    echo "<p>After doing shortcode on return</p><pre>" . htmlspecialchars( $return ) . "</pre>";

    return $return;

}

That should let you see, for each shortcode:

  • What is being received
  • What the return value is before you apply do_shortcode()
  • What the return value is when you apply the final do_shortcode()

Of course, I’d recommend removing that final do_shortcode unless you really have a shortcode that is named as the entire content of the returned value.