handle incoming custom emoji reactions properly

This commit is contained in:
fef 2022-12-03 10:22:15 +00:00 committed by Jeremy Kescher
parent 50cd1cc5f7
commit 3df2d0b1f1
No known key found for this signature in database
GPG key ID: 80A419A7A613DFA4
5 changed files with 29 additions and 19 deletions

View file

@ -181,24 +181,27 @@ class ActivityPub::Activity
# Ensure all emojis declared in the activity's tags are # Ensure all emojis declared in the activity's tags are
# present in the database and downloaded to the local cache. # present in the database and downloaded to the local cache.
def process_emoji_tags # Required by EmojiReact and Like for emoji reactions.
as_array(@object['tag']).each do |tag| def process_emoji_tags(tags)
process_single_emoji(tag) if tag['type'] == 'Emoji' as_array(tags).each do |tag|
process_single_emoji tag if tag['type'] == 'Emoji'
end end
end end
def process_single_emoji(tag) def process_single_emoji(tag)
parser = ActivityPub::Parser::CustomEmojiParser.new(tag) custom_emoji_parser = ActivityPub::Parser::CustomEmojiParser.new(tag)
return if parser.shortcode.blank? || parser.image_remote_url.blank? return if custom_emoji_parser.shortcode.blank? || custom_emoji_parser.image_remote_url.blank?
emoji = CustomEmoji.find_by(shortcode: parser.shortcode, domain: @account.domain) emoji = CustomEmoji.find_by(shortcode: custom_emoji_parser.shortcode, domain: @account.domain)
return unless emoji.nil? || return unless emoji.nil? ||
parser.image_remote_url != emoji.image_remote_url || custom_emoji_parser.image_remote_url != emoji.image_remote_url ||
(parser.updated_at && parser.updated_at >= emoji.updated_at) (custom_emoji_parser.updated_at && custom_emoji_parser.updated_at >= emoji.updated_at)
begin begin
emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: parser.shortcode, uri: parser.uri) emoji ||= CustomEmoji.new(domain: @account.domain,
emoji.image_remote_url = parser.image_remote_url shortcode: custom_emoji_parser.shortcode,
uri: custom_emoji_parser.uri)
emoji.image_remote_url = custom_emoji_parser.image_remote_url
emoji.save emoji.save
rescue Seahorse::Client::NetworkingError => e rescue Seahorse::Client::NetworkingError => e
Rails.logger.warn "Error fetching emoji: #{e}" Rails.logger.warn "Error fetching emoji: #{e}"

View file

@ -9,14 +9,16 @@ class ActivityPub::Activity::EmojiReact < ActivityPub::Activity
delete_arrived_first?(@json['id']) || delete_arrived_first?(@json['id']) ||
@account.reacted?(original_status, name) @account.reacted?(original_status, name)
custom_emoji = nil
if name =~ /^:.*:$/ if name =~ /^:.*:$/
process_emoji_tags process_emoji_tags(@json['tag'])
name.delete! ':' name.delete! ':'
return if CustomEmoji.find_by(shortcode: name, domain: @account.domain).nil? custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain)
return if custom_emoji.nil?
end end
reaction = original_status.status_reactions.create!(account: @account, name: name) 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') LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction')
end end

View file

@ -23,16 +23,16 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
custom_emoji = nil custom_emoji = nil
if name =~ /^:.*:$/ if name =~ /^:.*:$/
process_emoji_tags process_emoji_tags(@json['tag'])
name.delete! ':' name.delete! ':'
custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain) 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 return false if custom_emoji.nil? # invalid custom emoji, treat it as a regular like
end end
return true if @account.reacted?(original_status, name, custom_emoji) return true if @account.reacted?(original_status, name)
reaction = original_status.status_reactions.create!(account: @account, name: name, custom_emoji: 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') LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction')
return true true
end end
end end

View file

@ -243,8 +243,8 @@ module AccountInteractions
status.proper.favourites.where(account: self).exists? status.proper.favourites.where(account: self).exists?
end end
def reacted?(status, name, custom_emoji = nil) def reacted?(status, name)
status.proper.status_reactions.where(account: self, name: name, custom_emoji: custom_emoji).exists? status.proper.status_reactions.where(account: self, name: name).exists?
end end
def bookmarked?(status) def bookmarked?(status)

View file

@ -24,6 +24,11 @@ class StatusReaction < ApplicationRecord
private private
def set_custom_emoji def set_custom_emoji
self.custom_emoji = CustomEmoji.local.find_by(disabled: false, shortcode: name) if name.present? return if name.blank?
self.custom_emoji = if account.local?
CustomEmoji.local.find_by(disabled: false, shortcode: name)
else
CustomEmoji.find_by(shortcode: name, domain: account.domain)
end
end end
end end