diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index ef3bb8310d010a..a1817b96077374 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -119,10 +119,7 @@ def to(status) end.compact end when 'limited' - status.mentions.each_with_object([]) do |mention, result| - result << uri_for(mention.account) - result << followers_uri_for(mention.account) if mention.account.group? - end.compact + ['kmyblue:Limited'] # to avoid Fedibird personal visibility end end diff --git a/app/lib/status_reach_finder.rb b/app/lib/status_reach_finder.rb index 8f20b94675122d..62634f36c1b3d7 100644 --- a/app/lib/status_reach_finder.rb +++ b/app/lib/status_reach_finder.rb @@ -25,6 +25,12 @@ def inboxes_for_friend (reached_account_inboxes_for_friend + followers_inboxes_for_friend + friend_inboxes).uniq end + def inboxes_for_limited + DeliveryFailureTracker.without_unavailable( + @status.mentioned_accounts.where.not(domain: nil).pluck(:inbox_url).compact.uniq + ) + end + def all_inboxes (inboxes + inboxes_for_misskey + inboxes_for_friend).uniq end diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb index 12cb66aeb412f5..f8f80864a4afc4 100644 --- a/app/workers/activitypub/distribution_worker.rb +++ b/app/workers/activitypub/distribution_worker.rb @@ -7,13 +7,23 @@ def perform(status_id) @status = Status.find(status_id) @account = @status.account - distribute! + if @status.limited_visibility? + distribute_limited! + else + distribute! + end rescue ActiveRecord::RecordNotFound true end protected + def distribute_limited! + ActivityPub::DeliveryWorker.push_bulk(inboxes_for_limited, limit: 1_000) do |inbox_url| + [payload, @account.id, inbox_url, options] + end + end + def inboxes @inboxes ||= status_reach_finder.inboxes end @@ -26,6 +36,10 @@ def inboxes_for_friend @inboxes_for_friend ||= status_reach_finder.inboxes_for_friend end + def inboxes_for_limited + @inboxes_for_limited ||= status_reach_finder.inboxes_for_limited + end + def status_reach_finder @status_reach_finder ||= StatusReachFinder.new(@status) end diff --git a/spec/workers/activitypub/distribution_worker_spec.rb b/spec/workers/activitypub/distribution_worker_spec.rb index 2706967fcaea56..3b11207d8eb817 100644 --- a/spec/workers/activitypub/distribution_worker_spec.rb +++ b/spec/workers/activitypub/distribution_worker_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:status) { Fabricate(:status) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, shared_inbox_url: 'http://example.com', inbox_url: 'http://example.com/follower/inbox', domain: 'example.com') } describe '#perform' do before do @@ -25,6 +25,18 @@ end end + context 'with unlisted status' do + before do + status.update(visibility: :unlisted) + end + + it 'delivers to followers' do + expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com', anything]]) do + subject.perform(status.id) + end + end + end + context 'with private status' do before do status.update(visibility: :private) @@ -37,6 +49,20 @@ end end + context 'with limited status' do + before do + status.update(visibility: :limited) + status.capability_tokens.create! + status.mentions.create!(account: follower, silent: true) + end + + it 'delivers to followers' do + expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com/follower/inbox', anything]]) do + subject.perform(status.id) + end + end + end + context 'with direct status' do let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox', domain: 'foo.bar') }