Sync WooCommerce Memberships with Discourse groups

Если вам не нужно удалять пользователей из группы по истечении определённого периода, то есть они покупают пожизненный доступ к группе, а не временный/периодический, то вы можете использовать хук woocommerce_payment_complete и добавлять их в группу при совершении покупки. Также вы можете подключить SSO и обновлять их группы при входе в систему.

1 лайк

Спасибо, Джей!

С самого начала мы не будем предлагать опцию пожизненного доступа ни для одной из наших групп членства. Суть нашей «биржи менторов» заключается в том, что пользователи будут иметь тренера/ментора, в группу которого они хотят вступить. Они могут попробовать её в течение нескольких месяцев, а затем отменить подписку и выбрать другого ментора, который лучше подойдёт их потребностям или ожиданиям.

Поэтому нам потребуется активная синхронизация (SYNC), чтобы при подписке участника на пользовательскую группу в WordPress он автоматически добавлялся в соответствующую группу в Discourse, а если кто-либо отменит своё членство в WordPress, он автоматически исключался из этой группы в Discourse.

Если вы хотите получить последнюю версию этого кода, вы можете найти её в этом репозитории: GitHub - paviliondev/discourse-woocommerce · GitHub.

Этот код используется в рабочей среде и продолжает работать, как описано.

Шаги

  1. Установите код как плагин для WordPress.
  2. Обновите идентификаторы группы и тарифного плана.
  3. Синхронизация будет выполняться при каждом изменении статуса членства.

Если кто-нибудь сможет оформить исходный пост в формате вики, я обновлю его с более подробными инструкциями.

6 лайков

Привет! Я купил плагин WooCommerce Memberships. Он выполняет всё необходимое. После этого у меня всё наладилось. Я опубликовал здесь инструкцию по полностью рабочей интеграции, которую настроил.

1 лайк

Итак, вы сначала устанавливаете плагин в первом сообщении темы?

Я, как и вы, использую WordPress в качестве провайдера для нашего SSO, а не Discourse (как указано в заголовке этой темы и в первом сообщении).

Я понимаю, что исходный пост касается синхронизации групп, когда Discourse выступает провайдером SSO, но имеет ли смысл обновить заголовок темы и добавить инструкции по выполнению этой синхронизации, когда провайдером SSO является WordPress?

@Ed_Bobkov предоставил некоторые детали о том, как выполнить синхронизацию с обратной ролью провайдера SSO…

Итак, чтобы прояснить…

Было бы действительно здорово и, вероятно, полезно для других в долгосрочной перспективе, если бы в исходном посте были два разных набора инструкций…

Синхронизация членств WooCommerce с группами Discourse, когда:

  1. Discourse является провайдером SSO
  2. WordPress является провайдером SSO
2 лайка

Вы ошибаетесь. Я использую Discourse в качестве провайдера SSO. Но это не меняет сути.
Здесь вы можете найти темы с инструкциями, когда WordPress выступает в роли провайдера SSO.
Главное следующее:

  1. В любом случае — независимо от того, является ли WordPress провайдером SSO или Discourse — вы можете управлять членством в группах, подписками и условиями в WordPress с помощью плагина «WooCommerce Memberships».
  2. Для синхронизации участников и групп Discourse с WordPress в любом случае необходимо использовать этот плагин: GitHub - discourse/wp-discourse: WordPress plugin that lets you use Discourse as the community engine for a WordPress blog · GitHub. В его настройках можно выбрать тип интеграции — является ли WordPress или Discourse провайдером SSO.
    Также может быть полезен этот плагин: GitHub - paviliondev/discourse-woocommerce · GitHub
  3. Для пакетной синхронизации по расписанию cron необходимо использовать этот плагин: WP Crontrol – WordPress plugin | WordPress.org
    Подробные инструкции вы можете найти в этой теме (выше).
4 лайка

Эта ссылка теперь возвращает ошибку 404. Она переместилась?

1 лайк

Исходное сообщение теперь является вики-статьей.

2 лайка

Я обновил первое сообщение, добавив ссылку на последнюю версию кода и инструкции.

Ах, я забыл сделать её общедоступной. Спасибо.

@jord8on Как отмечает Эд, если Wordpress выступает в роли провайдера SSO, вам следует использовать официальный плагин Discourse для Wordpress.

2 лайка

У меня возникла проблема с интеграцией WooCommerce и Discourse.
Если пользователь покупает определённую подписку, он должен автоматически добавляться в соответствующую группу в Discourse.
В большинстве случаев это работает отлично.
Однако иногда автоматизация не срабатывает. Например, из 10 пользователей 8 были добавлены в нужную группу Discourse после покупки подписки, а остальные двое — нет. Мне нужно, чтобы процесс был полностью автоматизирован для всех пользователей.
Есть ли какие-либо предложения, как сделать это полностью автоматическим?

Привет :slight_smile:

Можешь просто подтвердить для меня каждый из этих пунктов:

  1. Вы используете Discourse в качестве провайдера Discourse Connect (пользователи входят в WordPress, используя форму входа Discourse).
  2. Вы используете плагин WP Discourse в WordPress.
  3. Вы используете код, который я опубликовал в первом сообщении этой темы, в WordPress.

Правильно ли я понимаю?

Ваш второй вариант верен. Я использую плагин для Discourse, и, как я уже упоминал, мои пользователи автоматически назначаются в конкретную группу при покупке соответствующего членства.

Всё работает исправно. Просто иногда, спустя несколько месяцев или больше, возникает проблема: один из случайных пользователей не получает назначение в нужную группу после покупки членства.

Я хочу полностью избавиться от этой периодически возникающей проблемы.

Если верен только второй вариант, то, к сожалению, эти инструкции вам не подойдут. Все три условия должны выполняться. Похоже, что у вас уже работает синхронизация. Просто чтобы я правильно понял, у вас есть:

  1. Установлен плагин WP Discourse; и

  2. Код для синхронизации ваших групп WooCommerce (например, как здесь) ← Вы добавили этот код? Можете поделиться тем, что вы добавили?

2 лайка

Нет, я думаю, что плагин выполнил всю автоматизацию, я не помню, чтобы вносил какой-либо код для интеграции.

Возможно, у меня версия плагина 2.2.3, и она устарела, так как доступно обновление до версии 2.4.1.

Возможно, проблема связана именно с этой версией. Но меня немного интересует, не навредило ли обновление текущему функционалу.

Для синхронизации групп между WooCommerce и Discourse требуется некоторый пользовательский код. Плагин WP Discourse не сделает это самостоятельно. Скорее всего, у вас уже есть реализация функций, описанных здесь:

Прежде чем я смогу помочь вам дальше, необходимо определить, как именно происходит синхронизация (это не только плагин WP Discourse).

1 лайк

Я добавил код в свой WordPress — тот, что опубликовал @Ed_Bobkov:

<?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', 'Плагин WP Discourse не настроен должным образом.' );
	}

	$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', 'Произошла ошибка при получении данных пользователя из 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');

Также я добавил и запустил через WP Crontrol действие run_full_wc_membership_sync.

К сожалению… Пользователь WordPress с активным членством (id 112) не добавляется в группу Discourse (id 41). Что я упускаю?

Поскольку это продолжает вызывать путаницу, я опубликую полную инструкцию «Как это сделать» по синхронизации членства в WooCommerce (независимо от того, является ли WordPress или Discourse провайдером DiscourseConnect) :slight_smile: . Пожалуйста, проверьте здесь в начале следующей недели, если я еще не связался с вами по этому поводу.

3 лайка

Спасибо! Я только что пытался разобраться… Я даже использовал плагин GitHub - paviliondev/discourse-woocommerce · GitHub, но безрезультатно.

1 лайк