Class: Attio::Webhook

Inherits:
APIResource show all
Defined in:
lib/attio/resources/webhook.rb

Overview

Represents a webhook configuration in Attio

Constant Summary collapse

EVENTS =

Event types

%w[
  record.created
  record.updated
  record.deleted
  list_entry.created
  list_entry.deleted
  note.created
  note.deleted
  task.created
  task.updated
  task.deleted
  object.created
  object.updated
  attribute.created
  attribute.updated
  attribute.archived
].freeze
SignatureVerifier =

Constants to match expected API

WebhookUtils::SignatureVerifier
Event =
WebhookUtils::Event

Constants inherited from APIResource

APIResource::SKIP_KEYS

Instance Attribute Summary collapse

Attributes inherited from APIResource

#created_at, #id, #metadata

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from APIResource

#==, #[], #[]=, api_operations, attr_attio, #changed, #changed?, #changed_attributes, #changes, #each, execute_request, #fetch, #hash, id_param_name, #inspect, #key?, #keys, #persisted?, #reset_changes!, resource_name, #revert!, #to_json, #update_attributes, #update_from, validate_id!, #values

Constructor Details

#initialize(attributes = {}, opts = {}) ⇒ Webhook

Returns a new instance of Webhook.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/attio/resources/webhook.rb', line 48

def initialize(attributes = {}, opts = {})
  super
  normalized_attrs = normalize_attributes(attributes)
  @secret = normalized_attrs[:secret]
  @last_event_at = parse_timestamp(normalized_attrs[:last_event_at])
  @created_by_actor = normalized_attrs[:created_by_actor]

  # Map status to active for convenience
  if status == "active"
    instance_variable_set(:@active, true)
  elsif status == "paused"
    instance_variable_set(:@active, false)
  end
end

Instance Attribute Details

#activeObject

Returns the value of attribute active.



42
43
44
# File 'lib/attio/resources/webhook.rb', line 42

def active
  @active
end

#created_by_actorObject (readonly)

Read-only attributes



41
42
43
# File 'lib/attio/resources/webhook.rb', line 41

def created_by_actor
  @created_by_actor
end

#last_event_atObject (readonly)

Read-only attributes



41
42
43
# File 'lib/attio/resources/webhook.rb', line 41

def last_event_at
  @last_event_at
end

#secretObject (readonly)

Read-only attributes



41
42
43
# File 'lib/attio/resources/webhook.rb', line 41

def secret
  @secret
end

Class Method Details

.create(**kwargs) ⇒ Object

Override create to handle keyword arguments



142
143
144
145
146
147
148
# File 'lib/attio/resources/webhook.rb', line 142

def create(**kwargs)
  opts = {}
  opts[:api_key] = kwargs.delete(:api_key) if kwargs.key?(:api_key)
  prepared_params = prepare_params_for_create(kwargs)
  response = execute_request(:POST, resource_path, prepared_params, opts)
  new(response["data"] || response, opts)
end

.delete(id, **opts) ⇒ Object

Override delete to handle hash IDs



158
159
160
161
162
# File 'lib/attio/resources/webhook.rb', line 158

def delete(id, **opts)
  webhook_id = Util::IdExtractor.extract_for_resource(id, :webhook)
  execute_request(:DELETE, "#{resource_path}/#{webhook_id}", {}, opts)
  true
end

.prepare_params_for_create(params) ⇒ Object

Override create to handle validation



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/attio/resources/webhook.rb', line 165

def prepare_params_for_create(params)
  # Handle both url and target_url parameters for convenience
  target_url = params[:target_url] || params["target_url"] || params[:url] || params["url"]
  validate_target_url!(target_url)
  subscriptions = params[:subscriptions] || params["subscriptions"]
  validate_subscriptions!(subscriptions)

  {
    data: {
      target_url: target_url,
      subscriptions: Array(subscriptions).map do |sub|
        # Ensure each subscription has a filter
        sub = sub.is_a?(Hash) ? sub : {"event_type" => sub}
        sub["filter"] ||= {"$and" => []}  # Default empty filter
        sub
      end
    }
  }
end

.prepare_params_for_update(params) ⇒ Object

Override update params preparation



186
187
188
189
190
# File 'lib/attio/resources/webhook.rb', line 186

def prepare_params_for_update(params)
  {
    data: params
  }
end

.resource_pathString

API endpoint path for webhooks

Returns:

  • (String)

    The API path



14
15
16
# File 'lib/attio/resources/webhook.rb', line 14

def self.resource_path
  "webhooks"
end

.retrieve(id, **opts) ⇒ Object

Override retrieve to handle hash IDs



151
152
153
154
155
# File 'lib/attio/resources/webhook.rb', line 151

def retrieve(id, **opts)
  webhook_id = Util::IdExtractor.extract_for_resource(id, :webhook)
  response = execute_request(:GET, "#{resource_path}/#{webhook_id}", {}, opts)
  new(response["data"] || response, opts)
end

Instance Method Details

#active?Boolean

Check if webhook is active

Returns:

  • (Boolean)


89
90
91
# File 'lib/attio/resources/webhook.rb', line 89

def active?
  active == true
end

#deliveries(params = {}, **opts) ⇒ Object

Get recent deliveries for this webhook



120
121
122
123
124
125
# File 'lib/attio/resources/webhook.rb', line 120

def deliveries(params = {}, **opts)
  raise InvalidRequestError, "Cannot get deliveries for a webhook without an ID" unless persisted?

  response = self.class.send(:execute_request, :GET, "#{resource_path}/deliveries", params, opts)
  response[:data] || []
end

#destroy(**opts) ⇒ Object

Override destroy to handle nested ID



79
80
81
82
83
84
85
86
# File 'lib/attio/resources/webhook.rb', line 79

def destroy(**opts)
  raise InvalidRequestError, "Cannot destroy a webhook without an ID" unless persisted?

  webhook_id = Util::IdExtractor.extract_for_resource(id, :webhook)
  self.class.delete(webhook_id, **opts)
  freeze
  true
end

#pause(**opts) ⇒ Object

Pause the webhook



99
100
101
102
# File 'lib/attio/resources/webhook.rb', line 99

def pause(**opts)
  self.active = false
  save(**opts)
end

#paused?Boolean

Check if webhook is paused

Returns:

  • (Boolean)


94
95
96
# File 'lib/attio/resources/webhook.rb', line 94

def paused?
  !active?
end

#resource_pathObject



63
64
65
66
67
# File 'lib/attio/resources/webhook.rb', line 63

def resource_path
  raise InvalidRequestError, "Cannot generate path without an ID" unless persisted?
  webhook_id = Util::IdExtractor.extract_for_resource(id, :webhook)
  "#{self.class.resource_path}/#{webhook_id}"
end

#resume(**opts) ⇒ Object Also known as: activate

Resume the webhook



105
106
107
108
# File 'lib/attio/resources/webhook.rb', line 105

def resume(**opts)
  self.active = true
  save(**opts)
end

#saveObject

Override save to handle nested ID



70
71
72
73
74
75
76
# File 'lib/attio/resources/webhook.rb', line 70

def save(**)
  raise InvalidRequestError, "Cannot save a webhook without an ID" unless persisted?
  return self unless changed?

  webhook_id = Util::IdExtractor.extract_for_resource(id, :webhook)
  self.class.update(webhook_id, changed_attributes, **)
end

#test(**opts) ⇒ Object

Test the webhook with a sample payload



112
113
114
115
116
117
# File 'lib/attio/resources/webhook.rb', line 112

def test(**opts)
  raise InvalidRequestError, "Cannot test a webhook without an ID" unless persisted?

  self.class.send(:execute_request, :POST, "#{resource_path}/test", {}, opts)
  true
end

#to_hHash

Convert webhook to hash representation

Returns:

  • (Hash)

    Webhook data as a hash



129
130
131
132
133
134
135
136
137
138
# File 'lib/attio/resources/webhook.rb', line 129

def to_h
  super.merge(
    target_url: target_url,
    subscriptions: subscriptions,
    status: status,
    secret: secret,
    last_event_at: last_event_at&.iso8601,
    created_by_actor: created_by_actor
  ).compact
end