Hinweis: Ja, ich habe Claude verwendet, um mir bei der Behebung dieses Problems zu helfen:
Discourse Core läuft mit dem Commit 5ee8e24 (2026-08-19). Der Patreon-Sync wird ohne Fehler abgeschlossen, synchronisiert aber null Benutzer:
Patreon sync complete: 63 pledges, 0 users synced
Die API-Antworten sind alle status=200, die Anfragen selbst sind also in Ordnung. Beim Nachverfolgen im Rails-Konsolentool ist die von dem Plugin erstellte Member-Anfrage korrekt und fordert auf der Member-Ressource tatsächlich die E-Mail-Adresse an:
fields[member]=full_name,last_charge_date,last_charge_status,currently_entitled_amount_cents,patron_status,email
Ruft man diesen Endpunkt direkt mit einem korrekt bereichsgesetzten Creator-Token auf (campaigns.members[email] gewährt), ist die E-Mail-Adresse im member-Objekt vorhanden, nicht aber im user-Objekt in included. Ein Abruf eines einzelnen Mitglieds bestätigt dies:
data.attributes.email => "patron@example.com" # vorhanden
included[].attributes.email => (nicht vorhanden) # user-Objekte enthalten nur full_name
Auf der Liste der Kampagnen-Mitglieder ist also member.attributes.email befüllt (bei 46 meiner 63 Mitglieder; die restlichen haben eingeschränkte Freigaben oder sind kostenlose Follower), während die included-Benutzereinträge überhaupt kein E-Mail-Feld haben.
Das Problem liegt in Patreon::ApiVersion::V2.extract (lib/api_version/v2.rb). Es baut die users-Map aus den included-Benutzerobjekten:
ruby
(member_data["included"] || []).each do |entry|
if entry["type"] == "user" && entry["attributes"]["email"].present?
users[entry["id"]] = entry["attributes"]["email"].downcase
end
end
Da diese Benutzerobjekte nie eine E-Mail-Adresse enthalten, bleibt die Map leer und jedes Mitglied scheitert beim E-Mail-Abgleich, daher 0 synchronisierte Benutzer.
Das Lesen der E-Mail-Adresse aus dem Member-Eintrag (indiziert über die Benutzer-ID, die bereits in member.relationships.user.data.id verfügbar ist und dieselbe patron_id wie bei den Pledges ist) hat es in meiner Installation behoben: Aus 0 wurden 46 users synced. Die Änderung, die ich vorgenommen habe:
diff
+ users[patron_id] = attrs["email"].downcase if attrs["email"].present?
pledges[patron_id] = attrs["currently_entitled_amount_cents"]
declines[patron_id] = attrs["last_charge_date"] if attrs["last_charge_status"] == "Declined"
end
-
- (member_data["included"] || []).each do |entry|
- if entry["type"] == "user" && entry["attributes"]["email"].present?
- users[entry["id"]] = entry["attributes"]["email"].downcase
- end
- end
Ich bin mir nicht sicher, ob das vollständige Entfernen der included-Schleife in jedem Fall die richtige Entscheidung ist — falls in einigen Setups die E-Mail-Adresse tatsächlich im Benutzerobjekt ankommt, sollte man sie vielleicht als Fallback beibehalten, statt sie zu ersetzen. Ich poste das beobachtete Verhalten und die minimale Änderung, die hier funktioniert hat, falls sie nützlich ist oder auf die richtige Lösung hindeutet.