handle incoming custom emoji reactions properly

This commit is contained in:
anna 2022-12-03 10:22:15 +00:00
parent 8ad172535e
commit ccf4f46d7f
Signed by: fef
GPG key ID: EC22E476DC2D3D84
5 changed files with 29 additions and 19 deletions

View file

@ -179,24 +179,27 @@ class ActivityPub::Activity
# 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'
# Required by EmojiReact and Like for emoji reactions.
def process_emoji_tags(tags)
as_array(tags).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?
custom_emoji_parser = ActivityPub::Parser::CustomEmojiParser.new(tag)
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? ||
parser.image_remote_url != emoji.image_remote_url ||
(parser.updated_at && parser.updated_at >= emoji.updated_at)
custom_emoji_parser.image_remote_url != emoji.image_remote_url ||
(custom_emoji_parser.updated_at && custom_emoji_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 ||= CustomEmoji.new(domain: @account.domain,
shortcode: custom_emoji_parser.shortcode,
uri: custom_emoji_parser.uri)
emoji.image_remote_url = custom_emoji_parser.image_remote_url
emoji.save
rescue Seahorse::Client::NetworkingError => 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']) ||
@account.reacted?(original_status, name)
custom_emoji = nil
if name =~ /^:.*:$/
process_emoji_tags
process_emoji_tags(@json['tag'])
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
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')
end

View file

@ -23,16 +23,16 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
custom_emoji = nil
if name =~ /^:.*:$/
process_emoji_tags
process_emoji_tags(@json['tag'])
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)
return true if @account.reacted?(original_status, 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')
return true
true
end
end

View file

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

View file

@ -24,6 +24,11 @@ class StatusReaction < ApplicationRecord
private
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