Patreon이 우리 인스턴스에서 동기화되지 않는 것 같습니다

저희는 discourse.group의 호스팅 인스턴스를 사용하고 있습니다. Patreon 플러그인을 설정하여 'Patrons’라는 그룹을 업데이트하도록 해 두었는데, 모든 티어의 사용자는 이 그룹에 포함되어야 합니다. 현재 Patreon에서 활성 후원자가 1,000명이 넘음에도 불구하고 이 그룹에는 약 70명만 포함되어 있어, 특히 소수의 사용자에게만 직접 초대 링크를 제공했을 뿐 나머지는 모두 Patreon으로 로그인하도록 지원하고 있는 상황을 고려하면 규모가 너무 작아 보입니다.

관리자 패널의 플러그인 화면에 따르면 동기화가 마지막으로 실행된 지 2일이 지났는데, 이는 6시간마다 실행되어야 한다는 문서 내용과 상충됩니다. 마지막 실행 시점에 여러 사용자가 이 그룹에서 제외되는 문제가 발생했고, 로그에도 실패 기록이 남아 있습니다(해당 기록은 api.patreon.com 자체의 응답이 아니라 CloudFlare에서 반환된 것으로 보입니다). 이러한 유사한 실패는 약 2주 간격으로 반복되고 있습니다.

플러그인 관리자 패널의 “Update Patreon Data & Sync Groups” 버튼을 클릭해도 아무 반응이 없습니다(플러그인에 대해 상세 로깅을 활성화해 두었는데, 아무것도 기록되지 않습니다).

저는 개인적으로 연결된 Patreon 계정에 대한 관리자 권한이 없지만, 플러그인에 설정된 크리에이터 토큰을 API 엔드포인트에 대해(curl을 사용하여) 직접 사용해 보면 정상적으로 작동하며 유효한 응답을 받을 수 있고, 후원 목록을 페이지별로 조회하는 것도 가능합니다. 이전 스레드에서는 해당 인스턴스의 요청 제한을 늘려야 한다는 제안이 있었는데, 저는 저희 인스턴스에서 이를 수행했지만 효과가 없는 것으로 보입니다.

다음과 같은 관련 스레드들을 확인해 보았습니다:

하지만 제가 볼 때, 이는 수동으로든 정기적으로든 동기화가 일어나지 않고 있거나, 적어도 문서에 명시된 하루 4회(매 6시간마다) 정기 동기화가 이루어지지 않고 있는 것으로 보입니다. 저희는 자체 호스팅을 하지 않고 있으므로, 제가 직접 점검할 수 있는 범위의 한계에 도달한 것 같습니다.

안녕하세요,

이 문제의 원인을 찾았거나, 적어도 Patreon API v2 동기화 문제와 밀접하게 관련된 문제를 발견한 것 같습니다.

저는 Patreon 통합 기능을 API v2로 사용하는 Discourse 인스턴스를 운영 중입니다. 기존 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

이후 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.rb를 살펴보면, MEMBER_FIELDS는 명시적으로 email을 요청하지만, V2.extractincluded의 관련 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

제 API 응답에서 Patreon이 이메일을 반환하는 곳은 member 객체임에도 불구하고, member 객체의 entry["attributes"]["email"]를 사용하지 않는 것으로 보입니다.

이것이 동기화는 1,968개의 후원(pledges)을 모두 성공적으로 가져오지만 0 users synced라고 보고하는 이유를 설명하는 것 같습니다.

또한 기존 Patreon/Discourse 연결은 계속 작동하면서 새 멤버는 이메일로 매칭되지 못하는 이유도 설명합니다. 기존 사용자는 이미 user_custom_fieldspatreon_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 처리를 폴백(fallback)으로 유지하면서요?