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

نحن نستخدم نسخة مستضافة على discourse.group. لدينا المكون الإضافي Patreon مُعد لتحديث مجموعة تسمى Patrons (الداعمون)، ويجب أن يتم تضمين أي شخص من أي مستوى (tier) في هذه المجموعة. حاليًا، على الرغم من وجود أكثر من 1000 داعم نشط على Patreon، تضم هذه المجموعة حوالي 70 عضوًا فقط، وهو ما يبدو صغيرًا جدًا، خاصة بالنظر إلى أننا دعمنا الأشخاص الذين قاموا بتسجيل الدخول باستخدام Patreon باستثناء بضعة أشخاص مُنحوا دعوات مباشرة.

لقد مر يومان منذ آخر عملية مزامنة تم تشغيلها وفقًا للوحة المكون الإضافي في الإدارة، على عكس الوثائق التي تشير إلى أنه يجب تشغيلها كل 6 ساعات، وتزامن آخر تشغيل مع خروج عدة أشخاص من هذه المجموعة، وفشل في السجل (يبدو أنه استجابة من CloudFlare وليس api.patreon.com نفسه). نرى إخفاقات مماثلة على فترات زمنية تبلغ أسبوعين تقريبًا.

الضغط على زر “Update Patreon Data & Sync Groups” (تحديث بيانات Patreon ومزامنة المجموعات) في لوحة إدارة المكون الإضافي لا يفعل شيئًا (لدينا تسجيل مفصل مُفعّل للمكون الإضافي، ولا يتم تسجيل أي شيء).

أنا شخصيًا ليس لدي صلاحية المسؤول لحساب Patreon المرتبط بنا، ولكن إذا استخدمت رمز المُنشئ (creator token) المُعد للمكون الإضافي مقابل نقاط نهاية API (باستخدام curl)، فإنه يعمل ويمكنني الحصول على استجابات صالحة، وتصفح التعهدات (pledges)، وما إلى ذلك. كان هناك موضوع سابق يشير إلى ضرورة زيادة حدود الطلبات لتلك النسخة؛ وقد قمت بذلك على نسختنا ولكنه لم يكن له تأثير على ما يبدو.

لقد اطلعت على بعض المواضيع ذات الصلة:

ولكن مما أراه، يبدو الأمر وكأن المزامنة لا تحدث إما يدويًا أو بجدول زمني، أو على الأقل ليس بالجدول الزمني 4 مرات يوميًا الذي تشير إليه الوثائق، وبما أننا لا نستضيف ذاتيًا، أعتقد أنني وصلت إلى الحد الأقصى لما يمكنني فحصه بنفسي.

مرحباً،

أعتقد أنني ربما وجدت سبب هذه المشكلة، أو على الأقل مشكلة متعلقة ارتباطاً وثيقاً بمزامنة 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 الحالية كحل احتياطي؟