Files
fizzy/app/models/webhook.rb
T
2025-11-05 13:31:54 +01:00

77 lines
1.8 KiB
Ruby

class Webhook < ApplicationRecord
include Triggerable
SLACK_WEBHOOK_URL_REGEX = %r{//hooks\.slack\.com/services/T[^\/]+/B[^\/]+/[^\/]+\Z}i
CAMPFIRE_WEBHOOK_URL_REGEX = %r{/rooms/\d+/\d+-[^\/]+/messages\Z}i
BASECAMP_CAMPFIRE_WEBHOOK_URL_REGEX = %r{/\d+/integrations/[^\/]+/buckets/\d+/chats/\d+/lines\Z}i
PERMITTED_SCHEMES = %w[ http https ].freeze
PERMITTED_ACTIONS = %w[
card_assigned
card_closed
card_postponed
card_auto_postponed
card_board_changed
card_published
card_reopened
card_sent_back_to_triage
card_triaged
card_unassigned
comment_created
].freeze
has_secure_token :signing_secret
has_many :deliveries, dependent: :delete_all
has_one :delinquency_tracker, dependent: :delete
belongs_to :board
serialize :subscribed_actions, type: Array, coder: JSON
scope :ordered, -> { order(name: :asc, id: :desc) }
scope :active, -> { where(active: true) }
after_create :create_delinquency_tracker!
normalizes :subscribed_actions, with: ->(value) { Array.wrap(value).map(&:to_s).uniq & PERMITTED_ACTIONS }
validates :name, presence: true
validate :validate_url
def activate
update! active: true unless active?
end
def deactivate
update! active: false
end
def renderer
@renderer ||= ApplicationController.renderer.new(script_name: "/#{tenant}", https: !Rails.env.local?)
end
def for_basecamp?
url.match? BASECAMP_CAMPFIRE_WEBHOOK_URL_REGEX
end
def for_campfire?
url.match? CAMPFIRE_WEBHOOK_URL_REGEX
end
def for_slack?
url.match? SLACK_WEBHOOK_URL_REGEX
end
private
def validate_url
uri = URI.parse(url.presence)
if PERMITTED_SCHEMES.exclude?(uri.scheme)
errors.add :url, "must use #{PERMITTED_SCHEMES.to_choice_sentence}"
end
rescue URI::InvalidURIError
errors.add :url, "not a URL"
end
end