@ -10,55 +10,61 @@ class ProcessMentionsService < BaseService
def call ( status )
def call ( status )
return unless status . local?
return unless status . local?
@status = status
mentions = [ ]
status . text = status . text . gsub ( Account :: MENTION_RE ) do | match |
status . text = status . text . gsub ( Account :: MENTION_RE ) do | match |
username , domain = $1 . split ( '@' )
username , domain = Regexp . last_match ( 1 ) . split ( '@' )
mentioned_account = Account . find_remote ( username , domain )
mentioned_account = Account . find_remote ( username , domain )
if mention_undeliverable? ( status, mentioned_account)
if mention_undeliverable? ( mentioned_account)
begin
begin
mentioned_account = resolve_account_service . call ( $1 )
mentioned_account = resolve_account_service . call ( Regexp . last_match ( 1 ) )
rescue Goldfinger :: Error , HTTP :: Error , OpenSSL :: SSL :: SSLError , Mastodon :: UnexpectedResponseError
rescue Goldfinger :: Error , HTTP :: Error , OpenSSL :: SSL :: SSLError , Mastodon :: UnexpectedResponseError
mentioned_account = nil
mentioned_account = nil
end
end
end
end
next match if mention_undeliverable? ( status , mentioned_account )
next match if mention_undeliverable? ( mentioned_account )
mentions << mentioned_account . mentions . where ( status : status ) . first_or_create ( status : status )
mentioned_account . mentions . where ( status : status ) . first_or_create ( status : status )
" @ #{ mentioned_account . acct } "
" @ #{ mentioned_account . acct } "
end
end
status . save!
status . save!
status . mentions . includes ( :account ) . each do | mention |
mentions . each { | mention | create_notification ( mention ) }
create_notification ( status , mention )
end
end
end
private
private
def mention_undeliverable? ( status, mentioned_account)
def mention_undeliverable? ( mentioned_account)
mentioned_account . nil? || ( ! mentioned_account . local? && mentioned_account . ostatus? && status. stream_entry . hidden? )
mentioned_account . nil? || ( ! mentioned_account . local? && mentioned_account . ostatus? && @ status. stream_entry . hidden? )
end
end
def create_notification ( status, mention)
def create_notification ( mention)
mentioned_account = mention . account
mentioned_account = mention . account
if mentioned_account . local?
if mentioned_account . local?
NotifyService. new . call ( mentioned_account , mention )
LocalNotificationWorker. perform_async ( mention . id )
elsif mentioned_account . ostatus? && ! status. stream_entry . hidden?
elsif mentioned_account . ostatus? && ! @ status. stream_entry . hidden?
NotificationWorker . perform_async ( stream_entry_to_xml( status . stream_entry ) , status. account_id , mentioned_account . id )
NotificationWorker . perform_async ( ostatus_xml, @ status. account_id , mentioned_account . id )
elsif mentioned_account . activitypub?
elsif mentioned_account . activitypub?
ActivityPub :: DeliveryWorker . perform_async ( build_json( mention . status ) , mention . status . account_id , mentioned_account . inbox_url )
ActivityPub :: DeliveryWorker . perform_async ( activitypub_json , mention . status . account_id , mentioned_account . inbox_url )
end
end
end
end
def build_json ( status )
def ostatus_xml
Oj . dump ( ActivityPub :: LinkedDataSignature . new ( ActiveModelSerializers :: SerializableResource . new (
@ostatus_xml || = stream_entry_to_xml ( @status . stream_entry )
status ,
end
def activitypub_json
@activitypub_json || = Oj . dump ( ActivityPub :: LinkedDataSignature . new ( ActiveModelSerializers :: SerializableResource . new (
@status ,
serializer : ActivityPub :: ActivitySerializer ,
serializer : ActivityPub :: ActivitySerializer ,
adapter : ActivityPub :: Adapter
adapter : ActivityPub :: Adapter
) . as_json ) . sign! ( status . account ) )
) . as_json ) . sign! ( @ status. account ) )
end
end
def resolve_account_service
def resolve_account_service