download remote custom emojis from reactions
Emoji reactions containing custom emojis from remote instances were assumed to already have been downloaded and stored in the database. This might obviously not be the case.
This commit is contained in:
parent
17d23d1c73
commit
bd026ad118
3 changed files with 58 additions and 13 deletions
|
@ -176,4 +176,30 @@ class ActivityPub::Activity
|
|||
Rails.logger.info("Rejected #{@json['type']} activity #{@json['id']} from #{@account.uri}#{@options[:relayed_through_actor] && "via #{@options[:relayed_through_actor].uri}"}")
|
||||
nil
|
||||
end
|
||||
|
||||
# Ensure all emojis declared in the activity's tags are
|
||||
# present in the database and downloaded to the local cache.
|
||||
def process_emoji_tags
|
||||
as_array(@object['tag']).each do |tag|
|
||||
process_single_emoji(tag) if tag['type'] == 'Emoji'
|
||||
end
|
||||
end
|
||||
|
||||
def process_single_emoji(tag)
|
||||
parser = ActivityPub::Parser::CustomEmojiParser.new(tag)
|
||||
return if parser.shortcode.blank? || parser.image_remote_url.blank?
|
||||
|
||||
emoji = CustomEmoji.find_by(shortcode: parser.shortcode, domain: @account.domain)
|
||||
return unless emoji.nil? ||
|
||||
parser.image_remote_url != emoji.image_remote_url ||
|
||||
(parser.updated_at && parser.updated_at >= emoji.updated_at)
|
||||
|
||||
begin
|
||||
emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: parser.shortcode, uri: parser.uri)
|
||||
emoji.image_remote_url = parser.image_remote_url
|
||||
emoji.save
|
||||
rescue Seahorse::Client::NetworkingError => e
|
||||
Rails.logger.warn "Error fetching emoji: #{e}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,9 +5,16 @@ class ActivityPub::Activity::EmojiReact < ActivityPub::Activity
|
|||
original_status = status_from_uri(object_uri)
|
||||
name = @json['content']
|
||||
return if original_status.nil? ||
|
||||
!original_status.account.local? ||
|
||||
delete_arrived_first?(@json['id']) ||
|
||||
@account.reacted?(original_status, name)
|
||||
!original_status.account.local? ||
|
||||
delete_arrived_first?(@json['id']) ||
|
||||
@account.reacted?(original_status, name)
|
||||
|
||||
if name =~ /^:.*:$/
|
||||
process_emoji_tags
|
||||
|
||||
name.delete! ':'
|
||||
return if CustomEmoji.find_by(shortcode: name, domain: @account.domain).nil?
|
||||
end
|
||||
|
||||
reaction = original_status.status_reactions.create!(account: @account, name: name)
|
||||
|
||||
|
|
|
@ -5,16 +5,7 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
|
|||
original_status = status_from_uri(object_uri)
|
||||
return if original_status.nil? || !original_status.account.local? || delete_arrived_first?(@json['id'])
|
||||
|
||||
# misskey delivers reactions as likes and attaches the emoji in _misskey_reaction
|
||||
mk_reaction = @json['_misskey_reaction']
|
||||
unless mk_reaction.nil?
|
||||
custom_emoji = CustomEmoji.find_by(shortcode: mk_reaction, domain: @account.domain)
|
||||
return if @account.reacted?(original_status, mk_reaction, custom_emoji)
|
||||
|
||||
reaction = original_status.status_reactions.create!(account: @account, name: mk_reaction, custom_emoji: custom_emoji)
|
||||
LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction')
|
||||
return
|
||||
end
|
||||
return if maybe_process_misskey_reaction(original_status)
|
||||
|
||||
return if @account.favourited?(original_status)
|
||||
|
||||
|
@ -23,4 +14,25 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
|
|||
LocalNotificationWorker.perform_async(original_status.account_id, favourite.id, 'Favourite', 'favourite')
|
||||
Trends.statuses.register(original_status)
|
||||
end
|
||||
|
||||
# Misskey delivers reactions as likes with the emoji in _misskey_reaction
|
||||
# see https://misskey-hub.net/ns.html#misskey-reaction for details
|
||||
def maybe_process_misskey_reaction(original_status)
|
||||
name = @json['_misskey_reaction']
|
||||
return false if name.nil?
|
||||
|
||||
custom_emoji = nil
|
||||
if name =~ /^:.*:$/
|
||||
process_emoji_tags
|
||||
|
||||
name.delete! ':'
|
||||
custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain)
|
||||
return false if custom_emoji.nil? # invalid custom emoji, treat it as a regular like
|
||||
end
|
||||
return true if @account.reacted?(original_status, name, custom_emoji)
|
||||
|
||||
reaction = original_status.status_reactions.create!(account: @account, name: name, custom_emoji: custom_emoji)
|
||||
LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction')
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue