Patreon 在我们的实例上似乎没有同步

我们使用的是 discourse.group 上的托管实例。我们配置了 Patreon 插件来更新一个名为“赞助者”(Patrons) 的群组,并且任何层级的赞助者都应该被包含在该群组中。目前,尽管 Patreon 上有超过 1000 名活跃赞助者,但该群组只有约 70 名成员,这似乎太少了,尤其是考虑到除了少数几个人是通过直接邀请获得支持外,我们只支持通过 Patreon 登录的人。

根据插件面板(位于管理员界面),同步已运行两天,这与文档中建议的每 6 小时运行一次的频率不符。上次运行恰逢几个人被移出该群组,并且日志中出现了一个错误(看起来像是来自 CloudFlare 而非 api.patreon.com 本身的响应)。我们大约每两周会看到类似的失败。

点击插件管理员面板中的“更新 Patreon 数据并同步群组”(Update Patreon Data & Sync Groups) 按钮似乎没有任何作用(我们在插件中启用了详细日志记录,但没有任何日志输出)。

我个人无法访问我们关联的 Patreon 账户的管理员权限,但如果我使用为该插件设置的创建者令牌 (creator token) 对 API 端点进行测试(使用 curl),它是有效的,我能够获得有效的响应、分页浏览认捐情况等。之前有一个帖子建议需要增加该实例的请求限制;我在我们的实例上增加了限制,但似乎没有效果。

我查看了一些相关的帖子:

但从我所看到的来看,同步似乎没有发生,无论是手动还是按计划,或者至少没有按文档暗示的每天 4 次的频率发生,而且由于我们不是自托管,我认为我能检查的范围已经到头了。

你好,

我想我可能找到了这个问题(或者至少是一个密切相关的 Patreon API v2 同步问题)的原因。

我运行着一个使用 Patreon 集成(API v2)的 Discourse 实例。现有的 Patreon 用户仍然被正确分配到 patrons 组,但一位新的付费成员没有被添加到该组中,即使我手动运行了 Update Patreon Data 也是如此。同步成功完成,并且 Patreon 中的电子邮件地址与用户的 Discourse 电子邮件地址完全匹配。

在启用 patreon_verbose_log 后,同步报告如下:

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

随后,我检查了 ApiVersion::V2 使用的 API 响应。

对于前 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.rbMEMBER_FIELDS 明确请求了 email,但 V2.extract 仅从 included 中的相关 user 对象填充 users 哈希:

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

它似乎没有使用 member 对象中的 entry["attributes"]["email"],尽管在我的 API 响应中,Patreon 正是在那里返回电子邮件地址的。

这似乎解释了为什么同步能够成功获取所有 1,968 个订阅(pledges),却报告 0 users synced

这也解释了为什么现有的 Patreon/Discourse 关联可以继续正常工作,而新成员却无法通过电子邮件进行匹配:现有用户可能已经在 user_custom_fields 中存储了他们的 patreon_id,而新成员则需要建立 Patreon ID 与电子邮件之间的关联。

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 处理作为回退方案?