relay.rb 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 enable!
  21. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  22. payload = Oj.dump(follow_activity(activity_id))
  23. update!(state: :pending, follow_activity_id: activity_id)
  24. DeliveryFailureTracker.reset!(inbox_url)
  25. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  26. end
  27. def disable!
  28. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  29. payload = Oj.dump(unfollow_activity(activity_id))
  30. update!(state: :idle, follow_activity_id: nil)
  31. DeliveryFailureTracker.reset!(inbox_url)
  32. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  33. end
  34. private
  35. def follow_activity(activity_id)
  36. {
  37. '@context': ActivityPub::TagManager::CONTEXT,
  38. id: activity_id,
  39. type: 'Follow',
  40. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  41. object: ActivityPub::TagManager::COLLECTIONS[:public],
  42. }
  43. end
  44. def unfollow_activity(activity_id)
  45. {
  46. '@context': ActivityPub::TagManager::CONTEXT,
  47. id: activity_id,
  48. type: 'Undo',
  49. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  50. object: {
  51. id: follow_activity_id,
  52. type: 'Follow',
  53. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  54. object: ActivityPub::TagManager::COLLECTIONS[:public],
  55. },
  56. }
  57. end
  58. def some_local_account
  59. @some_local_account ||= Account.representative
  60. end
  61. def ensure_disabled
  62. disable! if enabled?
  63. end
  64. end