Sync WooCommerce Memberships with Discourse groups

You are wrong. I use Discourse as a SSO provider. But that doesn’t change the sense.
You can find here topics with instructions when WP is SSO provider.
The main thing is that:

  1. You can manage your group memberships in Wordpress, subscriptions and terms by the plugin “WooCommerce Memberships” in all cases - when WP is a SSO provider OR Discourse is a SSO provider.
  2. To sync Discours members and groups with Wordpress you need in all cases use this plugin: GitHub - discourse/wp-discourse: WordPress plugin that lets you use Discourse as the community engine for a WordPress blog. In its’ settings you can choose the type of integration - WP or Discourse is a SSO provider.
    Also this plugin may be useful: https://github.com/paviliondev/discourse-woocommerce
  3. To do a batch syncing by cron you need to use this plugin: WP Crontrol – WordPress plugin | WordPress.org
    Detailed instructions you can find in this topic (above).
4 Likes

That link is now a 404. Did it move?

1 Like

The OP is now a wiki.

2 Likes

I’ve updated the OP with a link to the latest version of the code and instructions.

Ah I had forgot to make it public. Thanks.

@jord8on As Ed mentions, you should use the official Discourse Wordpress plugin if Wordpress is the SSO provider.

2 Likes

I am facing a problem regarding woo commerce integration with discourse.
If the user bought specific membership, they would automatically assign to the respective group in discourse.
It is working completely fine for most of the cases.
But sometimes, it is not automated. For example, 8 out of 10 users have been assigned to a specific discourse group on membership purchase, but the other two are not. So I want to make it automated for all users.
Any suggestion on how I can make it fully automated?

Hey :slight_smile:

Can you just confirm each of these things for me:

  1. You’re using Discourse as your Discourse Connect Provider (people sign in with the Discourse login form to sign into Wordpress)
  2. You’re using the WP Discourse plugin in Wordpress
  3. You’re using the code I posted in the first post of this topic in Wordpress

Is that right?

Your second option is right, I am using discourse plugin, And as i mention that my user are automatically assigned to specific group if they purchase specific membership.

All things are working fine . Just that after couple of months or more (occasionally) this issue happens that one of the random user not assigned to specific group after purchasing membership.

I want to get rid of that occasionally happened issue also

If only the second option is right, then these instructions won’t work for you unfortunately. All three need to be true. It sounds like you have a sync working though. Just so I understand you have

  1. The WP Discourse plugin installed; and

  2. Code to sync your WooCommerce groups (e.g. like this) ← Have you added this? Could you share what you’ve added?

2 Likes

No I think the plugin did all automation, I don’t remember of placing any kind of code to integrate

Maybe my plugin is 2.2.3 version, and it is out of date because the available update is 2.4.1.

Maybe it is happening due to this version. But I am a little curious that after doing an update, did it harm my current functionalities or not?

In order to sync groups between WooCommerce and Discourse you need to have some custom code. the WP Discourse plugin won’t do it by itself. You’ve most likely got an implementation of the functions described here.

You’ll need to first identify how the sync is happening (It’s not just the WP Discourse plugin) before I can help you further.

1 Like

I’ve added code to my WordPress - the one @Ed_Bobkov published:

<?php 

//wp+discourse
use WPDiscourse\Utilities\Utilities as DiscourseUtilities;

const MEMBERSHIP_PLAN_DISCOURSE_GROUP = [
“112” => “41”
];

//const ACTIVE_STATUSES = array( ‘wcm-active’ );
const ACTIVE_STATUSES = array( ‘wcm-active’, ‘wcm-free_trial’ );

function update_discourse_group_access( $user_id, $membership_plan_id, $membership_plan_name, $status ) {
$options = DiscourseUtilities::get_options();
$base_url = $options[‘url’];
$api_key = $options[‘api-key’];
$api_username = $options[‘publish-username’];

if ( empty( $base_url ) || empty( $api_key ) || empty( $api_username ) ) {
	return new \WP_Error( 'discourse_configuration_error', 'The WP Discourse plugin has not been properly configured.' );
}

$user_info         = get_userdata( $user_id );
$user_email        = $user_info->user_email;
$logger            = wc_get_logger();

$logger->info( sprintf( '%s membership of %s changed to %s', $user_email, $membership_plan_name, $status ) );

if ( in_array( $status, ACTIVE_STATUSES ) ) {
	$action = 'PUT';
} else {
	$action = 'DELETE';
}

$external_url = esc_url_raw( $base_url . "/groups/" . MEMBERSHIP_PLAN_DISCOURSE_GROUP[$membership_plan_id] . "/members" );

$logger->info( sprintf( 'Sending %s request to %s with %s', $action, $external_url, $user_email ) );

$response = wp_remote_request( $external_url,
	array(
		'method'  => $action,
		'headers' => array(
			'Api-Key'      => sanitize_key( $api_key ),
			'Api-Username' => sanitize_text_field( $api_username ),
		),
		'body'    => array( 'user_emails' => $user_email ),
	)
);

$logger->info( sprintf( 'Response from Discourse: %s %s',
	wp_remote_retrieve_response_code( $response ),
	wp_remote_retrieve_response_message( $response ) ) );

if ( ! DiscourseUtilities::validate( $response ) ) {

	return new \WP_Error( 'discourse_response_error', 'There has been an error in retrieving the user data from Discourse.' );
}
}

function handle_wc_membership_saved( $membership_plan, $args ) {
$logger = wc_get_logger();

$logger->info( sprintf( 'Running handle_wc_membership_saved %s, %s, %s', $args['user_id'], $args['user_membership_id'], $args['is_update'] ) );

$user_id            = $args['user_id'];

$membership         = wc_memberships_get_user_membership( $args['user_membership_id'] );

$membership_plan_id = $membership->plan->id;

if ( $membership && isset(MEMBERSHIP_PLAN_DISCOURSE_GROUP[$membership_plan_id])) {
	$membership_plan_name = $membership_plan->name;
	$status               = $membership->status;
	update_discourse_group_access( $user_id, $membership_plan_id, $membership_plan_name, $status );
}
}
add_action( ‘wc_memberships_user_membership_saved’, ‘handle_wc_membership_saved’, 10, 2 );

/* run_full_wc_membership_sync */
function full_wc_membership_sync() {
$allusers = get_users();
$logger = wc_get_logger();

$logger->info( sprintf('Running full_wc_membership_sync') );

foreach ( $allusers as $user ) {

   $user_id = $user->id;

   $membership = wc_memberships_get_user_membership($user_id);

   $membership_plan_id = $membership->plan->id;

   $logger->info( sprintf('Checking membership of %s', $user->user_login) );

   if ($membership  && isset(MEMBERSHIP_PLAN_DISCOURSE_GROUP[$membership_plan_id])) {
       
	  $membership_plan_name = $membership->plan->name;
      
	  $status = $membership->status;
      
	  $logger->info( sprintf('Updating group access of %s', $user->user_login) );

	  update_discourse_group_access($user_id, $membership_plan_id, $membership_plan_name, $status);

	  $logger->info( sprintf('Sleeping for 5 seconds') );
      
	  sleep(5);
   }
}
}

add_action(‘run_full_wc_membership_sync’, ‘full_wc_membership_sync’);

I’ve also added and ran via WP Crontrol run_full_wc_membership_sync

Sadly… WordPress user with active Membership (id 112) is not being added to discourse group (id 41). What I am missing here?

As this keeps confusing people, I’m going to publish a full “How to” with WooCommerce membership syncing (whether Wordpress or Discourse is the DiscourseConnect Provider) :slight_smile: . Please check in here at the beginning of next week if I haven’t already pinged you about it.

3 Likes

Thank you! Just tried to figure it out… I’ve even used a plugin GitHub - paviliondev/discourse-woocommerce but no luck either

1 Like

I’ve updated the discourse-woocommerce plugin to work when Wordpress is the DiscourseConnect Provider, and updated the instructions in the OP accordingly.

5 Likes
	''''''''''''''''''''''''''''''''''
            // add user to all applicable discourse groups
	if(wc_memberships_is_user_active_member($user_id,$membership_plan))
	{
		$group_name = $this->get_membership_discourse_groups($membership_plan);
		Utilities::add_user_to_discourse_group(
			$user_id,
			$group_name
		);
	}
            '''''''''''''''''''''''''''''''''''''''''''''''''

This is the code I am using to add membership users in discourse group. Where this function get_membership_discourse_groups() returns membership plan which users buy.

And my query is
" I am facing a problem regarding woo commerce integration with discourse.
If the user bought specific membership, they would automatically assign to the respective group in discourse.
It is working completely fine for most of the cases.
But sometimes, it is not automated. For example, 8 out of 10 users have been assigned to a specific discourse group on membership purchase, but the other two are not. So I want to make it automated for all users.
Any suggestion on how I can make it fully automated?"

Any idea what’s different about those users for whom it doesn’t work?

Hey Ansari,

So you’re not using the discourse-woocommerce plugin explained in the first post in this topic?

I’d suggest following the steps in the first post in the topic.

1 Like

No, as I said that it happens occasionally with random users, Issue happens maybe once in couple of months

Then it sounds like some kind of capacity issue, either WordPress isn’t doing its job or there’s some kind of network issue that’s keeping the updates from happening.

But if you’re not following the recommended course of action, then switching to that would probably solve the problem, as I believe that it updates the groups at every login.