relay.rb 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: relays
  5. #
  6. # id :bigint(8) not null, primary key
  7. # inbox_url :string default(""), not null
  8. # follow_activity_id :string
  9. # created_at :datetime not null
  10. # updated_at :datetime not null
  11. # state :integer default("idle"), not null
  12. #
  13. class Relay < ApplicationRecord
  14. validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
  15. enum :state, { idle: 0, pending: 1, accepted: 2, rejected: 3 }
  16. scope :enabled, -> { accepted }
  17. normalizes :inbox_url, with: ->(inbox_url) { inbox_url.strip }
  18. before_destroy :ensure_disabled
  19. alias enabled? accepted?
  20. def to_log_human_identifier
  21. inbox_url
  22. end
  23. def enable!
  24. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  25. payload = Oj.dump(follow_activity(activity_id))
  26. update!(state: :pending, follow_activity_id: activity_id)
  27. DeliveryFailureTracker.reset!(inbox_url)
  28. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  29. end
  30. def disable!
  31. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  32. payload = Oj.dump(unfollow_activity(activity_id))
  33. update!(state: :idle, follow_activity_id: nil)
  34. DeliveryFailureTracker.reset!(inbox_url)
  35. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  36. end
  37. private
  38. def follow_activity(activity_id)
  39. {
  40. '@context': ActivityPub::TagManager::CONTEXT,
  41. id: activity_id,
  42. type: 'Follow',
  43. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  44. object: ActivityPub::TagManager::COLLECTIONS[:public],
  45. }
  46. end
  47. def unfollow_activity(activity_id)
  48. {
  49. '@context': ActivityPub::TagManager::CONTEXT,
  50. id: activity_id,
  51. type: 'Undo',
  52. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  53. object: {
  54. id: follow_activity_id,
  55. type: 'Follow',
  56. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  57. object: ActivityPub::TagManager::COLLECTIONS[:public],
  58. },
  59. }
  60. end
  61. def some_local_account
  62. @some_local_account ||= Account.representative
  63. end
  64. def ensure_disabled
  65. disable! if enabled?
  66. end
  67. end