action_webhook 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2063e93683fe64ce519f241843f17e33da9f29d671b965af97c0f97540a98ecc
4
- data.tar.gz: 1f591bf9cfb727d9ab6e750338b708e4e24df2e782ea3f1a5096277f4311474d
3
+ metadata.gz: 5fd47bb2e72c2bd12feab3682031b00603f271279b435eeb56b5a4e7dba6bccb
4
+ data.tar.gz: a4e22834b739227926772b9b8d18f4dbc74c1d7f7fc06bcbc1174707a306897d
5
5
  SHA512:
6
- metadata.gz: 14ed8242d705d62f573fd884e83bc70479ed4397c4bb3fffd75fd178bdc929fe5d981c395abb99ab7d647c7f1aec3aeaf1685784b3d521e3e62ed2e073ee8c1c
7
- data.tar.gz: 45c7362968926262d79f6dedb16f2391d30a2b64980e3a5d0116558360ee63fe416b54f33a17012b82e5b50d8a465a58d5f91e1b6fa1f05e185959a2ce547230
6
+ metadata.gz: dd8df71521ef095e6f52aad36daacb1e518ec400a0cb1aa8919568dbe240731097679f18933bd9d30406d17a02685ffd79570189067e84405c80968c834de015
7
+ data.tar.gz: f42e11c74f275f4206c992a9e96a6e3b37eb40ed4f53191dbbef2192c596a2f039c172bd9d888f33ae0c18b9dc504a25d40055f86fba847ba5188c4e578af672
@@ -4,6 +4,10 @@ module ActionWebhook
4
4
  # Subclass this and define webhook methods (e.g. `created`, `updated`) that
5
5
  # define instance variables and call deliver to send webhooks.
6
6
  #
7
+ # Headers can be provided in two formats:
8
+ # 1. Hash format: { 'Authorization' => 'Bearer token', 'Content-Type' => 'application/json' }
9
+ # 2. Array format: [{ 'key' => 'Authorization', 'value' => 'Bearer token' }, { 'key' => 'Content-Type', 'value' => 'application/json' }]
10
+ #
7
11
  # Example:
8
12
  #
9
13
  # class UserWebhook < ActionWebhook::Base
@@ -41,10 +45,26 @@ module ActionWebhook
41
45
  #
42
46
  # def created(user)
43
47
  # @user = user
44
- # endpoints = WebhookSubscription.where(event: 'user.created').map do |sub|
45
- # { url: sub.url, headers: { 'Authorization' => "Bearer #{sub.token}" } }
48
+ # # Headers can be provided as a hash
49
+ # endpoints_with_hash_headers = WebhookSubscription.where(event: 'user.created').map do |sub|
50
+ # {
51
+ # url: sub.url,
52
+ # headers: { 'Authorization' => "Bearer #{sub.token}", 'X-Custom-Header' => 'value' }
53
+ # }
46
54
  # end
47
- # deliver(endpoints)
55
+ #
56
+ # # Or headers can be provided as an array of key/value objects (useful for database storage)
57
+ # endpoints_with_array_headers = WebhookSubscription.where(event: 'user.created').map do |sub|
58
+ # {
59
+ # url: sub.url,
60
+ # headers: [
61
+ # { 'key' => 'Authorization', 'value' => "Bearer #{sub.token}" },
62
+ # { 'key' => 'X-Custom-Header', 'value' => 'value' }
63
+ # ]
64
+ # }
65
+ # end
66
+ #
67
+ # deliver(endpoints_with_hash_headers)
48
68
  # end
49
69
  # end
50
70
  #
@@ -234,8 +254,51 @@ module ActionWebhook
234
254
  assigns
235
255
  end
236
256
 
257
+ # Builds HTTP headers for webhook requests
258
+ #
259
+ # Supports two input formats:
260
+ # 1. Hash format: { 'Authorization' => 'Bearer token', 'Content-Type' => 'application/json' }
261
+ # 2. Array format: [{ 'key' => 'Authorization', 'value' => 'Bearer token' }, { 'key' => 'Content-Type', 'value' => 'application/json' }]
262
+ #
263
+ # The array format is useful when storing headers in databases where you need
264
+ # structured data with separate key and value fields.
265
+ #
266
+ # @param detail_headers [Hash, Array, nil] Headers in hash or array format
267
+ # @return [Hash] Formatted headers hash ready for HTTP request
237
268
  def build_headers(detail_headers)
238
- headers = default_headers.merge(detail_headers)
269
+ # Handle both hash format and array format with key/value objects
270
+ processed_headers = case detail_headers
271
+ when Array
272
+ # Transform array of header hashes [{'key': 'value'}] into a single hash
273
+ detail_headers.each_with_object({}) do |header_item, acc|
274
+ next unless header_item.is_a?(Hash)
275
+
276
+ # Handle string keys
277
+ if header_item.key?('key') && header_item.key?('value')
278
+ key = header_item['key']
279
+ value = header_item['value']
280
+ acc[key.to_s] = value.to_s if key && value
281
+ # Handle symbol keys
282
+ elsif header_item.key?(:key) && header_item.key?(:value)
283
+ key = header_item[:key]
284
+ value = header_item[:value]
285
+ acc[key.to_s] = value.to_s if key && value
286
+ else
287
+ # Log warning for malformed header items
288
+ logger&.warn("Skipping malformed header item: #{header_item.inspect}")
289
+ end
290
+ end
291
+ when Hash
292
+ # Ensure all keys and values are strings for consistency
293
+ detail_headers.transform_keys(&:to_s).transform_values(&:to_s)
294
+ when NilClass
295
+ {}
296
+ else
297
+ logger&.warn("Unknown header format: #{detail_headers.class}. Expected Hash or Array.")
298
+ {}
299
+ end
300
+
301
+ headers = default_headers.merge(processed_headers)
239
302
  headers["Content-Type"] = "application/json" unless headers.key?("Content-Type")
240
303
  headers["X-Webhook-Attempt"] = @attempts.to_s if @attempts.positive?
241
304
  headers
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionWebhook
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_webhook
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vinay Uttam Vemparala
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-06 00:00:00.000000000 Z
10
+ date: 2025-07-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: httparty