WooCommerce Memberships と Discourse グループの同期

一定期間後にグループから自動的に削除する必要がない場合、つまり一時的・定期的なアクセスではなく、グループへの生涯アクセス権を購入する設定であれば、購入時に woocommerce_payment_complete にフックしてユーザーをグループに追加できます。また、SSO にフックしてログイン時にグループ情報を更新することも可能です。

「いいね!」 1

ジェイ、ありがとう!

当初、あらゆる会員グループに対して「終身アクセス」オプションは提供しません。当社の「メンターマーケットプレイス」の性質上、ユーザーは参加したいグループを持つコーチやメンターを選ぶことになります。数ヶ月間試してキャンセルし、自分のニーズや期待に合う別のメンターに登録し直すこともあり得ます。

そのため、WP でカスタムグループにメンバーがサブスクライブすると、Discourse の対応するグループに自動的に追加され、WP でメンバーシップをキャンセルした場合は Discourse のグループから自動的に削除されるように、アクティブな SYNC が必要となります。

このコードの最新バージョンが必要な場合は、以下のリポジトリでご確認ください: https://github.com/paviliondev/discourse-woocommerce。

これは本番環境で使用されており、説明通り正常に動作し続けています。

手順

  1. コードを WordPress プラグインとしてインストールします。
  2. グループ ID とプラン ID を更新します。
  3. メンバーシップステータスが変更されるたびに同期が行われます。

もし誰かが元の投稿(OP)をウィキ形式に編集してくだされば、より良い手順を追記します。

「いいね!」 6

こんにちは!WooCommerce Memberships プラグインを購入しました。必要な機能はすべて備わっています。その後、すべてが解決しました。私が設定した完全動作する統合の手順をここに投稿しました。

「いいね!」 1

つまり、まず OP にプラグインをインストールするのですか?

私はあなたと同じく、SSO のプロバイダーとして Discourse ではなく WordPress を使用しています(このトピックのタイトルと OP に記載されている通りです)。

OP は Discourse が SSO プロバイダーである場合のグループ同期について書かれていますが、SSO プロバイダーが WordPress である場合の同期手順をトピックタイトルに含めて更新するのは意味があるでしょうか?

@Ed_Bobkov さんは、SSO プロバイダーを逆転させた場合の同期方法について いくつかの詳細を提供しました

つまり、確認ですが…

OP に 2 つの異なる手順セットがあれば、長期的には非常に役立つし、他の人にもきっと役立つでしょう。

WooCommerce メンバーシップを Discourse グループと同期する方法(以下の場合):

  1. Discourse が SSO プロバイダーである場合
  2. WordPress が SSO プロバイダーである場合
「いいね!」 2

それは誤りです。私は Discourse を SSO プロバイダーとして使用しています。しかし、それは本質的な意味を変えません。
WordPress が SSO プロバイダーである場合の操作方法については、以下のトピックで確認できます。

重要なのは以下の点です:

  1. WordPress が SSO プロバイダーの場合でも、Discourse が SSO プロバイダーの場合でも、プラグイン「WooCommerce Memberships」を使用して、グループのメンバーシップ、サブスクリプション、利用規約を WordPress 上で管理できます。
  2. Discourse のメンバーとグループを WordPress と同期させるには、常に以下のプラグインを使用する必要があります:GitHub - discourse/wp-discourse: WordPress plugin that lets you use Discourse as the community engine for a WordPress blog · GitHub
    このプラグインの設定で、統合タイプ(WordPress が SSO プロバイダーか、Discourse が SSO プロバイダーか)を選択できます。
    また、以下のプラグインも役立ちます:GitHub - paviliondev/discourse-woocommerce · GitHub
  3. cron によるバッチ同期を行うには、以下のプラグインを使用する必要があります:WP Crontrol – WordPress plugin | WordPress.org
    詳しい手順については、このトピック(上記)をご覧ください。
「いいね!」 4

そのリンクは現在404です。移動しましたか?

「いいね!」 1

元投稿は現在ウィキ化されています。

「いいね!」 2

最新のコードと手順へのリンクを OP に更新しました。

ああ、公開設定を忘れていました。ありがとうございます。

@jord8on Ed が言及している通り、SSO プロバイダーが Wordpress の場合は、公式の Discourse Wordpress プラグインを使用してください。

「いいね!」 2

WooCommerceとDiscourseの連携に関して問題が発生しています。
特定のメンバーシップを購入した場合、ユーザーはDiscourseの該当グループに自動的に割り当てられるはずです。
ほとんどの場合、これは正常に機能しています。
しかし、時々自動化されません。例えば、10人のユーザーのうち8人はメンバーシップ購入時に特定のDiscourseグループに割り当てられましたが、残りの2人は割り当てられませんでした。そのため、すべてのユーザーに対して自動化したいと考えています。
これを完全に自動化する方法について、何か提案はありますか?

こんにちは :slight_smile:

これらのことをそれぞれ確認していただけますか?

  1. ディスコースをディスコースコネクトプロバイダーとして使用していますか?(ユーザーはディスコースログインフォームを使用してWordPressにサインインします)
  2. WordPressでWP Discourseプラグインを使用していますか?
  3. このトピックの最初の投稿で私が投稿したコードをWordPressで使用していますか?

これで合っていますか?

2番目のオプションで合っています。Discourseプラグインを使用しており、特定のメンバーシップを購入すると、ユーザーは特定のグループに自動的に割り当てられると述べました。

すべて正常に動作しています。ただ、数ヶ月に一度(時々)、特定のメンバーシップを購入しても、ランダムなユーザーが特定のグループに割り当てられないという問題が発生します。

この時々発生する問題も解消したいです。

残念ながら、2番目のオプションだけが正しい場合、これらの手順は機能しません。3つすべてが真実である必要があります。同期は機能しているようですね。理解のために、以下のことを確認してください。

  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', '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’);

また、WP Crontrol を介して run_full_wc_membership_sync を追加して実行しました。

残念ながら…アクティブなメンバーシップ(ID 112)を持つ WordPress ユーザーが Discourse グループ(ID 41)に追加されていません。何が足りないのでしょうか?

これが人々を混乱させ続けているので、WooCommerceメンバーシップの同期(WordPressまたはDiscourseのいずれかがDiscourseConnectプロバイダーであるかどうかにかかわらず)に関する完全な「ハウツー」を公開します :slight_smile: 。まだそれについてあなたに連絡していない場合は、来週初めにここを確認してください。

「いいね!」 3

ありがとうございます。調べてみました… プラグイン GitHub - paviliondev/discourse-woocommerce も試しましたが、うまくいきませんでした。

「いいね!」 1