Sync WooCommerce Memberships with Discourse groups

If you don’t need people to get removed from the group after some period of time, that is, they buy lifetime access to the group rather than temporary/periodic access to the group, then you can hook to woocommerce_payment_complete and add them to the group when the purchase is made. You can also hook to the SSO and update their groups at login.

1 Like

Thanks Jay!

Out of the gate we will not offer a lifetime access option for any of our membership groups. The nature of our “mentor marketplace” is that users will have a coach/mentor whose group they want to join. They may try it for a couple months and then cancel, and choose to sign up with a different mentor that might better suit their needs or expectations.

So we would need an active SYNC in order that when a member subscribes to a custom group in WP, then are automatically added to the respective group, in Discourse, and if anyone cancels their membership on WP, they would be automatically removed from the group, in Discourse.

If you want the latest version of this code you can find it in this repository: https://github.com/paviliondev/discourse-woocommerce.

This is used in production and continues to work as described.

Steps

  1. Install the code as a wordpress plugin.
  2. Update the group and plan ids.
  3. The sync will occur on each membership status change.

If someone could wikify the OP, I’ll update it with better instructions.

6 Likes

Hi! I bought the plugin Woocommerce memberships. It does everything you need. Then everything cleared for me. I posted here an instruction on a fully working integration that I set.

1 Like

So do you install the plugin in the OP first?

I’m like you in that I’m using Wordpress as the provider for our SSO… not Discourse (as noted in this topic title and OP)

I know the OP is about Syncing groups when Discourse is the SSO provider, but would it make sense to update the topic title and include instructions for doing this sync when Wordpress is the SSO provider?

@Ed_Bobkov provided some details on how to do the sync with an inverse of the SSO provider…

So just to clarify…

It would be really great and probably helpful to others In the long run if there were two different sets of instructions in the OP…

Sync WooCommerce Memberships with Discourse groups when:

  1. Discourse is the SSO Provider
  2. Wordpress is the SSO Provider
2 Likes

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