Module: RivetCms::Webhooks

Defined in:
app/services/rivet_cms/webhooks.rb

Overview

Fans a lifecycle event out to the host-configured webhook endpoints. RivetCms.webhooks is an array of { url:, events: } hashes; events is optional and defaults to everything.

Constant Summary collapse

EVENT_NAMES =
{ publish: "entry.published" }.freeze

Class Method Summary collapse

Class Method Details

.deliver(event, revision) ⇒ Object



8
9
10
11
12
13
14
15
# File 'app/services/rivet_cms/webhooks.rb', line 8

def self.deliver(event, revision)
  endpoints_for(event).each do |endpoint|
    url = endpoint[:url] || endpoint["url"]
    next if url.blank?

    WebhookDeliveryJob.perform_later(url, payload(event, revision))
  end
end

.endpoints_for(event) ⇒ Object



17
18
19
20
21
22
23
# File 'app/services/rivet_cms/webhooks.rb', line 17

def self.endpoints_for(event)
  name = EVENT_NAMES.fetch(event, event.to_s)
  Array(RivetCms.webhooks).select do |endpoint|
    events = endpoint[:events] || endpoint["events"]
    events.nil? || events.map(&:to_s).include?(name)
  end
end

.payload(event, revision) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/services/rivet_cms/webhooks.rb', line 25

def self.payload(event, revision)
  document = revision.document
  {
    event: EVENT_NAMES.fetch(event),
    document_id: document.prefix_id,
    slug: document.slug,
    # with_discarded: publishing into a removed type is reachable from host
    # code, and the payload should still say which type it was.
    content_type: ContentType.with_discarded.where(id: document.content_type_id).pick(:slug),
    organization: document.organization.subdomain,
    locale: revision.locale,
    published_at: revision.published_at&.iso8601,
    author: revision.author_name
  }
end

.validate_config!Object

Fails fast at boot so a malformed entry cannot silently disable delivery (publish-path errors are swallowed by the hook seam).



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/services/rivet_cms/webhooks.rb', line 43

def self.validate_config!
  Array(RivetCms.webhooks).each do |endpoint|
    raise ArgumentError, "RivetCms.webhooks entries must be hashes, got #{endpoint.class}" unless endpoint.is_a?(Hash)

    url = endpoint[:url] || endpoint["url"]
    uri = URI.parse(url.to_s) rescue nil
    unless uri.is_a?(URI::HTTP) # covers HTTPS (subclass)
      raise ArgumentError, "RivetCms.webhooks url must be http(s), got #{url.inspect}"
    end

    events = endpoint[:events] || endpoint["events"]
    next if events.nil?
    unless events.is_a?(Array) && (events.map(&:to_s) - EVENT_NAMES.values).empty?
      raise ArgumentError, "RivetCms.webhooks events must be an array from #{EVENT_NAMES.values.inspect}, got #{events.inspect}"
    end
  end
end