diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index f9b67867ef..52f7ed32ab 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -119,10 +119,7 @@ class ActivityPub::TagManager 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 8639a30a9f..c7069c7dac 100644 --- a/app/lib/status_reach_finder.rb +++ b/app/lib/status_reach_finder.rb @@ -21,6 +21,12 @@ class StatusReachFinder end end + def inboxes_for_limited + DeliveryFailureTracker.without_unavailable( + @status.mentioned_accounts.where.not(domain: nil).pluck(:inbox_url).compact.uniq + ) + end + private def reached_account_inboxes diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb index 34b6f6e32f..57ee1fbc0a 100644 --- a/app/workers/activitypub/distribution_worker.rb +++ b/app/workers/activitypub/distribution_worker.rb @@ -7,13 +7,23 @@ class ActivityPub::DistributionWorker < ActivityPub::RawDistributionWorker @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 @@ -22,6 +32,10 @@ class ActivityPub::DistributionWorker < ActivityPub::RawDistributionWorker @inboxes_for_misskey ||= status_reach_finder.inboxes_for_misskey 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 d8803f6b8a..df078dbf69 100644 --- a/spec/workers/activitypub/distribution_worker_spec.rb +++ b/spec/workers/activitypub/distribution_worker_spec.rb @@ -6,7 +6,7 @@ describe ActivityPub::DistributionWorker do 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 @@ -24,6 +24,18 @@ describe ActivityPub::DistributionWorker do 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) @@ -35,6 +47,20 @@ describe ActivityPub::DistributionWorker do 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') }