Skip to main content

Looking Up a Subscriber

Integrations arrive at Benecaster from one of two directions. Some already know the WordPress user ID — a template, a shortcode, anything running inside a logged-in request. Others start from an email address, because their own data is a CRM export, a webhook payload, or a CSV.

Benecaster has public functions for both. Picking the wrong entry point usually works, and then costs you a query per row, or loses a distinction you needed.

Which function to reach for

You have You want Use
An email address Everything about them on this show benecaster_get_subscriber_data()
An email address Just the WordPress user ID benecaster_get_user_id_by_subscriber_email()
A user ID Their tier on a show benecaster_get_user_tier_for_show()
A user ID The name to show publicly benecaster_resolve_wall_display_name()
A show ID How many people are paying benecaster_count_paying_subscribers()
Nothing The site-wide paying total behind your plan limit benecaster_count_paying_subscribers_site_wide()
A show ID and an audience slug Who a broadcast would reach benecaster_find_audience_user_ids()
A show ID and a list of user IDs Them rendered as Member Thanks rows benecaster_get_member_thanks_rows()

Starting from an email address

benecaster_get_subscriber_data( string $email, int $show_id ) is one call in place of three. It returns the user ID, both display names, the tier, the token status, and the revocation reason.

foreach ( $crm_rows as $row ) {
    $data = benecaster_get_subscriber_data( $row['email'], $show_id );

    if ( null === $data ) {
        // Nobody on this site has that address.
        continue;
    }

    if ( 'none' === $data['token_status'] ) {
        // Has an account, has never had access to this show.
        continue;
    }

    my_crm_sync( $row['id'], $data['tier'], $data['token_status'] );
}

Four return states, not two

The single most common mistake here is treating “no access” as one state. benecaster_get_subscriber_data() can come back four different ways, and each calls for different handling:

Return value Meaning
null No WordPress user holds that email address at all — a stranger.
token_status: 'none' They have a WordPress account, but have never held a token for this show.
token_status: 'revoked' They had access to this show and no longer do.
token_status: 'active' They currently have access to this show.

Treating any two of these as the same loses real information: a stranger is not the same as an existing member of your site who just isn’t subscribed here, and a former subscriber is not the same as someone who was never subscribed.

There is no 'expired' value. token_status is only ever 'active', 'revoked', or 'none'. Code that checks for 'expired' is testing for a string the function never returns, and will silently fall through to its else branch every time.

Read revocation_reason when the status is 'revoked'. Revocation covers five different situations — a bridge cancellation, a licence grace timeout, a promotion grace expiry, a manual grant reaching its end date, and a podcaster deliberately removing somebody. Treating them all as “lapsed” means emailing a win-back campaign to somebody the podcaster removed by hand.

The reason is an empty string for active tokens, for 'none', and for revoked rows written before the reason was recorded.

When you only need the ID

benecaster_get_user_id_by_subscriber_email( string $email ) returns a user ID or 0. Use it as a cheap first step when most rows will not match, so you can bail before doing anything expensive:

$user_id = benecaster_get_user_id_by_subscriber_email( $row['email'] );
if ( ! $user_id ) {
    continue;
}

There is no show argument, deliberately. A WordPress user is site-wide; scoping to a show is what the tier and access functions are for.

0 means “no WordPress user has this email”, and nothing more. It is not a statement about tokens, tiers, or payment, and it does not rule out that the same person is a subscriber under a different address.

Do not reach for this one and then make three follow-up calls — that is benecaster_get_subscriber_data() with extra steps, and it cannot distinguish “no such user” from “user with no token for this show”.


Counting an audience

benecaster_get_subscriber_count( int $show_id ) returns the number of active tokens for a show.

It is an audience size, not a paying-subscriber count, despite the name. It counts paying subscribers, free-tier bridge members and followers alike, and on a show with a large free following the two numbers differ by a wide margin.

It also has no effect on licensing: nothing in core calls it, so neither the value nor the benecaster_analytics_subscriber_count filter can reach a plan limit, a threshold notice, or what the licence server is told. Any documentation you find saying otherwise is out of date.

For a paying count, use benecaster_count_paying_subscribers() instead, or benecaster_count_paying_subscribers_site_wide() across every show. The two functions disagreeing is the correct outcome, not a bug — they answer different questions. See Which subscriber count is the paying one, and do not query the tables directly, because the storage layout is internal and changes between releases.


See Also