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.

63 lines
1.5 KiB

  1. # frozen_string_literal: true
  2. class ActivityPub::Forwarder
  3. def initialize(account, original_json, status)
  4. @json = original_json
  5. @account = account
  6. @status = status
  7. end
  8. def forwardable?
  9. @json['signature'].present? && @status.distributable?
  10. end
  11. def forward!
  12. ActivityPub::LowPriorityDeliveryWorker.push_bulk(inboxes) do |inbox_url|
  13. [payload, signature_account_id, inbox_url]
  14. end
  15. end
  16. private
  17. def payload
  18. @payload ||= Oj.dump(@json)
  19. end
  20. def reblogged_by_account_ids
  21. @reblogged_by_account_ids ||= @status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id)
  22. end
  23. def signature_account_id
  24. @signature_account_id ||= if in_reply_to_local?
  25. in_reply_to.account_id
  26. else
  27. reblogged_by_account_ids.first
  28. end
  29. end
  30. def inboxes
  31. @inboxes ||= begin
  32. arr = inboxes_for_followers_of_reblogged_by_accounts
  33. arr += inboxes_for_followers_of_replied_to_account if in_reply_to_local?
  34. arr -= [@account.preferred_inbox_url]
  35. arr.uniq!
  36. arr
  37. end
  38. end
  39. def inboxes_for_followers_of_reblogged_by_accounts
  40. Account.where(id: ::Follow.where(target_account_id: reblogged_by_account_ids).select(:account_id)).inboxes
  41. end
  42. def inboxes_for_followers_of_replied_to_account
  43. in_reply_to.account.followers.inboxes
  44. end
  45. def in_reply_to
  46. @status.thread
  47. end
  48. def in_reply_to_local?
  49. @status.thread&.account&.local?
  50. end
  51. end