pingram 1.0.10 → 1.0.11

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.
@@ -186,6 +186,26 @@ module Pingram
186
186
 
187
187
  attr_accessor :sms_replied_encoding
188
188
 
189
+ attr_accessor :sms_unsubscribe_at
190
+
191
+ attr_accessor :sms_unsubscribe_from
192
+
193
+ attr_accessor :sms_unsubscribe_keyword
194
+
195
+ attr_accessor :sms_unsubscribe_webhook_delivered
196
+
197
+ attr_accessor :sms_unsubscribe_webhook_res
198
+
199
+ attr_accessor :sms_subscribe_at
200
+
201
+ attr_accessor :sms_subscribe_from
202
+
203
+ attr_accessor :sms_subscribe_keyword
204
+
205
+ attr_accessor :sms_subscribe_webhook_delivered
206
+
207
+ attr_accessor :sms_subscribe_webhook_res
208
+
189
209
  attr_accessor :web_push_sent_token
190
210
 
191
211
  attr_accessor :web_push_sent_at
@@ -460,6 +480,16 @@ module Pingram
460
480
  :'sms_replied_text' => :'sms_replied_text',
461
481
  :'sms_replied_segments' => :'sms_replied_segments',
462
482
  :'sms_replied_encoding' => :'sms_replied_encoding',
483
+ :'sms_unsubscribe_at' => :'sms_unsubscribe_at',
484
+ :'sms_unsubscribe_from' => :'sms_unsubscribe_from',
485
+ :'sms_unsubscribe_keyword' => :'sms_unsubscribe_keyword',
486
+ :'sms_unsubscribe_webhook_delivered' => :'sms_unsubscribe_webhook_delivered',
487
+ :'sms_unsubscribe_webhook_res' => :'sms_unsubscribe_webhook_res',
488
+ :'sms_subscribe_at' => :'sms_subscribe_at',
489
+ :'sms_subscribe_from' => :'sms_subscribe_from',
490
+ :'sms_subscribe_keyword' => :'sms_subscribe_keyword',
491
+ :'sms_subscribe_webhook_delivered' => :'sms_subscribe_webhook_delivered',
492
+ :'sms_subscribe_webhook_res' => :'sms_subscribe_webhook_res',
463
493
  :'web_push_sent_token' => :'web_push_sent_token',
464
494
  :'web_push_sent_at' => :'web_push_sent_at',
465
495
  :'web_push_sent_after' => :'web_push_sent_after',
@@ -640,6 +670,16 @@ module Pingram
640
670
  :'sms_replied_text' => :'String',
641
671
  :'sms_replied_segments' => :'Float',
642
672
  :'sms_replied_encoding' => :'String',
673
+ :'sms_unsubscribe_at' => :'String',
674
+ :'sms_unsubscribe_from' => :'String',
675
+ :'sms_unsubscribe_keyword' => :'String',
676
+ :'sms_unsubscribe_webhook_delivered' => :'Boolean',
677
+ :'sms_unsubscribe_webhook_res' => :'String',
678
+ :'sms_subscribe_at' => :'String',
679
+ :'sms_subscribe_from' => :'String',
680
+ :'sms_subscribe_keyword' => :'String',
681
+ :'sms_subscribe_webhook_delivered' => :'Boolean',
682
+ :'sms_subscribe_webhook_res' => :'String',
643
683
  :'web_push_sent_token' => :'String',
644
684
  :'web_push_sent_at' => :'String',
645
685
  :'web_push_sent_after' => :'Float',
@@ -1085,6 +1125,46 @@ module Pingram
1085
1125
  self.sms_replied_encoding = attributes[:'sms_replied_encoding']
1086
1126
  end
1087
1127
 
1128
+ if attributes.key?(:'sms_unsubscribe_at')
1129
+ self.sms_unsubscribe_at = attributes[:'sms_unsubscribe_at']
1130
+ end
1131
+
1132
+ if attributes.key?(:'sms_unsubscribe_from')
1133
+ self.sms_unsubscribe_from = attributes[:'sms_unsubscribe_from']
1134
+ end
1135
+
1136
+ if attributes.key?(:'sms_unsubscribe_keyword')
1137
+ self.sms_unsubscribe_keyword = attributes[:'sms_unsubscribe_keyword']
1138
+ end
1139
+
1140
+ if attributes.key?(:'sms_unsubscribe_webhook_delivered')
1141
+ self.sms_unsubscribe_webhook_delivered = attributes[:'sms_unsubscribe_webhook_delivered']
1142
+ end
1143
+
1144
+ if attributes.key?(:'sms_unsubscribe_webhook_res')
1145
+ self.sms_unsubscribe_webhook_res = attributes[:'sms_unsubscribe_webhook_res']
1146
+ end
1147
+
1148
+ if attributes.key?(:'sms_subscribe_at')
1149
+ self.sms_subscribe_at = attributes[:'sms_subscribe_at']
1150
+ end
1151
+
1152
+ if attributes.key?(:'sms_subscribe_from')
1153
+ self.sms_subscribe_from = attributes[:'sms_subscribe_from']
1154
+ end
1155
+
1156
+ if attributes.key?(:'sms_subscribe_keyword')
1157
+ self.sms_subscribe_keyword = attributes[:'sms_subscribe_keyword']
1158
+ end
1159
+
1160
+ if attributes.key?(:'sms_subscribe_webhook_delivered')
1161
+ self.sms_subscribe_webhook_delivered = attributes[:'sms_subscribe_webhook_delivered']
1162
+ end
1163
+
1164
+ if attributes.key?(:'sms_subscribe_webhook_res')
1165
+ self.sms_subscribe_webhook_res = attributes[:'sms_subscribe_webhook_res']
1166
+ end
1167
+
1088
1168
  if attributes.key?(:'web_push_sent_token')
1089
1169
  self.web_push_sent_token = attributes[:'web_push_sent_token']
1090
1170
  end
@@ -1840,6 +1920,16 @@ module Pingram
1840
1920
  sms_replied_text == o.sms_replied_text &&
1841
1921
  sms_replied_segments == o.sms_replied_segments &&
1842
1922
  sms_replied_encoding == o.sms_replied_encoding &&
1923
+ sms_unsubscribe_at == o.sms_unsubscribe_at &&
1924
+ sms_unsubscribe_from == o.sms_unsubscribe_from &&
1925
+ sms_unsubscribe_keyword == o.sms_unsubscribe_keyword &&
1926
+ sms_unsubscribe_webhook_delivered == o.sms_unsubscribe_webhook_delivered &&
1927
+ sms_unsubscribe_webhook_res == o.sms_unsubscribe_webhook_res &&
1928
+ sms_subscribe_at == o.sms_subscribe_at &&
1929
+ sms_subscribe_from == o.sms_subscribe_from &&
1930
+ sms_subscribe_keyword == o.sms_subscribe_keyword &&
1931
+ sms_subscribe_webhook_delivered == o.sms_subscribe_webhook_delivered &&
1932
+ sms_subscribe_webhook_res == o.sms_subscribe_webhook_res &&
1843
1933
  web_push_sent_token == o.web_push_sent_token &&
1844
1934
  web_push_sent_at == o.web_push_sent_at &&
1845
1935
  web_push_sent_after == o.web_push_sent_after &&
@@ -1931,7 +2021,7 @@ module Pingram
1931
2021
  # Calculates hash code according to all attributes.
1932
2022
  # @return [Integer] Hash code
1933
2023
  def hash
1934
- [received_at, type, env_id, client_id, agent, ip, request, test, tracking_id, account_id, failed_at, failed_code, failed_internal, inapp_sent_at, inapp_sent_after, inapp_delivered_at, inapp_delivered_after, inapp_failed_at, inapp_failed_code, inapp_failed_internal, mobile_push_failed_at, mobile_push_failed_code, mobile_push_failed_token, mobile_push_failed_internal, mobile_push_sent_at, mobile_push_sent_after, mobile_push_sent_token, mobile_push_delivered_at, mobile_push_delivered_after, email_sent_at, email_sent_message_id, email_sent_after, email_preview, email_delivered_at, email_delivered_recipients, email_delivered_after, email_delivered_webhook_res, email_failed_at, email_failed_code, email_failed_recipient, email_failed_diagnostic_code, email_failed_internal, email_failed_webhook_res, email_opened_at, email_opened_user_agent, email_opened_ip, email_opened_webhook_res, email_clicked_at, email_clicked_user_agent, email_clicked_ip, email_clicked_link, email_clicked_link_tags, email_clicked_webhook_res, email_inbound_at, email_inbound_from, email_inbound_from_name, email_inbound_to, email_inbound_cc, email_inbound_bcc, email_inbound_reply_to, email_inbound_inbox, email_inbound_subject, email_inbound_body_text, email_inbound_body_html, email_inbound_has_attachments, email_inbound_attachment_count, email_inbound_message_id, email_inbound_in_reply_to, email_inbound_references, email_inbound_webhook_delivered, email_inbound_webhook_res, email_inbound_resolution_type, sms_inbound_at, sms_inbound_from, sms_inbound_to, sms_inbound_text, sms_inbound_webhook_delivered, sms_inbound_webhook_res, sms_inbound_media, sms_replied_at, sms_replied_to, sms_replied_text, sms_replied_segments, sms_replied_encoding, web_push_sent_token, web_push_sent_at, web_push_sent_after, web_push_delivered_at, web_push_delivered_after, web_push_delivered_token, web_push_delivered_internal, web_push_failed_at, web_push_failed_token, web_push_failed_code, web_push_failed_internal, processed_at, ignored, scheduled_for, user_id, user_email, user_number, email_routing, email_routing_reason, sms_routing, sms_routing_reason, web_push_routing, web_push_routing_reason, mobile_push_routing, mobile_push_routing_reason, call_routing, call_routing_reason, inapp_routing, inapp_routing_reason, slack_routing, slack_routing_reason, sms_preview, call_preview, web_push_preview, mobile_push_preview, slack_preview, inapp_preview, slack_sent_at, slack_sent_after, slack_delivered_at, slack_delivered_after, slack_delivered_internal, slack_failed_at, slack_failed_code, slack_failed_internal, call_sent_at, call_sent_after, call_sent_from, call_delivered_at, call_delivered_after, call_delivered_code, call_delivered_cost_internal, call_delivered_cost, call_failed_at, call_failed_code, call_failed_internal, sms_failed_at, sms_failed_code, sms_failed_internal, sms_sent_at, sms_sent_after, sms_sent_from, sms_sent_carrier, sms_sent_line_type, sms_sent_encoding, sms_sent_segments, sms_sent_parts, sms_sent_cost, sms_sent_country, sms_sent_message_id, sms_sent_mms, sms_carrier_cost_internal, sms_carrier_fee_internal, sms_rate_internal, sms_delivered_at, sms_delivered_after, sms_delivered_cost_internal, schedule_updated_at, schedule_updated_to, schedule_deleted_at].hash
2024
+ [received_at, type, env_id, client_id, agent, ip, request, test, tracking_id, account_id, failed_at, failed_code, failed_internal, inapp_sent_at, inapp_sent_after, inapp_delivered_at, inapp_delivered_after, inapp_failed_at, inapp_failed_code, inapp_failed_internal, mobile_push_failed_at, mobile_push_failed_code, mobile_push_failed_token, mobile_push_failed_internal, mobile_push_sent_at, mobile_push_sent_after, mobile_push_sent_token, mobile_push_delivered_at, mobile_push_delivered_after, email_sent_at, email_sent_message_id, email_sent_after, email_preview, email_delivered_at, email_delivered_recipients, email_delivered_after, email_delivered_webhook_res, email_failed_at, email_failed_code, email_failed_recipient, email_failed_diagnostic_code, email_failed_internal, email_failed_webhook_res, email_opened_at, email_opened_user_agent, email_opened_ip, email_opened_webhook_res, email_clicked_at, email_clicked_user_agent, email_clicked_ip, email_clicked_link, email_clicked_link_tags, email_clicked_webhook_res, email_inbound_at, email_inbound_from, email_inbound_from_name, email_inbound_to, email_inbound_cc, email_inbound_bcc, email_inbound_reply_to, email_inbound_inbox, email_inbound_subject, email_inbound_body_text, email_inbound_body_html, email_inbound_has_attachments, email_inbound_attachment_count, email_inbound_message_id, email_inbound_in_reply_to, email_inbound_references, email_inbound_webhook_delivered, email_inbound_webhook_res, email_inbound_resolution_type, sms_inbound_at, sms_inbound_from, sms_inbound_to, sms_inbound_text, sms_inbound_webhook_delivered, sms_inbound_webhook_res, sms_inbound_media, sms_replied_at, sms_replied_to, sms_replied_text, sms_replied_segments, sms_replied_encoding, sms_unsubscribe_at, sms_unsubscribe_from, sms_unsubscribe_keyword, sms_unsubscribe_webhook_delivered, sms_unsubscribe_webhook_res, sms_subscribe_at, sms_subscribe_from, sms_subscribe_keyword, sms_subscribe_webhook_delivered, sms_subscribe_webhook_res, web_push_sent_token, web_push_sent_at, web_push_sent_after, web_push_delivered_at, web_push_delivered_after, web_push_delivered_token, web_push_delivered_internal, web_push_failed_at, web_push_failed_token, web_push_failed_code, web_push_failed_internal, processed_at, ignored, scheduled_for, user_id, user_email, user_number, email_routing, email_routing_reason, sms_routing, sms_routing_reason, web_push_routing, web_push_routing_reason, mobile_push_routing, mobile_push_routing_reason, call_routing, call_routing_reason, inapp_routing, inapp_routing_reason, slack_routing, slack_routing_reason, sms_preview, call_preview, web_push_preview, mobile_push_preview, slack_preview, inapp_preview, slack_sent_at, slack_sent_after, slack_delivered_at, slack_delivered_after, slack_delivered_internal, slack_failed_at, slack_failed_code, slack_failed_internal, call_sent_at, call_sent_after, call_sent_from, call_delivered_at, call_delivered_after, call_delivered_code, call_delivered_cost_internal, call_delivered_cost, call_failed_at, call_failed_code, call_failed_internal, sms_failed_at, sms_failed_code, sms_failed_internal, sms_sent_at, sms_sent_after, sms_sent_from, sms_sent_carrier, sms_sent_line_type, sms_sent_encoding, sms_sent_segments, sms_sent_parts, sms_sent_cost, sms_sent_country, sms_sent_message_id, sms_sent_mms, sms_carrier_cost_internal, sms_carrier_fee_internal, sms_rate_internal, sms_delivered_at, sms_delivered_after, sms_delivered_cost_internal, schedule_updated_at, schedule_updated_to, schedule_deleted_at].hash
1935
2025
  end
1936
2026
 
1937
2027
  # Builds the object from hash
@@ -0,0 +1,328 @@
1
+ =begin
2
+ #Pingram
3
+
4
+ #Internal API for notification delivery and management
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Pingram
17
+ # Webhook event payload sent to customer endpoints. Use this type with SDK webhook verification methods (e.g., verify from 'pingram/webhooks').
18
+ class WebhookEvent < ApiModelBase
19
+ attr_accessor :event_type
20
+
21
+ attr_accessor :channel
22
+
23
+ # User ID the notification was sent to.
24
+ attr_accessor :user_id
25
+
26
+ # Notification type ID.
27
+ attr_accessor :notification_id
28
+
29
+ # Unique tracking ID for this notification instance.
30
+ attr_accessor :tracking_id
31
+
32
+ # Failure code for *_FAILED events.
33
+ attr_accessor :failure_code
34
+
35
+ # Clicked URL for EMAIL_CLICK events.
36
+ attr_accessor :clicked_link
37
+
38
+ # Link tags for EMAIL_CLICK events.
39
+ attr_accessor :clicked_link_tags
40
+
41
+ class EnumAttributeValidator
42
+ attr_reader :datatype
43
+ attr_reader :allowable_values
44
+
45
+ def initialize(datatype, allowable_values)
46
+ @allowable_values = allowable_values.map do |value|
47
+ case datatype.to_s
48
+ when /Integer/i
49
+ value.to_i
50
+ when /Float/i
51
+ value.to_f
52
+ else
53
+ value
54
+ end
55
+ end
56
+ end
57
+
58
+ def valid?(value)
59
+ !value || allowable_values.include?(value)
60
+ end
61
+ end
62
+
63
+ # Attribute mapping from ruby-style variable name to JSON key.
64
+ def self.attribute_map
65
+ {
66
+ :'event_type' => :'eventType',
67
+ :'channel' => :'channel',
68
+ :'user_id' => :'userId',
69
+ :'notification_id' => :'notificationId',
70
+ :'tracking_id' => :'trackingId',
71
+ :'failure_code' => :'failureCode',
72
+ :'clicked_link' => :'clickedLink',
73
+ :'clicked_link_tags' => :'clickedLinkTags'
74
+ }
75
+ end
76
+
77
+ # Returns attribute mapping this model knows about
78
+ def self.acceptable_attribute_map
79
+ attribute_map
80
+ end
81
+
82
+ # Returns all the JSON keys this model knows about
83
+ def self.acceptable_attributes
84
+ acceptable_attribute_map.values
85
+ end
86
+
87
+ # Attribute type mapping.
88
+ def self.openapi_types
89
+ {
90
+ :'event_type' => :'String',
91
+ :'channel' => :'ChannelsEnum',
92
+ :'user_id' => :'String',
93
+ :'notification_id' => :'String',
94
+ :'tracking_id' => :'String',
95
+ :'failure_code' => :'String',
96
+ :'clicked_link' => :'String',
97
+ :'clicked_link_tags' => :'Hash<String, Array<String>>'
98
+ }
99
+ end
100
+
101
+ # List of attributes with nullable: true
102
+ def self.openapi_nullable
103
+ Set.new([
104
+ ])
105
+ end
106
+
107
+ # Initializes the object
108
+ # @param [Hash] attributes Model attributes in the form of hash
109
+ def initialize(attributes = {})
110
+ if (!attributes.is_a?(Hash))
111
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Pingram::WebhookEvent` initialize method"
112
+ end
113
+
114
+ # check to see if the attribute exists and convert string to symbol for hash key
115
+ acceptable_attribute_map = self.class.acceptable_attribute_map
116
+ attributes = attributes.each_with_object({}) { |(k, v), h|
117
+ if (!acceptable_attribute_map.key?(k.to_sym))
118
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Pingram::WebhookEvent`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
119
+ end
120
+ h[k.to_sym] = v
121
+ }
122
+
123
+ if attributes.key?(:'event_type')
124
+ self.event_type = attributes[:'event_type']
125
+ else
126
+ self.event_type = nil
127
+ end
128
+
129
+ if attributes.key?(:'channel')
130
+ self.channel = attributes[:'channel']
131
+ else
132
+ self.channel = nil
133
+ end
134
+
135
+ if attributes.key?(:'user_id')
136
+ self.user_id = attributes[:'user_id']
137
+ else
138
+ self.user_id = nil
139
+ end
140
+
141
+ if attributes.key?(:'notification_id')
142
+ self.notification_id = attributes[:'notification_id']
143
+ else
144
+ self.notification_id = nil
145
+ end
146
+
147
+ if attributes.key?(:'tracking_id')
148
+ self.tracking_id = attributes[:'tracking_id']
149
+ else
150
+ self.tracking_id = nil
151
+ end
152
+
153
+ if attributes.key?(:'failure_code')
154
+ self.failure_code = attributes[:'failure_code']
155
+ end
156
+
157
+ if attributes.key?(:'clicked_link')
158
+ self.clicked_link = attributes[:'clicked_link']
159
+ end
160
+
161
+ if attributes.key?(:'clicked_link_tags')
162
+ if (value = attributes[:'clicked_link_tags']).is_a?(Hash)
163
+ self.clicked_link_tags = value
164
+ end
165
+ end
166
+ end
167
+
168
+ # Show invalid properties with the reasons. Usually used together with valid?
169
+ # @return Array for valid properties with the reasons
170
+ def list_invalid_properties
171
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
172
+ invalid_properties = Array.new
173
+ if @event_type.nil?
174
+ invalid_properties.push('invalid value for "event_type", event_type cannot be nil.')
175
+ end
176
+
177
+ if @channel.nil?
178
+ invalid_properties.push('invalid value for "channel", channel cannot be nil.')
179
+ end
180
+
181
+ if @user_id.nil?
182
+ invalid_properties.push('invalid value for "user_id", user_id cannot be nil.')
183
+ end
184
+
185
+ if @notification_id.nil?
186
+ invalid_properties.push('invalid value for "notification_id", notification_id cannot be nil.')
187
+ end
188
+
189
+ if @tracking_id.nil?
190
+ invalid_properties.push('invalid value for "tracking_id", tracking_id cannot be nil.')
191
+ end
192
+
193
+ invalid_properties
194
+ end
195
+
196
+ # Check to see if the all the properties in the model are valid
197
+ # @return true if the model is valid
198
+ def valid?
199
+ warn '[DEPRECATED] the `valid?` method is obsolete'
200
+ return false if @event_type.nil?
201
+ event_type_validator = EnumAttributeValidator.new('String', ["EMAIL_OPEN", "EMAIL_CLICK", "EMAIL_FAILED", "EMAIL_DELIVERED", "EMAIL_UNSUBSCRIBE", "EMAIL_INBOUND", "INAPP_WEB_FAILED", "INAPP_WEB_UNSUBSCRIBE", "SMS_DELIVERED", "SMS_FAILED", "SMS_UNSUBSCRIBE", "SMS_SUBSCRIBE", "SMS_INBOUND", "PUSH_FAILED", "PUSH_UNSUBSCRIBE", "CALL_FAILED", "CALL_UNSUBSCRIBE", "WEB_PUSH_FAILED", "WEB_PUSH_UNSUBSCRIBE", "SLACK_FAILED", "SLACK_UNSUBSCRIBE", "VOICE_INBOUND"])
202
+ return false unless event_type_validator.valid?(@event_type)
203
+ return false if @channel.nil?
204
+ return false if @user_id.nil?
205
+ return false if @notification_id.nil?
206
+ return false if @tracking_id.nil?
207
+ true
208
+ end
209
+
210
+ # Custom attribute writer method checking allowed values (enum).
211
+ # @param [Object] event_type Object to be assigned
212
+ def event_type=(event_type)
213
+ validator = EnumAttributeValidator.new('String', ["EMAIL_OPEN", "EMAIL_CLICK", "EMAIL_FAILED", "EMAIL_DELIVERED", "EMAIL_UNSUBSCRIBE", "EMAIL_INBOUND", "INAPP_WEB_FAILED", "INAPP_WEB_UNSUBSCRIBE", "SMS_DELIVERED", "SMS_FAILED", "SMS_UNSUBSCRIBE", "SMS_SUBSCRIBE", "SMS_INBOUND", "PUSH_FAILED", "PUSH_UNSUBSCRIBE", "CALL_FAILED", "CALL_UNSUBSCRIBE", "WEB_PUSH_FAILED", "WEB_PUSH_UNSUBSCRIBE", "SLACK_FAILED", "SLACK_UNSUBSCRIBE", "VOICE_INBOUND"])
214
+ unless validator.valid?(event_type)
215
+ fail ArgumentError, "invalid value for \"event_type\", must be one of #{validator.allowable_values}."
216
+ end
217
+ @event_type = event_type
218
+ end
219
+
220
+ # Custom attribute writer method with validation
221
+ # @param [Object] channel Value to be assigned
222
+ def channel=(channel)
223
+ if channel.nil?
224
+ fail ArgumentError, 'channel cannot be nil'
225
+ end
226
+
227
+ @channel = channel
228
+ end
229
+
230
+ # Custom attribute writer method with validation
231
+ # @param [Object] user_id Value to be assigned
232
+ def user_id=(user_id)
233
+ if user_id.nil?
234
+ fail ArgumentError, 'user_id cannot be nil'
235
+ end
236
+
237
+ @user_id = user_id
238
+ end
239
+
240
+ # Custom attribute writer method with validation
241
+ # @param [Object] notification_id Value to be assigned
242
+ def notification_id=(notification_id)
243
+ if notification_id.nil?
244
+ fail ArgumentError, 'notification_id cannot be nil'
245
+ end
246
+
247
+ @notification_id = notification_id
248
+ end
249
+
250
+ # Custom attribute writer method with validation
251
+ # @param [Object] tracking_id Value to be assigned
252
+ def tracking_id=(tracking_id)
253
+ if tracking_id.nil?
254
+ fail ArgumentError, 'tracking_id cannot be nil'
255
+ end
256
+
257
+ @tracking_id = tracking_id
258
+ end
259
+
260
+ # Checks equality by comparing each attribute.
261
+ # @param [Object] Object to be compared
262
+ def ==(o)
263
+ return true if self.equal?(o)
264
+ self.class == o.class &&
265
+ event_type == o.event_type &&
266
+ channel == o.channel &&
267
+ user_id == o.user_id &&
268
+ notification_id == o.notification_id &&
269
+ tracking_id == o.tracking_id &&
270
+ failure_code == o.failure_code &&
271
+ clicked_link == o.clicked_link &&
272
+ clicked_link_tags == o.clicked_link_tags
273
+ end
274
+
275
+ # @see the `==` method
276
+ # @param [Object] Object to be compared
277
+ def eql?(o)
278
+ self == o
279
+ end
280
+
281
+ # Calculates hash code according to all attributes.
282
+ # @return [Integer] Hash code
283
+ def hash
284
+ [event_type, channel, user_id, notification_id, tracking_id, failure_code, clicked_link, clicked_link_tags].hash
285
+ end
286
+
287
+ # Builds the object from hash
288
+ # @param [Hash] attributes Model attributes in the form of hash
289
+ # @return [Object] Returns the model itself
290
+ def self.build_from_hash(attributes)
291
+ return nil unless attributes.is_a?(Hash)
292
+ attributes = attributes.transform_keys(&:to_sym)
293
+ transformed_hash = {}
294
+ openapi_types.each_pair do |key, type|
295
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
296
+ transformed_hash["#{key}"] = nil
297
+ elsif type =~ /\AArray<(.*)>/i
298
+ # check to ensure the input is an array given that the attribute
299
+ # is documented as an array but the input is not
300
+ if attributes[attribute_map[key]].is_a?(Array)
301
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
302
+ end
303
+ elsif !attributes[attribute_map[key]].nil?
304
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
305
+ end
306
+ end
307
+ new(transformed_hash)
308
+ end
309
+
310
+ # Returns the object in the form of hash
311
+ # @return [Hash] Returns the object in the form of hash
312
+ def to_hash
313
+ hash = {}
314
+ self.class.attribute_map.each_pair do |attr, param|
315
+ value = self.send(attr)
316
+ if value.nil?
317
+ is_nullable = self.class.openapi_nullable.include?(attr)
318
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
319
+ end
320
+
321
+ hash[param] = _to_hash(value)
322
+ end
323
+ hash
324
+ end
325
+
326
+ end
327
+
328
+ end
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Pingram
14
- VERSION = '1.0.10'
14
+ VERSION = '1.0.11'
15
15
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is auto-generated by tools/sdk-codegen/generate-ruby-wrapper.ts
4
+ # DO NOT EDIT MANUALLY - changes will be overwritten
5
+ # Edit sdks/ruby/templates/webhooks.rb.mustache instead
6
+
7
+ require 'json'
8
+ require 'openssl'
9
+ require_relative 'models/webhook_event'
10
+
11
+ module Pingram
12
+ # Error raised when webhook signature verification fails.
13
+ class WebhookSignatureError < StandardError; end
14
+
15
+ # Error raised when webhook timestamp is outside tolerance.
16
+ class WebhookTimestampError < StandardError; end
17
+
18
+ # Verifies HMAC signatures on webhook payloads. Call class methods on {WebhookVerification}.
19
+ class WebhookVerification
20
+ # Default timestamp tolerance in seconds (5 minutes)
21
+ DEFAULT_TOLERANCE_SECONDS = 300
22
+
23
+ class << self
24
+ # Verify webhook signature and return the parsed event.
25
+ def construct_event(payload:, message_id:, signature:, timestamp:, secret:, tolerance: DEFAULT_TOLERANCE_SECONDS)
26
+ begin
27
+ timestamp_ms = Integer(timestamp)
28
+ rescue ArgumentError, TypeError
29
+ raise WebhookTimestampError, 'Invalid timestamp format'
30
+ end
31
+
32
+ now_ms = (Time.now.to_f * 1000).to_i
33
+ age = (now_ms - timestamp_ms).abs / 1000.0
34
+ if age > tolerance
35
+ raise WebhookTimestampError, "Webhook timestamp is outside tolerance (#{age.to_i}s > #{tolerance}s)"
36
+ end
37
+
38
+ raw_signature = parse_signature(signature)
39
+ expected_signature = compute_signature(payload, secret, timestamp, message_id)
40
+
41
+ unless secure_compare(expected_signature, raw_signature)
42
+ raise WebhookSignatureError, 'Invalid webhook signature'
43
+ end
44
+
45
+ begin
46
+ data = JSON.parse(payload)
47
+ WebhookEvent.build_from_hash(data)
48
+ rescue JSON::ParserError => e
49
+ raise WebhookSignatureError, "Invalid JSON payload: #{e.message}"
50
+ end
51
+ end
52
+
53
+ def verify(payload:, message_id:, signature:, timestamp:, secret:, tolerance: DEFAULT_TOLERANCE_SECONDS)
54
+ construct_event(
55
+ payload: payload,
56
+ message_id: message_id,
57
+ signature: signature,
58
+ timestamp: timestamp,
59
+ secret: secret,
60
+ tolerance: tolerance
61
+ )
62
+ end
63
+
64
+ private
65
+
66
+ def parse_signature(signature)
67
+ parts = signature.split(',', 2)
68
+ raise WebhookSignatureError, 'Invalid signature format' unless parts.length == 2 && parts[0] == 'v1'
69
+ parts[1]
70
+ end
71
+
72
+ def compute_signature(payload, secret, timestamp, message_id)
73
+ signed_payload = "#{message_id}.#{timestamp}.#{payload}"
74
+ OpenSSL::HMAC.hexdigest('SHA256', secret, signed_payload)
75
+ end
76
+
77
+ def secure_compare(a, b)
78
+ return false unless a.bytesize == b.bytesize
79
+
80
+ if OpenSSL.respond_to?(:secure_compare)
81
+ OpenSSL.secure_compare(a, b)
82
+ else
83
+ l = a.unpack('C*')
84
+ r = 0
85
+ i = -1
86
+ b.each_byte { |v| r |= v ^ l[i += 1] }
87
+ r == 0
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def self.webhooks
94
+ Webhooks
95
+ end
96
+ end
data/lib/pingram.rb CHANGED
@@ -17,8 +17,12 @@ require 'pingram/api_model_base'
17
17
  require 'pingram/version'
18
18
  require 'pingram/configuration'
19
19
  require 'pingram/client_wrapper'
20
+ require 'pingram/webhooks'
20
21
 
21
22
  # Models
23
+ require 'pingram/models/a2p_registration'
24
+ require 'pingram/models/a2p_registration_create_request'
25
+ require 'pingram/models/a2p_registration_update_request'
22
26
  require 'pingram/models/apn_config'
23
27
  require 'pingram/models/accept_invite_request'
24
28
  require 'pingram/models/accept_invite_response'
@@ -219,6 +223,7 @@ require 'pingram/models/template_post_request'
219
223
  require 'pingram/models/update_address_request'
220
224
  require 'pingram/models/user'
221
225
  require 'pingram/models/user_suppression_delete_response'
226
+ require 'pingram/models/webhook_event'
222
227
  require 'pingram/models/webhook_response'
223
228
 
224
229
  # APIs
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pingram
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pingram
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-03 00:00:00.000000000 Z
11
+ date: 2026-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -92,6 +92,9 @@ files:
92
92
  - lib/pingram/api_model_base.rb
93
93
  - lib/pingram/client_wrapper.rb
94
94
  - lib/pingram/configuration.rb
95
+ - lib/pingram/models/a2p_registration.rb
96
+ - lib/pingram/models/a2p_registration_create_request.rb
97
+ - lib/pingram/models/a2p_registration_update_request.rb
95
98
  - lib/pingram/models/accept_invite_request.rb
96
99
  - lib/pingram/models/accept_invite_response.rb
97
100
  - lib/pingram/models/account_addresses_response.rb
@@ -292,8 +295,10 @@ files:
292
295
  - lib/pingram/models/update_address_request.rb
293
296
  - lib/pingram/models/user.rb
294
297
  - lib/pingram/models/user_suppression_delete_response.rb
298
+ - lib/pingram/models/webhook_event.rb
295
299
  - lib/pingram/models/webhook_response.rb
296
300
  - lib/pingram/version.rb
301
+ - lib/pingram/webhooks.rb
297
302
  - pingram.gemspec
298
303
  - vendor/bundle/ruby/3.2.0/bin/byebug
299
304
  - vendor/bundle/ruby/3.2.0/bin/coderay