Two things. Firstly, don’t load WordPress yourself. Instead of linking directly to your plugin file, use your WordPress home URL:
<a href="https://wordpress.stackexchange.com/questions/183197/<?php echo home_url("?workshop_id=X' ) ?>">Download iCal</a>
…and then intercept the request:
function wpse_183197_send_ical() {
if ( ! empty( $_GET['workshop_id'] ) && ! is_admin() ) {
// Your code
exit;
}
}
add_action( 'init', 'wpse_183197_send_ical' );
As for the code itself, since you’re only operating on one post, we can make it a lot leaner:
if ( ! $id = ( int ) $_GET['workshop_id'] )
return; // Invalid parameter
if ( ! $post = get_post( $id ) )
return; // Invalid post
if ( ! $title = get_field( 'workshop', $post->ID /* You can pass a post ID as a second arg to ACF get_field */ ) )
return; // No workshop
if ( $post->post_status !== 'publish' )
return; // Might want to protect access to drafts and the like
// Calendar headers
echo "SUMMARY:$title\n";