Patreon, похоже, не синхронизируется на нашем экземпляре

Мы размещены на хостинговом экземпляре discourse.group. У нас настроен плагин Patreon для обновления группы под названием «Patrons», и в неё должны включаться пользователи любого уровня поддержки. В настоящее время, несмотря на более чем 1000 активных патронов на Patreon, эта группа насчитывает лишь около 70 участников, что кажется слишком малым числом, особенно учитывая, что за исключением нескольких человек, получивших прямые приглашения, мы поддерживаем только вход через Patreon.

Согласно панели администратора плагина, синхронизация не выполнялась уже два дня, хотя документация указывает, что она должна запускаться каждые 6 часов. Последнее выполнение совпало с исключением нескольких пользователей из этой группы и ошибкой в логе (которая, судя по всему, является ответом от CloudFlare, а не от самого api.patreon.com). Подобные сбои происходят примерно каждые две недели.

Нажатие кнопки «Обновить данные Patreon и синхронизировать группы» в панели администратора плагина, по-видимому, не даёт никакого результата (у нас включено подробное логирование для плагина, но в логах ничего не появляется).

У меня лично нет доступа администратора к аккаунту Patreon, с которым мы связаны, но если я использую токен создателя, настроенный для плагина, для вызова конечных точек API (через curl), всё работает: я получаю корректные ответы, могу листать страницы с обязательствами и так далее. Ранее была тема, в которой предполагалось, что для этого экземпляра необходимо увеличить лимиты запросов; я сделал это на нашем экземпляре, но, похоже, это не дало эффекта.

Я изучил несколько соответствующих тем:

Однако, судя по всему, синхронизация не происходит ни вручную, ни по расписанию, или хотя бы не в соответствии с четырёхкратным ежедневным графиком, который предполагает документация. Поскольку мы не используем самостоятельный хостинг, я думаю, что достиг предела возможностей для самостоятельного анализа ситуации.

Привет,

Похоже, я выяснил причину этой проблемы, или хотя бы связанной с ней проблемы синхронизации с Patreon API v2.

У меня есть инстанс Discourse, использующий интеграцию с Patreon через API v2. Существующие пользователи 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

Затем я изучил ответ API, используемый в ApiVersion::V2.

Для первой страницы из 1000 участников:

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.

Это, вероятно, объясняет, почему синхронизация успешно получает все 1968 подписок, но сообщает 0 users synced.

Также это объясняет, почему существующие ассоциации Patreon/Discourse продолжают работать, в то время как новых участников невозможно сопоставить по электронной почте: у существующих пользователей patreon_id уже может быть сохранён в user_custom_fields, тогда как для нового участника необходимо установить связь между ID 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 в качестве резервного варианта?