# Private Full-Content RSS Feed for Members

> Gives each member a personal feed URL (shown on their profile) that includes members-only posts in full, so they can read in a feed reader or podcast app.

- Type: PHP
- Runs: Run everywhere
- Category: [Memberships](https://wpide.com/library/category/memberships/)
- Tags: rss, members, feeds
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/private-member-feed/

## Code

```php
$wpide_feed_key = function ( $user_id, $reset = false ) {
    $key = get_user_meta( $user_id, 'wpide_feed_key', true );

    if ( ! $key || $reset ) {
        $key = wp_generate_password( 24, false );
        update_user_meta( $user_id, 'wpide_feed_key', $key );
    }

    return $key;
};

// Treat a feed request with a valid key as that member, for this request only.
add_filter( 'determine_current_user', function ( $user_id ) {
    $uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';

    if ( $user_id || empty( $_GET['member_key'] ) || ( empty( $_GET['feed'] ) && false === strpos( $uri, '/feed' ) ) ) {
        return $user_id;
    }

    $key   = sanitize_text_field( wp_unslash( $_GET['member_key'] ) );
    $users = get_users( array( 'meta_key' => 'wpide_feed_key', 'meta_value' => $key, 'fields' => 'ID', 'number' => 1 ) );

    if ( $users && ! user_can( (int) $users[0], 'edit_posts' ) ) {
        add_action( 'template_redirect', function () {
            if ( ! is_feed() ) {
                wp_die( 'This key only works for feeds.', 'Forbidden', array( 'response' => 403 ) );
            }
        }, 0 );
        return (int) $users[0];
    }

    return $user_id;
}, 30 );

$wpide_feed_profile = function ( $user ) use ( $wpide_feed_key ) {
    if ( get_current_user_id() !== $user->ID || user_can( $user, 'edit_posts' ) ) {
        return;
    }

    $url = add_query_arg( 'member_key', $wpide_feed_key( $user->ID ), get_feed_link() );
    wp_nonce_field( 'wpide_feed_reset', 'wpide_feed_nonce' );
    printf(
        '<h2>Your private feed</h2><table class="form-table" role="presentation"><tr><th scope="row">Feed URL</th><td><input type="text" readonly class="large-text code" value="%s" onfocus="this.select()"><p><label><input type="checkbox" name="wpide_feed_reset" value="1"> Create a new URL (the old one stops working)</label></p></td></tr></table>',
        esc_attr( $url )
    );
};
add_action( 'show_user_profile', $wpide_feed_profile );

add_action( 'personal_options_update', function ( $user_id ) use ( $wpide_feed_key ) {
    if ( ! empty( $_POST['wpide_feed_reset'] ) && isset( $_POST['wpide_feed_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wpide_feed_nonce'] ), 'wpide_feed_reset' ) ) {
        $wpide_feed_key( $user_id, true );
    }
} );
```

## Notes

The key only unlocks feeds, never the rest of the site. Members can reset their key from their profile if the URL leaks.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Private Full-Content RSS Feed for Members" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
