It’s easy to create URLs with WP that find and map to content. Making URLs that trigger an action is a bit harder.
The main idea here is that I want a specific action to take place when a user clicks a link to a specific URL. Let’s say unsubscribe from a mailing list.
The unsubscribe link may look like this: http://yoursite.com/unsubscribe/21225/jdf94jjf9o45jrjsdja8kjm4
That link represents http://yoursite.com/unsubscribe/user_id/hash ( where hash is a value that has been stored in usermeta )
The rewrite rule might look like so:
add_rewrite_rule( 'unsubscribe/([0-9]+)/([^/]+)/?$', 'index.php?unsubscribe=1&uid=$matches[1]&hash=$matches[2]', 'top' );
After the rule has been added it’s necessary to flush all the rewrite_rules. Easiest way to do that is by saving permalinks. If the rule is added in a plugin, the activation hook is a good place, just before flushing all rules
flush_rewrite_rules();
We will also need to add query vars for the user_id and hash. This can be done using the query_vars filter:
add_filter ( 'query_vars', 'add_unsubscribe_query_vars' );
That hook provides you with an array of the existing query_vars. You just need to add your own and return the array:
function add_unsubscribe_query_var( $query_vars ) {
   $query_vars[] = 'uid';
   $query_vars[] = 'hash';
   $query_vars[] = 'unsubscribe';
   return $query_vars;
}
Now we need a way to intercept the data. Remember, this is not redirecting to an existing page. We can do this with the parse_request action hook:
add_action ( ‘parse_request’, ‘process_unsubscribe’ );
parse_request is the first action after the URL has been parsed. This happens before any headers are sent, before the main query is run, etc…
function process_unsubscribe_endpoint() {
   global $wp;
   // if the query var is not available, bail
   if ( ! isset ( $wp->query_vars['unsubscribe'] ) ) {
      return;
   }
   $opt_out_key = 'opt_out_of_email';
   // your query vars should be available in the $wp object
   $hash        = $wp->query_vars['hash'];
   $user        = get_userdata( $wp->query_vars['uid'] );
   $user_id = $user->ID;
   if ( false !== update_user_meta( $user_id, $opt_out_key, true ) ) {
      echo 'You have been unsubscribed.';
   } else {
      echo 'this means there was a problem updating the usermeta table.
   }
}
