84cfee2488
* Resolve remote accounts when mentioned even if they are already known This commit reduces the risk of not having up-to-date public key or protocol information for a remote account, which is required to deliver toots (especially direct messages). * Do not add mentions in private messages for remote users we cannot deliver to Mastodon does not deliver private and direct toots to OStatus users, as there is no guarantee the remote software understands the toot's privacy. However, users currently do not get any feedback on it (Mastodon won't attempt delivery, but the toot will be displayed exactly the same way to the user). This change introduces *some* feedback by not processing mentions that are not going to be delivered. A long-term solution is still needed to have delivery receipts or at least some better indication of what is going on, but at least an user can see *something* is up.
55 lines
1.8 KiB
Ruby
55 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ProcessMentionsService < BaseService
|
|
include StreamEntryRenderer
|
|
|
|
# Scan status for mentions and fetch remote mentioned users, create
|
|
# local mention pointers, send Salmon notifications to mentioned
|
|
# remote users
|
|
# @param [Status] status
|
|
def call(status)
|
|
return unless status.local?
|
|
|
|
status.text.scan(Account::MENTION_RE).each do |match|
|
|
begin
|
|
mentioned_account = resolve_remote_account_service.call(match.first.to_s)
|
|
rescue Goldfinger::Error, HTTP::Error
|
|
mentioned_account = nil
|
|
end
|
|
|
|
next if mentioned_account.nil? || (mentioned_account.ostatus? && status.stream_entry.hidden?)
|
|
|
|
mentioned_account.mentions.where(status: status).first_or_create(status: status)
|
|
end
|
|
|
|
status.mentions.includes(:account).each do |mention|
|
|
create_notification(status, mention)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def create_notification(status, mention)
|
|
mentioned_account = mention.account
|
|
|
|
if mentioned_account.local?
|
|
NotifyService.new.call(mentioned_account, mention)
|
|
elsif mentioned_account.ostatus? && !status.stream_entry.hidden?
|
|
NotificationWorker.perform_async(stream_entry_to_xml(status.stream_entry), status.account_id, mentioned_account.id)
|
|
elsif mentioned_account.activitypub?
|
|
ActivityPub::DeliveryWorker.perform_async(build_json(mention.status), mention.status.account_id, mentioned_account.inbox_url)
|
|
end
|
|
end
|
|
|
|
def build_json(status)
|
|
Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
|
|
status,
|
|
serializer: ActivityPub::ActivitySerializer,
|
|
adapter: ActivityPub::Adapter
|
|
).as_json).sign!(status.account))
|
|
end
|
|
|
|
def resolve_remote_account_service
|
|
ResolveRemoteAccountService.new
|
|
end
|
|
end
|