You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.0 KiB

  1. class ProcessInteractionService
  2. include ApplicationHelper
  3. def call(envelope, target_account)
  4. body = salmon.unpack(envelope)
  5. xml = Nokogiri::XML(body)
  6. return unless involves_target_account?(xml, target_account) && contains_author?(xml)
  7. username = xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:name').content
  8. url = xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:uri').content
  9. domain = Addressable::URI.parse(url).host
  10. account = Account.find_by(username: username, domain: domain)
  11. if account.nil?
  12. account = follow_remote_account_service.("acct:#{username}@#{domain}")
  13. return if account.nil?
  14. end
  15. if salmon.verify(envelope, account.keypair)
  16. case get_verb(xml)
  17. when :follow
  18. account.follow!(target_account)
  19. when :unfollow
  20. account.unfollow!(target_account)
  21. when :favorite
  22. # todo: a favourite
  23. when :post
  24. # todo: a reply
  25. when :share
  26. # todo: a reblog
  27. end
  28. end
  29. end
  30. private
  31. def contains_author?(xml)
  32. !(xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:name').nil? || xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:uri').nil?)
  33. end
  34. def involves_target_account?(xml, account)
  35. targeted_at_account?(xml, account) || mentions_account?(xml, account)
  36. end
  37. def targeted_at_account?(xml, account)
  38. target_id = xml.at_xpath('/xmlns:entry/activity:object/xmlns:id')
  39. !target_id.nil? && target_id.content == profile_url(name: account.username)
  40. end
  41. def mentions_account?(xml, account)
  42. xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]').each do |mention_link|
  43. return true if mention_link.attribute('ref') == profile_url(name: account.username)
  44. end
  45. false
  46. end
  47. def get_verb(xml)
  48. verb = xml.at_xpath('//activity:verb').content.gsub 'http://activitystrea.ms/schema/1.0/', ''
  49. verb.to_sym
  50. end
  51. def salmon
  52. OStatus2::Salmon.new
  53. end
  54. def follow_remote_account_service
  55. FollowRemoteAccountService.new
  56. end
  57. end