laneful-ruby 1.2.0 → 1.3.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 +4 -4
- data/lib/laneful/models.rb +24 -6
- data/lib/laneful/version.rb +1 -1
- data/lib/laneful/webhooks.rb +4 -10
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae0fefd1de5f15988a54f6d158b70bb9037a7879d344ce217066347bec84dbd0
|
|
4
|
+
data.tar.gz: 5c4f9702e0fa83de52b7bbe040700817bbcabeabed1d753951cdaed0a6ea831f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb8596d2eccaac4b25963ef3bfa5dc0eff89bd3884d5a44fa61b10892aad841d342d06f303918e68e3a49cf17509519fa3bcf3a577c2672cb2cf4c82dbb8182c
|
|
7
|
+
data.tar.gz: 7012812bed4f9c9c217d1aa6299c76eeb43c29cc8c4effe3cf0b78aaae6340992483b05ed58e1e975d95e98f11029f76f813e0c0775345150062a3dab15dcc8c
|
data/lib/laneful/models.rb
CHANGED
|
@@ -115,19 +115,26 @@ module Laneful
|
|
|
115
115
|
end
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
# Request-level mail settings (sandbox mode, return message IDs)
|
|
118
|
+
# Request-level mail settings (sandbox mode, return message IDs, idempotency key).
|
|
119
|
+
#
|
|
120
|
+
# idempotency_key protects against duplicate sends: Laneful accepts a key once per
|
|
121
|
+
# organization for one hour. A repeated request with the same key is answered with
|
|
122
|
+
# status "accepted" (and no message IDs) and sends nothing. Keys are 1 to 36 bytes.
|
|
119
123
|
class MailSettings
|
|
120
|
-
attr_reader :sandbox_mode, :return_message_ids
|
|
124
|
+
attr_reader :sandbox_mode, :return_message_ids, :idempotency_key
|
|
121
125
|
|
|
122
|
-
def initialize(sandbox_mode: nil, return_message_ids: nil)
|
|
126
|
+
def initialize(sandbox_mode: nil, return_message_ids: nil, idempotency_key: nil)
|
|
123
127
|
@sandbox_mode = sandbox_mode
|
|
124
128
|
@return_message_ids = return_message_ids
|
|
129
|
+
@idempotency_key = idempotency_key
|
|
130
|
+
validate_idempotency_key!
|
|
125
131
|
end
|
|
126
132
|
|
|
127
133
|
def self.from_hash(data)
|
|
128
134
|
new(
|
|
129
135
|
sandbox_mode: data['sandbox_mode'],
|
|
130
|
-
return_message_ids: data['return_message_ids']
|
|
136
|
+
return_message_ids: data['return_message_ids'],
|
|
137
|
+
idempotency_key: data['idempotency_key']
|
|
131
138
|
)
|
|
132
139
|
end
|
|
133
140
|
|
|
@@ -135,13 +142,15 @@ module Laneful
|
|
|
135
142
|
hash = {}
|
|
136
143
|
hash['sandbox_mode'] = sandbox_mode unless sandbox_mode.nil?
|
|
137
144
|
hash['return_message_ids'] = return_message_ids unless return_message_ids.nil?
|
|
145
|
+
hash['idempotency_key'] = idempotency_key unless idempotency_key.nil?
|
|
138
146
|
hash
|
|
139
147
|
end
|
|
140
148
|
|
|
141
149
|
def ==(other)
|
|
142
150
|
return false unless other.is_a?(MailSettings)
|
|
143
151
|
|
|
144
|
-
sandbox_mode == other.sandbox_mode && return_message_ids == other.return_message_ids
|
|
152
|
+
sandbox_mode == other.sandbox_mode && return_message_ids == other.return_message_ids &&
|
|
153
|
+
idempotency_key == other.idempotency_key
|
|
145
154
|
end
|
|
146
155
|
|
|
147
156
|
def eql?(other)
|
|
@@ -149,7 +158,16 @@ module Laneful
|
|
|
149
158
|
end
|
|
150
159
|
|
|
151
160
|
def hash
|
|
152
|
-
[sandbox_mode, return_message_ids].hash
|
|
161
|
+
[sandbox_mode, return_message_ids, idempotency_key].hash
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
def validate_idempotency_key!
|
|
167
|
+
return if idempotency_key.nil?
|
|
168
|
+
return if idempotency_key.bytesize.between?(1, 36)
|
|
169
|
+
|
|
170
|
+
raise ValidationException, 'idempotency_key must contain between 1 and 36 bytes'
|
|
153
171
|
end
|
|
154
172
|
end
|
|
155
173
|
|
data/lib/laneful/version.rb
CHANGED
data/lib/laneful/webhooks.rb
CHANGED
|
@@ -10,14 +10,12 @@ module Laneful
|
|
|
10
10
|
SIGNATURE_PREFIX = 'sha256='
|
|
11
11
|
SIGNATURE_HEADER_NAME = 'x-webhook-signature'
|
|
12
12
|
|
|
13
|
-
#
|
|
13
|
+
# Documented event types. Informational: parse_webhook_payload keeps events of other
|
|
14
|
+
# types, so new event types don't make the whole payload fail.
|
|
14
15
|
VALID_EVENT_TYPES = %w[
|
|
15
16
|
request delivery open click drop spam_complaint unsubscribe bounce
|
|
16
17
|
].freeze
|
|
17
18
|
|
|
18
|
-
# UUID pattern for lane_id validation
|
|
19
|
-
UUID_PATTERN = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
|
|
20
|
-
|
|
21
19
|
# Verifies a webhook signature with support for sha256= prefix
|
|
22
20
|
# @param secret [String] The webhook secret
|
|
23
21
|
# @param payload [String] The webhook payload
|
|
@@ -133,9 +131,7 @@ module Laneful
|
|
|
133
131
|
raise ArgumentError, "Missing required field: #{field}" unless event.key?(field)
|
|
134
132
|
end
|
|
135
133
|
|
|
136
|
-
|
|
137
|
-
event_type = event['event']
|
|
138
|
-
raise ArgumentError, "Invalid event type: #{event_type}" unless VALID_EVENT_TYPES.include?(event_type)
|
|
134
|
+
raise ArgumentError, 'Missing required field: event' if event['event'].to_s.empty?
|
|
139
135
|
|
|
140
136
|
# Validate email format
|
|
141
137
|
email = event['email']
|
|
@@ -149,9 +145,7 @@ module Laneful
|
|
|
149
145
|
raise ArgumentError, 'Invalid timestamp format'
|
|
150
146
|
end
|
|
151
147
|
|
|
152
|
-
#
|
|
153
|
-
lane_id = event['lane_id']
|
|
154
|
-
raise ArgumentError, "Invalid lane_id format: #{lane_id}" unless UUID_PATTERN.match?(lane_id)
|
|
148
|
+
# lane_id isn't checked: request events have an empty lane_id.
|
|
155
149
|
|
|
156
150
|
# Return event with all fields (required + optional)
|
|
157
151
|
event
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: laneful-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Laneful Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httparty
|
|
@@ -53,14 +53,14 @@ files:
|
|
|
53
53
|
- lib/laneful/org_models.rb
|
|
54
54
|
- lib/laneful/version.rb
|
|
55
55
|
- lib/laneful/webhooks.rb
|
|
56
|
-
homepage: https://github.com/
|
|
56
|
+
homepage: https://github.com/lanefulhq/laneful-ruby
|
|
57
57
|
licenses:
|
|
58
58
|
- MIT
|
|
59
59
|
metadata:
|
|
60
|
-
homepage_uri: https://github.com/
|
|
61
|
-
source_code_uri: https://github.com/
|
|
62
|
-
changelog_uri: https://github.com/
|
|
63
|
-
documentation_uri: https://
|
|
60
|
+
homepage_uri: https://github.com/lanefulhq/laneful-ruby
|
|
61
|
+
source_code_uri: https://github.com/lanefulhq/laneful-ruby
|
|
62
|
+
changelog_uri: https://github.com/lanefulhq/laneful-ruby/blob/main/CHANGELOG.md
|
|
63
|
+
documentation_uri: https://laneful.com/docs/ruby-sdk/
|
|
64
64
|
rubygems_mfa_required: 'true'
|
|
65
65
|
post_install_message:
|
|
66
66
|
rdoc_options: []
|