Patreon لا يتزامن على نسختنا

مرحباً،

أعتقد أنني ربما وجدت سبب هذه المشكلة، أو على الأقل مشكلة متعلقة ارتباطاً وثيقاً بمزامنة Patreon API v2.

لديّ نسخة من Discourse تستخدم تكامل Patreon مع API v2. يستمر المستخدمون الحاليون في Patreon في الحصول على تعيينهم بشكل صحيح إلى مجموعة patrons، لكن لم يتم إضافة عضو مدفوع جديد إلى المجموعة، حتى بعد تشغيل تحديث بيانات Patreon يدوياً. اكتملت المزامنة بنجاح، وكان عنوان البريد الإلكتروني في Patreon مطابقاً تماماً لبريد المستخدم في Discourse.

مع تمكين patreon_verbose_log، تبلغ المزامنة:

Patreon sync: found 4 rewards/tiers across 1 campaigns
Patreon sync complete: 1968 pledges, 0 users synced

ثم فحصت استجابة API التي تستخدمها ApiVersion::V2.

بالنسبة لأول صفحة تضم 1,000 عضو:

Members in data: 1000
Included total: 1004
Included users: 1000
Keys for first included user: ["full_name"]
Included users with email: 0

ومع ذلك، تحتوي كائنات member نفسها على البريد الإلكتروني:

Members: 1000
Keys for first member:
["currently_entitled_amount_cents", "email", "full_name",
 "last_charge_date", "last_charge_status", "patron_status"]

Members with email: 928

بالنظر إلى plugins/discourse-patreon/lib/api_version/v2.rb، تطلب MEMBER_FIELDS صراحةً email، لكن V2.extract يملأ كائن users فقط من كائنات user المرتبطة في included:

(member_data["included"] || []).each do |entry|
  if entry["type"] == "user" && entry["attributes"]["email"].present?
    users[entry["id"]] = entry["attributes"]["email"].downcase
  end
end

لا يبدو أنه يستخدم entry["attributes"]["email"] من كائنات member، على الرغم من أن هذا هو المكان الذي تُعيد فيه Patreon البريد الإلكتروني في استجابة API لديّ.

يبدو أن هذا يفسر سبب نجاح المزامنة في استرداد جميع التزامات 1,968 بينما تبلغ عن 0 users synced.

كما يفسر سبب استمرار عمل الارتباطات الحالية بين Patreon/Discourse بينما لا يمكن مطابقة الأعضاء الجدد عبر البريد الإلكتروني: فقد يكون لدى المستخدمين الحاليين patreon_id مخزّناً بالفعل في user_custom_fields، في حين يحتاج العضو الجديد إلى إنشاء ارتباط معرّف Patreon ↔ البريد الإلكتروني.

هل من المنطقي أن يملأ V2.extract users مباشرةً أثناء معالجة كل عضو، على سبيل المثال:

patron_id = entry["relationships"]["user"]["data"]["id"]
attrs = entry["attributes"]

if attrs["email"].present?
  users[patron_id] = attrs["email"].downcase
end

مع الاحتفاظ بمعالجة included الحالية كحل احتياطي؟