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.2 KiB

  1. # frozen_string_literal: true
  2. class UnfollowService < BaseService
  3. # Unfollow and notify the remote user
  4. # @param [Account] source_account Where to unfollow from
  5. # @param [Account] target_account Which to unfollow
  6. def call(source_account, target_account)
  7. @source_account = source_account
  8. @target_account = target_account
  9. unfollow! || undo_follow_request!
  10. end
  11. private
  12. def unfollow!
  13. follow = Follow.find_by(account: @source_account, target_account: @target_account)
  14. return unless follow
  15. follow.destroy!
  16. create_notification(follow) unless @target_account.local?
  17. create_reject_notification(follow) if @target_account.local? && !@source_account.local?
  18. UnmergeWorker.perform_async(@target_account.id, @source_account.id)
  19. follow
  20. end
  21. def undo_follow_request!
  22. follow_request = FollowRequest.find_by(account: @source_account, target_account: @target_account)
  23. return unless follow_request
  24. follow_request.destroy!
  25. create_notification(follow_request) unless @target_account.local?
  26. follow_request
  27. end
  28. def create_notification(follow)
  29. if follow.target_account.ostatus?
  30. NotificationWorker.perform_async(build_xml(follow), follow.account_id, follow.target_account_id)
  31. elsif follow.target_account.activitypub?
  32. ActivityPub::DeliveryWorker.perform_async(build_json(follow), follow.account_id, follow.target_account.inbox_url)
  33. end
  34. end
  35. def create_reject_notification(follow)
  36. # Rejecting an already-existing follow request
  37. return unless follow.account.activitypub?
  38. ActivityPub::DeliveryWorker.perform_async(build_reject_json(follow), follow.target_account_id, follow.account.inbox_url)
  39. end
  40. def build_json(follow)
  41. ActiveModelSerializers::SerializableResource.new(
  42. follow,
  43. serializer: ActivityPub::UndoFollowSerializer,
  44. adapter: ActivityPub::Adapter
  45. ).to_json
  46. end
  47. def build_reject_json(follow)
  48. ActiveModelSerializers::SerializableResource.new(
  49. follow,
  50. serializer: ActivityPub::RejectFollowSerializer,
  51. adapter: ActivityPub::Adapter
  52. ).to_json
  53. end
  54. def build_xml(follow)
  55. OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.unfollow_salmon(follow))
  56. end
  57. end