diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c8c695c1..e51b89dd 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -77,12 +77,17 @@ module Api end # Genera un objeto a partir de la actividad. Si el objeto ya - # existe, actualiza su contenido. + # existe, actualiza su contenido. Si el objeto no viene + # incorporado, obtenemos el contenido más tarde. # # @return [ActivityPub::Object] def object @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, uri: object_uri).tap do |o| - o.content = original_object if object_embedded? + if object_embedded? + o.content = original_object + else + ActivityPub::FetchJob.perform_later(site: site, object: object) + end o.save! end end diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb new file mode 100644 index 00000000..526cdafb --- /dev/null +++ b/app/jobs/activity_pub/fetch_job.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Obtiene o actualiza el contenido de un objeto, usando las credenciales +# del sitio. +# +# XXX: Esto usa las credenciales del sitio para volver el objeto +# disponible para todo el CMS. Asumimos que el objeto devuelto es el +# mismo para todo el mundo y las credenciales solo son para +# autenticación. +class ActivityPub::FetchJob < ApplicationJob + def perform(site:, object:) + ActivityPub::Object.transaction do + response = site.social_inbox.dereferencer.get(uri: object.uri) + + object.update(content: FastJsonparser.parse(response.body)) if response.ok? + end + end +end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 78362a10..624ee571 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -2,6 +2,7 @@ require 'distributed_press/v1/social/client' require 'distributed_press/v1/social/hook' +require 'distributed_press/v1/social/dereferencer' # Gestiona la Social Inbox de un sitio class SocialInbox @@ -41,6 +42,11 @@ class SocialInbox ) end + # @return [DistributedPress::V1::Social::Dereferencer] + def dereferencer + @dereferencer ||= DistributedPress::V1::Social::Dereferencer.new(client: client) + end + # @return [DistributedPress::V1::Social::Hook] def hook @hook ||= DistributedPress::V1::Social::Hook.new(client: client, actor: actor)