Change: #185 『スタンプをつけられた人』ではなく『スタンプをつけた人』のフォロワーにスタンプを転送 (#232)

* Change: #185 『スタンプをつけられた人』ではなく『スタンプをつけた人』のフォロワーにスタンプを転送

* Fix: 絵文字削除が届かない問題

* Test: 送る方にも同じテストを追加
This commit is contained in:
KMY(雪あすか) 2023-11-04 21:27:59 +09:00 committed by GitHub
parent a1d197dfef
commit 24909f9760
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 91 deletions

View file

@ -27,7 +27,7 @@ class Api::V1::Statuses::EmojiReactionsController < Api::BaseController
authorize @status, :show? if emoji_reaction.nil?
UnEmojiReactService.new.call(current_account.id, @status.id, emoji_reaction) if emoji_reaction.present?
UnEmojiReactService.new.call(current_account, @status, emoji_reaction) if emoji_reaction.present?
else
authorize @status, :show?
end

View file

@ -54,38 +54,11 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
Trends.statuses.register(@original_status)
write_stream(reaction)
if @original_status.account.local?
NotifyService.new.call(@original_status.account, :emoji_reaction, reaction)
forward_for_emoji_reaction
relay_for_emoji_reaction
relay_friend_for_emoji_reaction
end
NotifyService.new.call(@original_status.account, :emoji_reaction, reaction) if @original_status.account.local?
rescue Seahorse::Client::NetworkingError
nil
end
def forward_for_emoji_reaction
return if @json['signature'].blank?
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), @original_status.account.id, [@account.preferred_inbox_url])
end
def relay_for_emoji_reaction
return unless @json['signature'].present? && @original_status.public_visibility?
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
[Oj.dump(@json), @original_status.account.id, inbox_url]
end
end
def relay_friend_for_emoji_reaction
return unless @json['signature'].present? && @original_status.distributable_friend?
ActivityPub::DeliveryWorker.push_bulk(FriendDomain.distributables.pluck(:inbox_url)) do |inbox_url|
[Oj.dump(@json), @original_status.account.id, inbox_url]
end
end
def shortcode
return @shortcode if defined?(@shortcode)

View file

@ -147,12 +147,6 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
if emoji_reaction
emoji_reaction.destroy
write_stream(emoji_reaction)
if @original_status.account.local?
forward_for_undo_emoji_reaction
relay_for_undo_emoji_reaction
relay_friend_for_undo_emoji_reaction
end
end
else
undo_like_original
@ -176,28 +170,6 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
@render_emoji_reaction ||= Oj.dump(event: :emoji_reaction, payload: emoji_group.to_json)
end
def forward_for_undo_emoji_reaction
return if @json['signature'].blank?
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), @original_status.account.id, [@account.preferred_inbox_url])
end
def relay_for_undo_emoji_reaction
return unless @json['signature'].present? && @original_status.public_visibility?
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
[Oj.dump(@json), @original_status.account.id, inbox_url]
end
end
def relay_friend_for_undo_emoji_reaction
return unless @json['signature'].present? && @original_status.distributable_friend?
ActivityPub::DeliveryWorker.push_bulk(FriendDomain.distributables.pluck(:inbox_url)) do |inbox_url|
[Oj.dump(@json), @original_status.account.id, inbox_url]
end
end
def shortcode
return @shortcode if defined?(@shortcode)

View file

@ -150,7 +150,7 @@ class StatusReachFinder
end
def friend_inboxes
if @status.public_visibility? || @status.public_unlisted_visibility? || (@status.unlisted_visibility? && (@status.public_searchability? || @status.public_unlisted_searchability?))
if @status.distributable_friend?
DeliveryFailureTracker.without_unavailable(FriendDomain.distributables.where(delivery_local: true).where.not(domain: AccountDomainBlock.where(account: @status.account).select(:domain)).pluck(:inbox_url))
else
[]

View file

@ -46,29 +46,15 @@ class EmojiReactService < BaseService
def create_notification
status = @emoji_reaction.status
return unless status.account.local?
return unless status.account.user&.setting_enable_emoji_reaction
if status.account.local?
if status.account.user&.setting_enable_emoji_reaction
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', 'reaction') if status.account.user&.setting_emoji_reaction_streaming_notify_impl2
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', 'emoji_reaction')
end
elsif status.account.activitypub?
ActivityPub::DeliveryWorker.perform_async(payload, @emoji_reaction.account_id, status.account.inbox_url)
end
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', 'reaction') if status.account.user&.setting_emoji_reaction_streaming_notify_impl2
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', 'emoji_reaction')
end
def notify_to_followers
status = @emoji_reaction.status
return unless status.account.local?
ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url|
[payload, @status.account.id, inbox_url]
end
end
def inboxes
StatusReachFinder.new(@status).all_inboxes
ActivityPub::EmojiReactionDistributionWorker.perform_async(@emoji_reaction.id)
end
def write_stream!

View file

@ -4,23 +4,23 @@ class UnEmojiReactService < BaseService
include Redisable
include Payloadable
def call(account_id, status_id, emoji_reaction = nil)
@status = Status.find(status_id)
def call(account, status, emoji_reaction = nil)
@account = account
@status = status
if emoji_reaction
emoji_reaction.destroy!
@status.touch # rubocop:disable Rails/SkipsModelValidations
status.touch # rubocop:disable Rails/SkipsModelValidations
create_notification(emoji_reaction) if !@status.account.local? && @status.account.activitypub?
notify_to_followers(emoji_reaction) if @status.account.local?
notify_to_followers(emoji_reaction)
write_stream(emoji_reaction)
relay_for_undo_emoji_reaction!(emoji_reaction)
relay_friend_for_undo_emoji_reaction!(emoji_reaction)
else
account = Account.find(account_id)
bulk(account, @status)
bulk(account, status)
end
emoji_reaction
end
@ -28,8 +28,8 @@ class UnEmojiReactService < BaseService
private
def bulk(account, status)
EmojiReaction.where(account: account).where(status: status).each do |emoji_reaction|
call(account.id, status.id, emoji_reaction)
EmojiReaction.where(account: account, status: status).each do |emoji_reaction|
call(account, status, emoji_reaction)
end
end
@ -38,7 +38,7 @@ class UnEmojiReactService < BaseService
end
def notify_to_followers(emoji_reaction)
ActivityPub::RawDistributionWorker.perform_async(build_json(emoji_reaction), @status.account_id)
ActivityPub::RawDistributionWorker.perform_async(build_json(emoji_reaction), @account.id)
end
def write_stream(emoji_reaction)

View file

@ -0,0 +1,41 @@
# frozen_string_literal: true
class ActivityPub::EmojiReactionDistributionWorker < ActivityPub::RawDistributionWorker
# Distribute an emoji reaction to servers that might have a copy of ohagi
def perform(emoji_reaction_id, options = {})
@options = options.with_indifferent_access
@emoji_reaction = EmojiReaction.find(emoji_reaction_id)
@account = @emoji_reaction.account
@status = @emoji_reaction.status
distribute!
rescue ActiveRecord::RecordNotFound
true
end
protected
def payload
@payload ||= Oj.dump(serialize_payload(@emoji_reaction, ActivityPub::EmojiReactionSerializer, signer: @account))
end
def inboxes
@inboxes ||= (@account.followers.inboxes + [@status.account.preferred_inbox_url].compact_blank + relay_inboxes + friend_inboxes).uniq
end
def relay_inboxes
if @status.public_visibility?
Relay.enabled.pluck(:inbox_url)
else
[]
end
end
def friend_inboxes
if @status.distributable_friend?
DeliveryFailureTracker.without_unavailable(FriendDomain.distributables.where(delivery_local: true).where.not(domain: AccountDomainBlock.where(account: @status.account).select(:domain)).pluck(:inbox_url))
else
[]
end
end
end