* Change: #185 『スタンプをつけられた人』ではなく『スタンプをつけた人』のフォロワーにスタンプを転送 * Fix: 絵文字削除が届かない問題 * Test: 送る方にも同じテストを追加
This commit is contained in:
parent
a1d197dfef
commit
24909f9760
9 changed files with 134 additions and 91 deletions
|
@ -27,7 +27,7 @@ class Api::V1::Statuses::EmojiReactionsController < Api::BaseController
|
||||||
|
|
||||||
authorize @status, :show? if emoji_reaction.nil?
|
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
|
else
|
||||||
authorize @status, :show?
|
authorize @status, :show?
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,38 +54,11 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
|
||||||
Trends.statuses.register(@original_status)
|
Trends.statuses.register(@original_status)
|
||||||
write_stream(reaction)
|
write_stream(reaction)
|
||||||
|
|
||||||
if @original_status.account.local?
|
NotifyService.new.call(@original_status.account, :emoji_reaction, 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
|
|
||||||
rescue Seahorse::Client::NetworkingError
|
rescue Seahorse::Client::NetworkingError
|
||||||
nil
|
nil
|
||||||
end
|
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
|
def shortcode
|
||||||
return @shortcode if defined?(@shortcode)
|
return @shortcode if defined?(@shortcode)
|
||||||
|
|
||||||
|
|
|
@ -147,12 +147,6 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
|
||||||
if emoji_reaction
|
if emoji_reaction
|
||||||
emoji_reaction.destroy
|
emoji_reaction.destroy
|
||||||
write_stream(emoji_reaction)
|
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
|
end
|
||||||
else
|
else
|
||||||
undo_like_original
|
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)
|
@render_emoji_reaction ||= Oj.dump(event: :emoji_reaction, payload: emoji_group.to_json)
|
||||||
end
|
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
|
def shortcode
|
||||||
return @shortcode if defined?(@shortcode)
|
return @shortcode if defined?(@shortcode)
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ class StatusReachFinder
|
||||||
end
|
end
|
||||||
|
|
||||||
def friend_inboxes
|
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))
|
DeliveryFailureTracker.without_unavailable(FriendDomain.distributables.where(delivery_local: true).where.not(domain: AccountDomainBlock.where(account: @status.account).select(:domain)).pluck(:inbox_url))
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -46,29 +46,15 @@ class EmojiReactService < BaseService
|
||||||
|
|
||||||
def create_notification
|
def create_notification
|
||||||
status = @emoji_reaction.status
|
status = @emoji_reaction.status
|
||||||
|
return unless status.account.local?
|
||||||
|
return unless status.account.user&.setting_enable_emoji_reaction
|
||||||
|
|
||||||
if status.account.local?
|
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', 'reaction') if status.account.user&.setting_emoji_reaction_streaming_notify_impl2
|
||||||
if status.account.user&.setting_enable_emoji_reaction
|
LocalNotificationWorker.perform_async(status.account_id, @emoji_reaction.id, 'EmojiReaction', '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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_to_followers
|
def notify_to_followers
|
||||||
status = @emoji_reaction.status
|
ActivityPub::EmojiReactionDistributionWorker.perform_async(@emoji_reaction.id)
|
||||||
|
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_stream!
|
def write_stream!
|
||||||
|
|
|
@ -4,23 +4,23 @@ class UnEmojiReactService < BaseService
|
||||||
include Redisable
|
include Redisable
|
||||||
include Payloadable
|
include Payloadable
|
||||||
|
|
||||||
def call(account_id, status_id, emoji_reaction = nil)
|
def call(account, status, emoji_reaction = nil)
|
||||||
@status = Status.find(status_id)
|
@account = account
|
||||||
|
@status = status
|
||||||
|
|
||||||
if emoji_reaction
|
if emoji_reaction
|
||||||
emoji_reaction.destroy!
|
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?
|
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)
|
write_stream(emoji_reaction)
|
||||||
|
|
||||||
relay_for_undo_emoji_reaction!(emoji_reaction)
|
relay_for_undo_emoji_reaction!(emoji_reaction)
|
||||||
relay_friend_for_undo_emoji_reaction!(emoji_reaction)
|
relay_friend_for_undo_emoji_reaction!(emoji_reaction)
|
||||||
else
|
else
|
||||||
account = Account.find(account_id)
|
bulk(account, status)
|
||||||
bulk(account, @status)
|
|
||||||
end
|
end
|
||||||
emoji_reaction
|
emoji_reaction
|
||||||
end
|
end
|
||||||
|
@ -28,8 +28,8 @@ class UnEmojiReactService < BaseService
|
||||||
private
|
private
|
||||||
|
|
||||||
def bulk(account, status)
|
def bulk(account, status)
|
||||||
EmojiReaction.where(account: account).where(status: status).each do |emoji_reaction|
|
EmojiReaction.where(account: account, status: status).each do |emoji_reaction|
|
||||||
call(account.id, status.id, emoji_reaction)
|
call(account, status, emoji_reaction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class UnEmojiReactService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_to_followers(emoji_reaction)
|
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
|
end
|
||||||
|
|
||||||
def write_stream(emoji_reaction)
|
def write_stream(emoji_reaction)
|
||||||
|
|
|
@ -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
|
|
@ -161,11 +161,46 @@ RSpec.describe EmojiReactService, type: :service do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when has remote followers' do
|
context 'when remote status' do
|
||||||
|
let(:author) { Fabricate(:account, domain: 'author.foo.bar', uri: 'https://author.foo.bar/actor', inbox_url: 'https://author.foo.bar/inbox', protocol: 'activitypub') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:post, 'https://author.foo.bar/inbox')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'react with emoji' do
|
||||||
|
expect(subject.count).to eq 1
|
||||||
|
expect(a_request(:post, 'https://author.foo.bar/inbox').with(body: hash_including({
|
||||||
|
type: 'Like',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(sender),
|
||||||
|
content: '😀',
|
||||||
|
}))).to have_been_made.once
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when has followers' do
|
||||||
|
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
bob.follow!(sender)
|
||||||
|
stub_request(:post, 'https://foo.bar/inbox')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'react with emoji' do
|
||||||
|
expect(subject.count).to eq 1
|
||||||
|
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||||
|
type: 'Like',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(sender),
|
||||||
|
content: '😀',
|
||||||
|
}))).to have_been_made.once
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when sender has remote followers' do
|
||||||
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
bob.follow!(author)
|
bob.follow!(sender)
|
||||||
stub_request(:post, 'https://foo.bar/inbox')
|
stub_request(:post, 'https://foo.bar/inbox')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe UnEmojiReactService, type: :service do
|
RSpec.describe UnEmojiReactService, type: :service do
|
||||||
subject do
|
subject do
|
||||||
described_class.new.call(sender.id, status.id, emoji_reaction)
|
described_class.new.call(sender, status, emoji_reaction)
|
||||||
EmojiReaction.where(status: status, account: sender)
|
EmojiReaction.where(status: status, account: sender)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -82,12 +82,48 @@ RSpec.describe UnEmojiReactService, type: :service do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when has remote followers' do
|
context 'when remote status' do
|
||||||
|
let(:author) { Fabricate(:account, domain: 'author.foo.bar', uri: 'https://author.foo.bar/actor', inbox_url: 'https://author.foo.bar/inbox', protocol: 'activitypub') }
|
||||||
|
let(:emoji_reaction) { Fabricate(:emoji_reaction, account: sender, status: status, name: '😀') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:post, 'https://author.foo.bar/inbox')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'react with emoji' do
|
||||||
|
expect(subject.count).to eq 0
|
||||||
|
expect(a_request(:post, 'https://author.foo.bar/inbox').with(body: hash_including({
|
||||||
|
type: 'Undo',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(sender),
|
||||||
|
content: '😀',
|
||||||
|
}))).to have_been_made.once
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when has followers' do
|
||||||
|
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
bob.follow!(sender)
|
||||||
|
stub_request(:post, 'https://foo.bar/inbox')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'react with emoji' do
|
||||||
|
expect(subject.count).to eq 0
|
||||||
|
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||||
|
type: 'Undo',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(sender),
|
||||||
|
content: '😀',
|
||||||
|
}))).to have_been_made.once
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when sender has remote followers' do
|
||||||
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
let!(:bob) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', inbox_url: 'https://foo.bar/inbox', protocol: 'activitypub') }
|
||||||
let(:emoji_reaction) { Fabricate(:emoji_reaction, account: sender, status: status, name: '😀') }
|
let(:emoji_reaction) { Fabricate(:emoji_reaction, account: sender, status: status, name: '😀') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
bob.follow!(author)
|
bob.follow!(sender)
|
||||||
stub_request(:post, 'https://foo.bar/inbox')
|
stub_request(:post, 'https://foo.bar/inbox')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue