Manage group membership in Discourse with WP Discourse SSO

As far as WordPress membership platforms go, the only one I’m aware of that has built in Discourse integration is Memberful:

More specific documentation of their Discourse integration: Integrate Discourse with Memberful

It costs a bit more than some other WP membership solutions (like Woo, Memberpress, etc.) all in since they take a % transaction fee as well. But it does seem pretty user friendly and full-featured.

Haven’t used it personally (we use Woo) but this is prob what I’d use if I wanted to not get into too much custom technical stuff. Though worth noting the above functions Simon has made to manage groups from WP > Discourse are relatively easy to use; if you wanted to use a different membership platform a professional WP dev could most likely get the basic integration set up in half a day or less.


The others are not too hard, but they do take a bit of cushion code.


Cushion code, eh?



Err, custom code? Might be required?

Nope. You said cushion code.


Sounds like the kind of thing a custom title would be perfect to immortalise :laughing:


That’s true. However, I am unable to decipher the code in your cushion.

does this start the sync automaticly ? Or do we need to do something ?

is there someone who is willing to help me with this ?

I believe it adjusts group membership whenever someone logs in again. Have you set it up?

Yes, i have everything set-up.

i have a connection between discourse and WP

i have Paid membership pro set-up and the woocommerce settings are good.
When i make a test order there is a membership.

Now the sync for the users won’t sync, and the memberships also

1 Like

does anyone nows if this still works ? Or canm anyone help me ?

The add_user_to_discourse_group and remove_user_from_discourse_group functions should still be working correctly. The easiest way to test this is to call the functions directly from the WP CLI shell.

The code that is required for syncing group memberships with Discourse is fairly complex. I wouldn’t attempt to write the code directly on a live WordPress site. You should setup a WordPress development site on your local computer for writing the code, or hire someone to do the work for you. Writing the code doesn’t require much knowledge of Discourse. Any WordPress developer who is familiar with how your membership plugin works should be able to handle it. If they get stuck, we can try to help them here.


i get this from discourse when i logged in at the webhooks request:

  "user": {
    "id": 744,
    "username": "webwinkeladviseur",
    "name": "Patrick Heijmans",
    "avatar_template": "/user_avatar/{size}/5511_2.png",
    "email": "",
    "last_posted_at": null,
    "last_seen_at": "2019-02-18T07:41:05.723Z",
    "created_at": "2019-02-18T07:25:29.746Z",
    "stats": [
        "action_type": 13,
        "count": 1
    "trust_level": 0,
    "moderator": false,
    "admin": false,
    "title": null,
    "badge_count": 0,
    "pending_count": 0,
    "profile_view_count": 0,
    "time_read": 0,
    "recent_time_read": 0,
    "primary_group_name": null,
    "primary_group_flair_url": null,
    "primary_group_flair_bg_color": null,
    "primary_group_flair_color": null,
    "staged": false,
    "second_factor_enabled": false,
    "post_count": 0,
    "locale": null,
    "muted_category_ids": [],
    "watched_tags": [],
    "watching_first_post_tags": [],
    "tracked_tags": [],
    "muted_tags": [],
    "tracked_category_ids": [],
    "watched_category_ids": [],
    "watched_first_post_category_ids": [],
    "private_messages_stats": {
      "all": 1,
      "mine": 0,
      "unread": 1
    "system_avatar_template": "/letter_avatar_proxy/v2/letter/w/7ea924/{size}.png",
    "muted_usernames": [],
    "mailing_list_posts_per_day": 49,
    "external_id": "143",
    "invited_by": null,
    "groups": [
        "id": 10,
        "automatic": true,
        "name": "vertrouwensniveau_0",
        "display_name": "vertrouwensniveau_0",
        "user_count": 154,
        "mentionable_level": 0,
        "messageable_level": 0,
        "visibility_level": 0,
        "automatic_membership_email_domains": null,
        "automatic_membership_retroactive": false,
        "primary_group": false,
        "title": null,
        "grant_trust_level": null,
        "incoming_email": null,
        "has_messages": false,
        "flair_url": null,
        "flair_bg_color": null,
        "flair_color": null,
        "bio_raw": null,
        "bio_cooked": null,
        "public_admission": false,
        "public_exit": false,
        "allow_membership_requests": false,
        "full_name": null,
        "default_notification_level": 3,
        "membership_request_template": null
    "featured_user_badge_ids": [],
    "user_option": {
      "user_id": 744,
      "email_always": false,
      "mailing_list_mode": false,
      "mailing_list_mode_frequency": 1,
      "email_digests": true,
      "email_private_messages": true,
      "email_direct": true,
      "external_links_in_new_tab": true,
      "dynamic_favicon": false,
      "enable_quoting": true,
      "disable_jump_reply": false,
      "digest_after_minutes": 10080,
      "automatically_unpin_topics": true,
      "auto_track_topics_after_msecs": 240000,
      "notification_level_when_replying": 2,
      "new_topic_duration_minutes": 2880,
      "email_previous_replies": 2,
      "email_in_reply_to": true,
      "like_notification_frequency": 1,
      "include_tl0_in_digests": false,
      "theme_ids": [
      "theme_key_seq": 0,
      "allow_private_messages": true,
      "homepage_id": null,
      "hide_profile_and_presence": false,
      "text_size": "normal",
      "text_size_seq": 0

do i need to do something here:

No, you do not need to enable any of the sso overrides settings.

The add_user_to_discourse_group and remove_user_from_discourse_group functions do not use webhooks. They need to be called from some code that you add to your WordPress site. Tha basic idea is that when your membership plugin adds a member, your code will hook into an action that is provided by the membership plugin and then call:

WPDiscourse\Utilities\Utilities::add_user_to_discourse_group( $wp_user_id, $group_names );

The user’s WordPress user ID should be substituted for $wp_user_id. $group_names should be the name of the Discourse group you want to add the user to. You can add a user to multiple groups by using a comma separated list of group names for $group_names. If you supply multiple group names, make sure there are no spaces between the commas.

The add_user_to_discourse_group and remove_user_from_discourse_group functions are static and namespaced. You need to be sure that you are calling the functions with their namespace.

1 Like

Our user don`t have an primary_group_name, title and some more fields. How we can fix it?

Are these users being added to the group with add_user_to_discourse_group? When added in this way, the users should have the group set as their primary group if you have enabled the ‘Automatically set as primary group’ checkbox on the group’s membership tab on Discourse. If you set the ‘Default title’ field for the group on Discourse, that title should be given to the user when they are added to the group.

1 Like

Yes we do that:

use WPDiscourse\Utilities\Utilities as DiscourseUtilities;

function dcpmp_get_level_for_id( $id ) {
    $levels_to_discourse_groups = array(
        1 => 'forum', 
		2 => 'premium'

    if ( empty( $levels_to_discourse_groups[ $id ] ) ) {

        return new WP_Error( 'pmpdc_group_not_set_error', 'A Discourse group has not been assigned to the level.' );

    return $levels_to_discourse_groups[ $id ];

function dcpmp_add_member_to_group( $member_order ) {
    if ( ! empty( $member_order->membership_id ) && ! empty( $member_order->user_id ) ) {
        $user_id = $member_order->user_id;
        $group_name = dcpmp_get_level_for_id( $member_order->membership_id );
        if ( is_wp_error( $group_name ) ) {
            return null;
        $result = DiscourseUtilities::add_user_to_discourse_group( $user_id, $group_name );

        if ( ! empty( $result->success ) ) {
            add_user_meta( $user_id, "dcpmp_group_{$group_name}", 1, true );

        return $result;

    return new WP_Error( 'dcpmp_order_not_set_error', 'There was an error with the PMP order.' );

function dcpmp_remove_member_from_group( $level_id, $user_id, $cancel_level ) {
    if ( ! empty( $cancel_level ) ) {
        $group_name = dcpmp_get_level_for_id( $cancel_level );
        if ( is_wp_error( $group_name ) ) {
            return null;

        $result = DiscourseUtilities::remove_user_from_discourse_group( $user_id, $group_name );
        if ( ! empty( $result->success ) ) {
            delete_user_meta( $user_id, "dcpmp_group_{$group_name}" );

        return $result;

    return null;

if ( class_exists( '\WPDiscourse\Discourse\Discourse' ) ) {
    add_action( 'pmpro_added_order', 'dcpmp_add_member_to_group' );
    add_action( 'pmpro_after_change_membership_level', 'dcpmp_remove_member_from_group', 10, 3 );

we have also enabled the ‘Automatically set as primary group’ checkbox

defatult title is: ★Forum lid★


i can’t figure out what is wrong…

membership for this user is set to premium

we know the connection is working…
but no groups added

what am i’m missing ?